From 5aa308ec50e98cbfcf0b08cb0965f9232e247d74 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 4 Apr 2024 23:11:43 -0400 Subject: [PATCH 1/6] Add Battery Reporting to FindMy --- applications/system/findmy/findmy.c | 22 +++++++++ applications/system/findmy/findmy_i.h | 6 +++ applications/system/findmy/findmy_state.c | 48 ++++++++++++++++--- applications/system/findmy/findmy_state.h | 5 ++ .../system/findmy/scenes/findmy_scene_main.c | 3 +- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/applications/system/findmy/findmy.c b/applications/system/findmy/findmy.c index 1cafcf8cbd..da8bceb2ae 100644 --- a/applications/system/findmy/findmy.c +++ b/applications/system/findmy/findmy.c @@ -1,4 +1,5 @@ #include "findmy_i.h" +#include static bool findmy_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -148,6 +149,7 @@ void findmy_toggle_beacon(FindMy* app) { furi_check(furi_hal_bt_extra_beacon_start()); } findmy_main_update_active(app->findmy_main, furi_hal_bt_extra_beacon_is_active()); + findmy_update_battery(app, app->state.battery_level); } void findmy_set_tag_type(FindMy* app, FindMyType type) { @@ -158,6 +160,26 @@ void findmy_set_tag_type(FindMy* app, FindMyType type) { FURI_LOG_I("TagType2", "Tag Type: %d", type); } +void findmy_update_battery(FindMy* app, uint8_t battery_level) { + uint32_t battery_capacity = furi_hal_power_get_battery_full_capacity(); + uint32_t battery_remaining = furi_hal_power_get_battery_remaining_capacity(); + uint16_t battery_percent = (battery_remaining * 100) / battery_capacity; + + if(battery_percent > 80) { + battery_level = BATTERY_FULL; + } else if(battery_percent > 50) { + battery_level = BATTERY_MEDIUM; + } else if(battery_percent > 20) { + battery_level = BATTERY_LOW; + } else { + battery_level = BATTERY_CRITICAL; + } + + app->state.battery_level = battery_level; + findmy_state_sync_config(&app->state); + findmy_state_save(&app->state); +} + void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) { uint8_t tmp; for(size_t i = 0; i < GAP_MAC_ADDR_SIZE / 2; i++) { diff --git a/applications/system/findmy/findmy_i.h b/applications/system/findmy/findmy_i.h index af7458f8c8..2283b4a7aa 100644 --- a/applications/system/findmy/findmy_i.h +++ b/applications/system/findmy/findmy_i.h @@ -24,6 +24,11 @@ void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]); #endif +#define BATTERY_FULL 0x00 +#define BATTERY_MEDIUM 0x50 +#define BATTERY_LOW 0xA0 +#define BATTERY_CRITICAL 0xF0 + struct FindMy { Gui* gui; Storage* storage; @@ -54,3 +59,4 @@ void findmy_change_transmit_power(FindMy* app, uint8_t value); void findmy_toggle_show_mac(FindMy* app, bool show_mac); void findmy_set_tag_type(FindMy* app, FindMyType type); void findmy_toggle_beacon(FindMy* app); +void findmy_update_battery(FindMy* app, uint8_t battery_level); diff --git a/applications/system/findmy/findmy_state.c b/applications/system/findmy/findmy_state.c index ae81eab839..2f39c268ad 100644 --- a/applications/system/findmy/findmy_state.c +++ b/applications/system/findmy/findmy_state.c @@ -1,5 +1,6 @@ #include "findmy_state.h" +#include "findmy_i.h" #include #include #include @@ -42,6 +43,13 @@ bool findmy_state_load(FindMyState* out_state) { } state.tag_type = tmp; + if(!flipper_format_read_uint32(file, "battery_level", &tmp, 1)) { + tmp = 0x00; // Default battery level set to Full + flipper_format_rewind(file); + } + FURI_LOG_I("findmy_load", "Saved Battery: %ld", tmp); + state.battery_level = tmp; + if(!flipper_format_read_hex(file, "mac", state.mac, sizeof(state.mac))) break; if(!flipper_format_read_hex( @@ -74,12 +82,12 @@ bool findmy_state_load(FindMyState* out_state) { *data++ = 0x00; // ... *data++ = 0x12; // Type (FindMy) *data++ = 0x19; // Length - *data++ = 0x00; // Status + *data++ = 0x00; // Battery Status set to Full // Placeholder Empty Public Key without the MAC address for(size_t i = 0; i < 22; ++i) { *data++ = 0x00; } - *data++ = 0x00; // First 2 bits are the version, the rest is the battery level + *data++ = 0x00; // First 2 bits are the version *data++ = 0x00; // Hint (0x00) } @@ -102,12 +110,11 @@ void findmy_state_apply(FindMyState* state) { if(furi_hal_bt_extra_beacon_is_active()) { furi_check(furi_hal_bt_extra_beacon_stop()); } - furi_check(furi_hal_bt_extra_beacon_set_config(&state->config)); - + findmy_update_payload_battery(state->data, state->battery_level, state->tag_type); + 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()); } @@ -118,6 +125,32 @@ void findmy_state_sync_config(FindMyState* state) { state->config.max_adv_interval_ms = (state->broadcast_interval * 1000) + 150; state->config.adv_power_level = GapAdvPowerLevel_0dBm + state->transmit_power; memcpy(state->config.address, state->mac, sizeof(state->config.address)); + findmy_update_payload_battery(state->data, state->battery_level, state->tag_type); +} + +void findmy_update_payload_battery(uint8_t* data, uint8_t battery_level, FindMyType type) { + // Update the battery level in the payload + FURI_LOG_I("update_bat", "Before update: %d", battery_level); + if(type == FindMyTypeApple) { + switch(battery_level) { + case BATTERY_FULL: + data[6] = BATTERY_FULL; + break; + case BATTERY_MEDIUM: + data[6] = BATTERY_MEDIUM; + break; + case BATTERY_LOW: + data[6] = BATTERY_LOW; + break; + case BATTERY_CRITICAL: + data[6] = BATTERY_CRITICAL; + break; + default: + FURI_LOG_E("update_bat", "Invalid battery level: %d", battery_level); + return; + } + } + FURI_LOG_I("update_bat", "After update: %02X", data[6]); } void findmy_state_save(FindMyState* state) { @@ -141,10 +174,13 @@ void findmy_state_save(FindMyState* state) { tmp = state->tag_type; if(!flipper_format_write_uint32(file, "tag_type", &tmp, 1)) break; + tmp = state->battery_level; + if(!flipper_format_write_uint32(file, "battery_level", &tmp, 1)) break; + if(!flipper_format_write_bool(file, "show_mac", &state->show_mac, 1)) break; if(!flipper_format_write_hex(file, "mac", state->mac, sizeof(state->mac))) break; - + findmy_update_payload_battery(state->data, state->battery_level, state->tag_type); if(!flipper_format_write_hex( file, "data", state->data, findmy_state_data_size(state->tag_type))) break; diff --git a/applications/system/findmy/findmy_state.h b/applications/system/findmy/findmy_state.h index 813dfee414..e6b60ec7be 100644 --- a/applications/system/findmy/findmy_state.h +++ b/applications/system/findmy/findmy_state.h @@ -13,6 +13,7 @@ typedef enum { FindMyTypeTile, } FindMyType; + typedef struct { bool beacon_active; uint8_t broadcast_interval; @@ -24,6 +25,8 @@ typedef struct { // Generated from the other state values GapExtraBeaconConfig config; + + uint8_t battery_level; } FindMyState; bool findmy_state_load(FindMyState* out_state); @@ -34,4 +37,6 @@ void findmy_state_sync_config(FindMyState* state); void findmy_state_save(FindMyState* state); +void findmy_update_payload_battery(uint8_t* data, uint8_t battery_level, FindMyType type); + uint8_t findmy_state_data_size(FindMyType type); diff --git a/applications/system/findmy/scenes/findmy_scene_main.c b/applications/system/findmy/scenes/findmy_scene_main.c index e70b59fc54..86501f13d2 100644 --- a/applications/system/findmy/scenes/findmy_scene_main.c +++ b/applications/system/findmy/scenes/findmy_scene_main.c @@ -10,7 +10,7 @@ void findmy_scene_main_on_enter(void* context) { FindMy* app = context; findmy_main_set_callback(app->findmy_main, findmy_scene_main_callback, app); - + findmy_update_battery(app, app->state.battery_level); view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewMain); } @@ -26,6 +26,7 @@ bool findmy_scene_main_on_event(void* context, SceneManagerEvent event) { break; case FindMyMainEventBackground: app->state.beacon_active = true; + findmy_update_battery(app, app->state.battery_level); findmy_state_save(&app->state); if(!furi_hal_bt_extra_beacon_is_active()) { furi_check(furi_hal_bt_extra_beacon_start()); From 35b243634d5e02e131a1bef1d2dac28c570f998e Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 4 Apr 2024 23:25:35 -0400 Subject: [PATCH 2/6] switcheroo battery defines --- applications/system/findmy/findmy_i.h | 5 ----- applications/system/findmy/findmy_state.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/system/findmy/findmy_i.h b/applications/system/findmy/findmy_i.h index 2283b4a7aa..9476373fa4 100644 --- a/applications/system/findmy/findmy_i.h +++ b/applications/system/findmy/findmy_i.h @@ -24,11 +24,6 @@ void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]); #endif -#define BATTERY_FULL 0x00 -#define BATTERY_MEDIUM 0x50 -#define BATTERY_LOW 0xA0 -#define BATTERY_CRITICAL 0xF0 - struct FindMy { Gui* gui; Storage* storage; diff --git a/applications/system/findmy/findmy_state.h b/applications/system/findmy/findmy_state.h index e6b60ec7be..a39f574f62 100644 --- a/applications/system/findmy/findmy_state.h +++ b/applications/system/findmy/findmy_state.h @@ -7,6 +7,11 @@ #define FINDMY_STATE_DIR EXT_PATH("apps_data/findmy") #define FINDMY_STATE_PATH FINDMY_STATE_DIR "/findmy_state.txt" +#define BATTERY_FULL 0x00 +#define BATTERY_MEDIUM 0x50 +#define BATTERY_LOW 0xA0 +#define BATTERY_CRITICAL 0xF0 + typedef enum { FindMyTypeApple, FindMyTypeSamsung, From 75092380693099603429eebd862f68b4fa968b21 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 4 Apr 2024 23:33:24 -0400 Subject: [PATCH 3/6] im dummy --- applications/system/findmy/findmy_state.c | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/system/findmy/findmy_state.c b/applications/system/findmy/findmy_state.c index 2f39c268ad..7478589826 100644 --- a/applications/system/findmy/findmy_state.c +++ b/applications/system/findmy/findmy_state.c @@ -1,6 +1,5 @@ #include "findmy_state.h" -#include "findmy_i.h" #include #include #include From d42111193ab310447641ae19a7edde3013e1e492 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 4 Apr 2024 23:44:08 -0400 Subject: [PATCH 4/6] Update to latest README --- applications/system/findmy/README.md | 139 +++++++++++++++++++++------ 1 file changed, 112 insertions(+), 27 deletions(-) diff --git a/applications/system/findmy/README.md b/applications/system/findmy/README.md index e697aeb7a0..f6bf9fe871 100644 --- a/applications/system/findmy/README.md +++ b/applications/system/findmy/README.md @@ -1,10 +1,10 @@ -# FindMy Flipper - FindMy SmartTag Emulator +# FindMy Flipper - AirTag and SmartTag Emulator -This app extends the functionality of the FlipperZero's bluetooth capabilities, enabling it to act as an Apple AirTag or Samsung SmartTag, or even both simultaneously. It utilizes the FlipperZero's BLE beacon to broadcast a SmartTag signal to be picked up by the FindMy Network. I made this to serve as a versatile tool for tracking purposes, offering the ability to clone existing tags, generate OpenHaystack key pairs for integration with Apple's FindMy network, and tune the device's beacon broadcast settings. +This app extends the functionality of the FlipperZero's bluetooth capabilities, enabling it to act as an Apple AirTag, Samsung SmartTag, or a Tile Tracker. It utilizes the FlipperZero's BLE beacon to broadcast a SmartTag signal to be picked up by the FindMy Network. I made this to serve as a versatile tool for tracking purposes, offering the ability to clone existing tags, generate OpenHaystack key pairs for integration with Apple's FindMy network, and always know where your FlipperZero is. ## Features -1. Tag Emulation: Clone your existing Apple AirTag or Samsung SmartTag to the FlipperZero, or generate a key pair for use with the FindMy network without owning an actual AirTag. +1. Tag Emulation: Clone your existing Apple AirTag, Samsung SmartTag, or Tile Tracker to the FlipperZero, or generate a key pair for use with the FindMy network without owning an actual AirTag. 2. Customization: Users can adjust the interval between beacon broadcasts and modify the transmit power to suit their needs, optimizing for both visibility and battery life. 3. Efficient Background Operation: The app is optimized to run in the background, ensuring that your FlipperZero can still be tracked with minimal battery usage and without stopping normal use. @@ -14,38 +14,122 @@ This app extends the functionality of the FlipperZero's bluetooth capabilities, - **Option A:** Use the released/precompiled firmware appropriate (FAP) for your device. - **Option B:** Build the firmware yourself using `fbt/ufbt`. - Both Installation options require you to be running a dev build of firmware. When release gets access to the extra BLE beacon this will change, thank you! +- All firmware should now work with main branch, including icons + ### Step 2: Obtaining SmartTag Data +###### There are 2 methods to get SmartTag data depending on the type of tag you wish to emulate. Option A allows you to use Apple, Samsung, and Tile tags through the use of cloning the MAC Address and Payload of an actual tag. This also allows you to use the native app for tracking (Apple FindMy, Samsung SmartThing, Tile App). Option B allows you to emulate an Apple AirTag without needing to own an Apple device or airtag. This is done through key generation and requires a computer to download the location data. -#### Option A: Open Haystack Method -1. **Generate a Tag:** Download the `generate_keys.py` file and execute it in your terminal. (You will need cryptography ```python3 -m pip install cryptography```) -2. **Follow Prompts:** During execution, you'll be prompted for inputs. By the end, you'll obtain a **Private Key**, **Public Key**, **Payload**, and **MAC Address**. - - **Private Key** is necessary to receive location reports from Apple. - - **MAC Address** should be registered in the FlipperZero app: - 1. Open the app and navigate to the config menu. - 2. Choose "register tag" and enter the MAC Address when prompted. - 3. A payload dialog will appear next. Enter your **Payload** here. - 4. Click save. -3. **Configuration Completion:** With this setup, your device is ready for Open Haystack. Proceed with the specific steps for Open Haystack or MaclessHaystack based on your setup. - - Don't Own a Mac: https://github.com/dchristl/macless-haystack - - Own a Mac: https://github.com/seemoo-lab/openhaystack - -#### Option B: Cloning Existing Tag -1. **Pair a Tag:** First, pair an AirTag or Samsung SmartTag with your device. +
+ Option A: Cloning Existing Tag (Preferred and allows you to track without additional setup) + +1. **Pair a Tag:** First, pair an AirTag, Samsung SmartTag or Tile Tracker with your device. 2. **Enter 'Lost' Mode:** Keep the tag away from the device it's registered to for approximately 15 minutes. -3. **Download nrfConnect:** Install nrfConnect from the Apple App Store or Google Play Store. -4. **Filter and Scan:** +3. **Download nrfConnect or use an ESP32** Install nrfConnect from the Google Play Store. (Apple version doesn't reveal the needed Raw data, looking for a workaround) +4. OR **Use an ESP32-WROOM / ESP32-S3** Don't have an android? No problem! You can get all the data you need from an ESP32: https://github.com/MatthewKuKanich/ESP32-AirTag-Scanner (Skip to step 7 if using an ESP32) +5. **Filter and Scan:** - Open the app, click on filters, and exclude all except for the brand of your tag (Apple/Samsung). - Adjust the RSSI to the lowest setting (-40 dBm). - Initiate a scan. Wait for your SmartTag to appear as a "FindMy" device. -5. **Capture Data:** Click **Raw** or **View Raw** to capture your **payload** and note your tag's **MAC Address**. Immediately remove the tag's battery to prevent key/MAC rotation. -6. **Enter Data in FlipperZero App:** Input the captured **payload** and **MAC Address** into the FlipperZero app. +6. **Capture Data:** Click **Raw** or **View Raw** to capture your **payload** and note your tag's **MAC Address**. Immediately remove the tag's battery to prevent key/MAC rotation. + - The AirTag has now been cloned, if you put the battery back into the AirTag it will eventually rotate its keys with the Apple servers. This will invalidate the current keys on the Flipper. To prevent this you must keep the AirTag powered off / battery removed. You can always repeat these steps to return functionality to the Flipper. No need to get rid of the AirTag, you can always return to it if you desire, you just can't use both at the same time. +8. **Enter Data in FlipperZero App:** Input the captured **payload** and **MAC Address** into the FlipperZero app. +
+ +
+Option B: AirTag Key Generation +
+ +Video Tutorial: https://youtu.be/XGwHmwvQoqo?si=CAsKWEqGP5VFi9p9 + +### Prerequisites + +Before you begin, ensure you have the following installed on your system: + +- Docker Desktop +- Python +- Git + +## Step-by-Step Instructions + +### 1. Clone the Repository + +Navigate to Matthew KuKanich's GitHub repository, copy the repository URL, and clone it to your desired location using the terminal. +``` +git clone https://github.com/MatthewKuKanich/FindMyFlipper.git +``` +### 2. Set Up the AirTag Generation Folder + +Inside the cloned repository, locate the 'air tag generation' folder which contains all necessary files for creating AirTags. + +### 3. Start Docker Desktop + +Ensure Docker Desktop is running on your computer, as it is required for the server setup. + +### 4. Set Up a Server Using Docker + +Run the following Docker command to set up the server. This server emulates an environment that tricks Apple's authentication servers. +``` +docker run -d --restart always --name anisette-v3 -p 6969:6969 dadoum/anisette-v3-server:latest +``` +### 5. Create a Python Virtual Environment + +Navigate to the AirTag generation directory, then create and activate a Python virtual environment. You will run all scripts in this terminal. +``` +cd AirTagGeneration +``` +``` +python3 -m venv venv +``` +(or `python -m venv venv`) + +Activate the environment: + - Windows: +``` +.\venv\Scripts\activate.bat +``` + - Mac/Linux: +``` +source venv/bin/activate +``` +### 6. Install the Required Python Packages +``` +pip3 install -r requirements.txt +``` +### 7. Generate Keys for AirTags + +Run the ```generate_keys.py``` script in the current terminal to generate the keys needed for AirTags, which will be saved in a new folder called 'keys'. + + +### 8. Transfer the Generated Keys to Flipper Zero + +Move the '.Keys' file to your Flipper device by connecting it to your computer and using the Flipper's file management system. + - For ease of use, drag your `.keys` file onto your FlipperZero's SD card in the apps_data->findmy folder. You can import it directly from the app! + 1. Open the app and navigate to the config menu. + 2. Choose "register tag" and select the tag type. + 3. Either click import `.keys`, `.txt`, or enter Manually. + 4. If entering manually then a MAC and payload dialog will appear next. Enter your **MAC** then **Payload** here. + 5. Click save. + +### 9. Request Location Reports + +Use the ```request_reports.py``` script to request real-time location data, requiring your Apple ID and password for authentication. This will save your Apple login information to a auth file so you won't need to re-enter your Apple credentials. + +### 10. Generate an Advanced Location Map + +Finally, run the ```RequestReport&Map.py``` script to generate an interactive map of all location data in the past 24 hours. This script automates the process by requesting the location report using the hashed adv key in your ```keys``` folder, then decrypting that data from your private key located in the same `.keys` file. After the data is decrypted it will be displayed in the terminal. It then launches a mapping script that maps all the coordinates, connects them to show movement, displays a plethora of location metadata, and saves to an html file named by the date of the report. + +You're done! -### Step 3: Configuration -- Upon launching the app, choose whether to clone an AirTag or SmartTag, generate a new Open Haystack key pair, or adjust broadcast settings. + - If you want to use OpenHaystack or Macless instead, then you can follow the steps below. I don't recommend these methods due to reliability issues and setup complexity. +To use OpenHayStack for tracking, you must use MacOS lower than version 14 (Mail Plug-in Incompetiablity of MacOS 14+ seemoo-lab/openhaystack#224). If you do own a device, I believe a convertor script can be provided without much of effort. If you do not own a Mac device or the system has been upgraded to 14 and beyond. The alternative solutions includes, -### Step 4: Tracking -- Once the app is configured, your FlipperZero can be tracked using the relevant platform's tracking service (FindMy app for Apple devices, SmartThings for Samsung devices, and respective web browsers). + https://github.com/dchristl/macless-haystack + +If using this solution, be sure to only use the `generate_keys.py` script from this repo in the AirTagGeneration folder. Not the ones included in that repo as the formatting of the key file changes. (Mine includes data that the FlipperZero needs for proper importing) +
+### On The Flipper: Configuration on the FlipperZero (if not completed yet) +- Upon launching the app, open the config menu and either click ```Import Tag From File``` or ```Register Tag Manually```. Put your generated .keys file onto the FlipperZero SD card inside the AppsData/FindMyFlipper folder to import from file. Or you can manually enter the tag information. When using the cloning method, you can export a .txt file from nrfConnect (click save button) amd place that in the same folder in order to import. Customization @@ -60,10 +144,11 @@ Compatibility - Apple devices for AirTag tracking via the FindMy network. - Any device that supports Samsung SmartTag tracking, including web browsers (previously FindMyMobile). +- Tile Trackers via the Tile App Thanks -- Huge thanks to all the people that contributed to the OpenHaystack project, supporting projects, and guides on the subject. This wouldn't be a thing without any of you! +- Huge thanks to all the people that contributed to the OpenHaystack project, supporting projects, and guides on the subject. This wouldn't be a thing without any of you! Special thanks to Chapoly1305 for introducing me to the FindMy network and WillyJL for helping get the app input working and overall overhaul of the apps functions! Legal and Privacy From 11357734e7696fd1bad45089fce533b571c302e0 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 18 Apr 2024 20:28:18 -0400 Subject: [PATCH 5/6] FindMy Flipper Battery Status Refactor, Unify State Sync --- applications/system/findmy/findmy.c | 55 +++++++------------ applications/system/findmy/findmy_i.h | 3 +- applications/system/findmy/findmy_state.c | 37 ++++++------- applications/system/findmy/findmy_state.h | 1 - .../findmy_scene_config_import_result.c | 4 +- .../system/findmy/scenes/findmy_scene_main.c | 2 - 6 files changed, 41 insertions(+), 61 deletions(-) diff --git a/applications/system/findmy/findmy.c b/applications/system/findmy/findmy.c index da8bceb2ae..26381351dc 100644 --- a/applications/system/findmy/findmy.c +++ b/applications/system/findmy/findmy.c @@ -103,17 +103,8 @@ void findmy_change_broadcast_interval(FindMy* app, uint8_t value) { return; } app->state.broadcast_interval = value; - findmy_state_sync_config(&app->state); - findmy_state_save(&app->state); findmy_main_update_interval(app->findmy_main, app->state.broadcast_interval); - if(furi_hal_bt_extra_beacon_is_active()) { - // Always check if beacon is active before changing config - furi_check(furi_hal_bt_extra_beacon_stop()); - } - furi_check(furi_hal_bt_extra_beacon_set_config(&app->state.config)); - if(app->state.beacon_active) { - furi_check(furi_hal_bt_extra_beacon_start()); - } + findmy_state_save_and_apply(app, &app->state); } void findmy_change_transmit_power(FindMy* app, uint8_t value) { @@ -121,49 +112,32 @@ void findmy_change_transmit_power(FindMy* app, uint8_t value) { return; } app->state.transmit_power = value; - findmy_state_sync_config(&app->state); - findmy_state_save(&app->state); - if(furi_hal_bt_extra_beacon_is_active()) { - furi_check(furi_hal_bt_extra_beacon_stop()); - } - furi_check(furi_hal_bt_extra_beacon_set_config(&app->state.config)); - if(app->state.beacon_active) { - furi_check(furi_hal_bt_extra_beacon_start()); - } + findmy_state_save_and_apply(app, &app->state); } void findmy_toggle_show_mac(FindMy* app, bool show_mac) { app->state.show_mac = show_mac; - findmy_state_sync_config(&app->state); - findmy_state_save(&app->state); findmy_main_toggle_mac(app->findmy_main, app->state.show_mac); + findmy_state_save_and_apply(app, &app->state); } void findmy_toggle_beacon(FindMy* app) { app->state.beacon_active = !app->state.beacon_active; - findmy_state_save(&app->state); - if(furi_hal_bt_extra_beacon_is_active()) { - furi_check(furi_hal_bt_extra_beacon_stop()); - } - if(app->state.beacon_active) { - furi_check(furi_hal_bt_extra_beacon_start()); - } + findmy_state_save_and_apply(app, &app->state); findmy_main_update_active(app->findmy_main, furi_hal_bt_extra_beacon_is_active()); - findmy_update_battery(app, app->state.battery_level); } 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_state_save_and_apply(app, &app->state); findmy_main_update_type(app->findmy_main, type); - FURI_LOG_I("TagType2", "Tag Type: %d", type); } -void findmy_update_battery(FindMy* app, uint8_t battery_level) { +void findmy_state_save_and_apply(FindMy* app, FindMyState* state) { uint32_t battery_capacity = furi_hal_power_get_battery_full_capacity(); uint32_t battery_remaining = furi_hal_power_get_battery_remaining_capacity(); uint16_t battery_percent = (battery_remaining * 100) / battery_capacity; + uint8_t battery_level; if(battery_percent > 80) { battery_level = BATTERY_FULL; @@ -174,10 +148,19 @@ void findmy_update_battery(FindMy* app, uint8_t battery_level) { } else { battery_level = BATTERY_CRITICAL; } - app->state.battery_level = battery_level; - findmy_state_sync_config(&app->state); - findmy_state_save(&app->state); + + if(furi_hal_bt_extra_beacon_is_active()) { + furi_check(furi_hal_bt_extra_beacon_stop()); + } + furi_check( + furi_hal_bt_extra_beacon_set_data(state->data, findmy_state_data_size(state->tag_type))); + findmy_state_sync_config(state); + findmy_state_save(state); + furi_check(furi_hal_bt_extra_beacon_set_config(&state->config)); + if(state->beacon_active) { + furi_check(furi_hal_bt_extra_beacon_start()); + } } void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) { diff --git a/applications/system/findmy/findmy_i.h b/applications/system/findmy/findmy_i.h index 9476373fa4..b4ffa5c50f 100644 --- a/applications/system/findmy/findmy_i.h +++ b/applications/system/findmy/findmy_i.h @@ -38,6 +38,7 @@ struct FindMy { uint8_t mac_buf[EXTRA_BEACON_MAC_ADDR_SIZE]; uint8_t packet_buf[EXTRA_BEACON_MAX_DATA_SIZE]; + uint8_t battery_level; FindMyState state; }; @@ -54,4 +55,4 @@ void findmy_change_transmit_power(FindMy* app, uint8_t value); void findmy_toggle_show_mac(FindMy* app, bool show_mac); void findmy_set_tag_type(FindMy* app, FindMyType type); void findmy_toggle_beacon(FindMy* app); -void findmy_update_battery(FindMy* app, uint8_t battery_level); +void findmy_state_save_and_apply(FindMy* app, FindMyState* state); diff --git a/applications/system/findmy/findmy_state.c b/applications/system/findmy/findmy_state.c index 7478589826..b1b1e272a3 100644 --- a/applications/system/findmy/findmy_state.c +++ b/applications/system/findmy/findmy_state.c @@ -105,13 +105,13 @@ bool findmy_state_load(FindMyState* out_state) { } void findmy_state_apply(FindMyState* state) { - // Stop any running beacon + // This function applies initial state to the beacon (loaded values) if(furi_hal_bt_extra_beacon_is_active()) { furi_check(furi_hal_bt_extra_beacon_stop()); } furi_check(furi_hal_bt_extra_beacon_set_config(&state->config)); findmy_update_payload_battery(state->data, state->battery_level, state->tag_type); - + furi_check( furi_hal_bt_extra_beacon_set_data(state->data, findmy_state_data_size(state->tag_type))); if(state->beacon_active) { @@ -129,27 +129,25 @@ void findmy_state_sync_config(FindMyState* state) { void findmy_update_payload_battery(uint8_t* data, uint8_t battery_level, FindMyType type) { // Update the battery level in the payload - FURI_LOG_I("update_bat", "Before update: %d", battery_level); if(type == FindMyTypeApple) { switch(battery_level) { - case BATTERY_FULL: - data[6] = BATTERY_FULL; - break; - case BATTERY_MEDIUM: - data[6] = BATTERY_MEDIUM; - break; - case BATTERY_LOW: - data[6] = BATTERY_LOW; - break; - case BATTERY_CRITICAL: - data[6] = BATTERY_CRITICAL; - break; - default: - FURI_LOG_E("update_bat", "Invalid battery level: %d", battery_level); - return; + case BATTERY_FULL: + data[6] = BATTERY_FULL; + break; + case BATTERY_MEDIUM: + data[6] = BATTERY_MEDIUM; + break; + case BATTERY_LOW: + data[6] = BATTERY_LOW; + break; + case BATTERY_CRITICAL: + data[6] = BATTERY_CRITICAL; + break; + default: + FURI_LOG_E("update_bat", "Invalid battery level: %d", battery_level); + return; } } - FURI_LOG_I("update_bat", "After update: %02X", data[6]); } void findmy_state_save(FindMyState* state) { @@ -184,7 +182,6 @@ void findmy_state_save(FindMyState* state) { file, "data", state->data, findmy_state_data_size(state->tag_type))) break; } while(0); - flipper_format_free(file); furi_record_close(RECORD_STORAGE); } diff --git a/applications/system/findmy/findmy_state.h b/applications/system/findmy/findmy_state.h index a39f574f62..75753135ce 100644 --- a/applications/system/findmy/findmy_state.h +++ b/applications/system/findmy/findmy_state.h @@ -18,7 +18,6 @@ typedef enum { FindMyTypeTile, } FindMyType; - typedef struct { bool beacon_active; uint8_t broadcast_interval; diff --git a/applications/system/findmy/scenes/findmy_scene_config_import_result.c b/applications/system/findmy/scenes/findmy_scene_config_import_result.c index f15f55c069..c6cd956655 100644 --- a/applications/system/findmy/scenes/findmy_scene_config_import_result.c +++ b/applications/system/findmy/scenes/findmy_scene_config_import_result.c @@ -29,7 +29,9 @@ void findmy_scene_config_import_result_on_enter(void* context) { popup_set_timeout(popup, 1500); popup_set_context(popup, app); popup_set_callback(popup, findmy_scene_config_import_result_callback); - + findmy_main_update_active(app->findmy_main, furi_hal_bt_extra_beacon_is_active()); + findmy_main_update_mac(app->findmy_main, app->state.mac); + findmy_main_update_type(app->findmy_main, app->state.tag_type); view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewPopup); } diff --git a/applications/system/findmy/scenes/findmy_scene_main.c b/applications/system/findmy/scenes/findmy_scene_main.c index 86501f13d2..76504f36fd 100644 --- a/applications/system/findmy/scenes/findmy_scene_main.c +++ b/applications/system/findmy/scenes/findmy_scene_main.c @@ -10,7 +10,6 @@ void findmy_scene_main_on_enter(void* context) { FindMy* app = context; findmy_main_set_callback(app->findmy_main, findmy_scene_main_callback, app); - findmy_update_battery(app, app->state.battery_level); view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewMain); } @@ -26,7 +25,6 @@ bool findmy_scene_main_on_event(void* context, SceneManagerEvent event) { break; case FindMyMainEventBackground: app->state.beacon_active = true; - findmy_update_battery(app, app->state.battery_level); findmy_state_save(&app->state); if(!furi_hal_bt_extra_beacon_is_active()) { furi_check(furi_hal_bt_extra_beacon_start()); From 5f260af443198e4423cffa1928ee03a5cd463c08 Mon Sep 17 00:00:00 2001 From: Matthew Date: Thu, 18 Apr 2024 21:18:22 -0400 Subject: [PATCH 6/6] small changes --- applications/system/findmy/findmy_i.h | 1 - applications/system/findmy/findmy_state.c | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/applications/system/findmy/findmy_i.h b/applications/system/findmy/findmy_i.h index b4ffa5c50f..1d1178d584 100644 --- a/applications/system/findmy/findmy_i.h +++ b/applications/system/findmy/findmy_i.h @@ -38,7 +38,6 @@ struct FindMy { uint8_t mac_buf[EXTRA_BEACON_MAC_ADDR_SIZE]; uint8_t packet_buf[EXTRA_BEACON_MAX_DATA_SIZE]; - uint8_t battery_level; FindMyState state; }; diff --git a/applications/system/findmy/findmy_state.c b/applications/system/findmy/findmy_state.c index b1b1e272a3..8a60a312e5 100644 --- a/applications/system/findmy/findmy_state.c +++ b/applications/system/findmy/findmy_state.c @@ -42,13 +42,6 @@ bool findmy_state_load(FindMyState* out_state) { } state.tag_type = tmp; - if(!flipper_format_read_uint32(file, "battery_level", &tmp, 1)) { - tmp = 0x00; // Default battery level set to Full - flipper_format_rewind(file); - } - FURI_LOG_I("findmy_load", "Saved Battery: %ld", tmp); - state.battery_level = tmp; - if(!flipper_format_read_hex(file, "mac", state.mac, sizeof(state.mac))) break; if(!flipper_format_read_hex( @@ -171,9 +164,6 @@ void findmy_state_save(FindMyState* state) { tmp = state->tag_type; if(!flipper_format_write_uint32(file, "tag_type", &tmp, 1)) break; - tmp = state->battery_level; - if(!flipper_format_write_uint32(file, "battery_level", &tmp, 1)) break; - if(!flipper_format_write_bool(file, "show_mac", &state->show_mac, 1)) break; if(!flipper_format_write_hex(file, "mac", state->mac, sizeof(state->mac))) break;