mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-10 06:54:19 +00:00
New way of changing device name
Settings scene, char Validator, Idea -> by Willy-JL Implemented by me Kod plohoi, ochen plohoi, kto mozhet - sdelaite kak nado, esli smozhete :) Ya luche varianta ne pridumal poka 4to
This commit is contained in:
parent
bdc720ac7d
commit
c2713eff87
20 changed files with 316 additions and 72 deletions
|
@ -9,6 +9,9 @@
|
||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
#include <cli/cli_vcp.h>
|
#include <cli/cli_vcp.h>
|
||||||
|
|
||||||
|
#include <toolbox/namechanger.h>
|
||||||
|
#include <bt/bt_service/bt.h>
|
||||||
|
|
||||||
#include "animations/animation_manager.h"
|
#include "animations/animation_manager.h"
|
||||||
#include "desktop/scenes/desktop_scene.h"
|
#include "desktop/scenes/desktop_scene.h"
|
||||||
#include "desktop/scenes/desktop_scene_i.h"
|
#include "desktop/scenes/desktop_scene_i.h"
|
||||||
|
@ -426,6 +429,26 @@ int32_t desktop_srv(void* p) {
|
||||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault);
|
scene_manager_next_scene(desktop->scene_manager, DesktopSceneFault);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I added some very bydlo kod here, and thrown some delays to make it worse, pls don't look at it, it will make you cry from laugh
|
||||||
|
if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) {
|
||||||
|
if(NameChanger_Init()) {
|
||||||
|
Cli* cli = furi_record_open(RECORD_CLI);
|
||||||
|
cli_session_close(cli);
|
||||||
|
furi_delay_ms(2);
|
||||||
|
cli_session_open(cli, &cli_vcp);
|
||||||
|
furi_record_close(RECORD_CLI);
|
||||||
|
|
||||||
|
furi_delay_ms(3);
|
||||||
|
Bt* bt = furi_record_open(RECORD_BT);
|
||||||
|
if(!bt_set_profile(bt, BtProfileSerial)) {
|
||||||
|
FURI_LOG_D(TAG, "Failed to touch bluetooth to name change");
|
||||||
|
}
|
||||||
|
furi_record_close(RECORD_BT);
|
||||||
|
bt = NULL;
|
||||||
|
furi_delay_ms(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view_dispatcher_run(desktop->view_dispatcher);
|
view_dispatcher_run(desktop->view_dispatcher);
|
||||||
desktop_free(desktop);
|
desktop_free(desktop);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ void popup_free(Popup* popup);
|
||||||
*/
|
*/
|
||||||
View* popup_get_view(Popup* popup);
|
View* popup_get_view(Popup* popup);
|
||||||
|
|
||||||
/** Set popup header text
|
/** Set popup callback function
|
||||||
*
|
*
|
||||||
* @param popup Popup instance
|
* @param popup Popup instance
|
||||||
* @param callback PopupCallback
|
* @param callback PopupCallback
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <gui/modules/popup.h>
|
#include <gui/modules/popup.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
|
#include <toolbox/namechanger.h>
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
#include <power/power_service/power.h>
|
||||||
|
|
||||||
#include "desktop_settings_app.h"
|
#include "desktop_settings_app.h"
|
||||||
#include "scenes/desktop_settings_scene.h"
|
#include "scenes/desktop_settings_scene.h"
|
||||||
|
@ -62,11 +65,41 @@ DesktopSettingsApp* desktop_settings_app_alloc() {
|
||||||
app->view_dispatcher,
|
app->view_dispatcher,
|
||||||
DesktopSettingsAppViewIdPinSetupHowto2,
|
DesktopSettingsAppViewIdPinSetupHowto2,
|
||||||
desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view));
|
desktop_settings_view_pin_setup_howto2_get_view(app->pin_setup_howto2_view));
|
||||||
|
|
||||||
|
// Text Input
|
||||||
|
app->text_input = text_input_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
app->view_dispatcher,
|
||||||
|
DesktopSettingsAppViewTextInput,
|
||||||
|
text_input_get_view(app->text_input));
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
void desktop_settings_app_free(DesktopSettingsApp* app) {
|
void desktop_settings_app_free(DesktopSettingsApp* app) {
|
||||||
furi_assert(app);
|
furi_assert(app);
|
||||||
|
|
||||||
|
bool temp_save_name = app->save_name;
|
||||||
|
// Save name if set or remove file
|
||||||
|
if(temp_save_name) {
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
if(strcmp(app->device_name, "") == 0) {
|
||||||
|
storage_simply_remove(storage, NAMECHANGER_PATH);
|
||||||
|
} else {
|
||||||
|
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!flipper_format_file_open_always(file, NAMECHANGER_PATH)) break;
|
||||||
|
if(!flipper_format_write_header_cstr(file, NAMECHANGER_HEADER, NAMECHANGER_VERSION))
|
||||||
|
break;
|
||||||
|
if(!flipper_format_write_string_cstr(file, "Name", app->device_name)) break;
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
flipper_format_free(file);
|
||||||
|
}
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
}
|
||||||
|
|
||||||
// Variable item list
|
// Variable item list
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
|
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewMenu);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList);
|
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList);
|
||||||
|
@ -74,6 +107,10 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
|
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto);
|
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2);
|
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewIdPinSetupHowto2);
|
||||||
|
// TextInput
|
||||||
|
view_dispatcher_remove_view(app->view_dispatcher, DesktopSettingsAppViewTextInput);
|
||||||
|
text_input_free(app->text_input);
|
||||||
|
|
||||||
variable_item_list_free(app->variable_item_list);
|
variable_item_list_free(app->variable_item_list);
|
||||||
submenu_free(app->submenu);
|
submenu_free(app->submenu);
|
||||||
popup_free(app->popup);
|
popup_free(app->popup);
|
||||||
|
@ -87,6 +124,10 @@ void desktop_settings_app_free(DesktopSettingsApp* app) {
|
||||||
furi_record_close(RECORD_DIALOGS);
|
furi_record_close(RECORD_DIALOGS);
|
||||||
furi_record_close(RECORD_GUI);
|
furi_record_close(RECORD_GUI);
|
||||||
free(app);
|
free(app);
|
||||||
|
|
||||||
|
if(temp_save_name) {
|
||||||
|
power_reboot(PowerBootModeNormal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int32_t desktop_settings_app(void* p) {
|
extern int32_t desktop_settings_app(void* p) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
#include <gui/modules/submenu.h>
|
#include <gui/modules/submenu.h>
|
||||||
#include <gui/modules/variable_item_list.h>
|
#include <gui/modules/variable_item_list.h>
|
||||||
|
#include <gui/modules/text_input.h>
|
||||||
#include <dialogs/dialogs.h>
|
#include <dialogs/dialogs.h>
|
||||||
#include <assets_icons.h>
|
#include <assets_icons.h>
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ typedef enum {
|
||||||
DesktopSettingsAppViewIdPinInput,
|
DesktopSettingsAppViewIdPinInput,
|
||||||
DesktopSettingsAppViewIdPinSetupHowto,
|
DesktopSettingsAppViewIdPinSetupHowto,
|
||||||
DesktopSettingsAppViewIdPinSetupHowto2,
|
DesktopSettingsAppViewIdPinSetupHowto2,
|
||||||
|
DesktopSettingsAppViewTextInput,
|
||||||
} DesktopSettingsAppView;
|
} DesktopSettingsAppView;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -32,6 +34,7 @@ typedef struct {
|
||||||
ViewDispatcher* view_dispatcher;
|
ViewDispatcher* view_dispatcher;
|
||||||
VariableItemList* variable_item_list;
|
VariableItemList* variable_item_list;
|
||||||
Submenu* submenu;
|
Submenu* submenu;
|
||||||
|
TextInput* text_input;
|
||||||
Popup* popup;
|
Popup* popup;
|
||||||
DesktopViewPinInput* pin_input_view;
|
DesktopViewPinInput* pin_input_view;
|
||||||
DesktopSettingsViewPinSetupHowto* pin_setup_howto_view;
|
DesktopSettingsViewPinSetupHowto* pin_setup_howto_view;
|
||||||
|
@ -40,5 +43,8 @@ typedef struct {
|
||||||
PinCode pincode_buffer;
|
PinCode pincode_buffer;
|
||||||
bool pincode_buffer_filled;
|
bool pincode_buffer_filled;
|
||||||
|
|
||||||
|
bool save_name;
|
||||||
|
char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH];
|
||||||
|
|
||||||
uint8_t menu_idx;
|
uint8_t menu_idx;
|
||||||
} DesktopSettingsApp;
|
} DesktopSettingsApp;
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include "../desktop_settings_app.h"
|
||||||
|
#include <desktop/desktop_settings.h>
|
||||||
|
#include "desktop_settings_scene.h"
|
||||||
|
|
||||||
|
enum TextInputIndex {
|
||||||
|
TextInputResultOk,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void desktop_settings_scene_change_name_text_input_callback(void* context) {
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
|
||||||
|
app->save_name = true;
|
||||||
|
view_dispatcher_send_custom_event(app->view_dispatcher, TextInputResultOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool desktop_settings_scene_change_name_validator(
|
||||||
|
const char* text,
|
||||||
|
FuriString* error,
|
||||||
|
void* context) {
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
|
for(; *text; ++text) {
|
||||||
|
const char c = *text;
|
||||||
|
if((c < '0' || c > '9') && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
|
||||||
|
furi_string_printf(error, "Please only\nenter letters\nand numbers!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_settings_scene_change_name_on_enter(void* context) {
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
TextInput* text_input = app->text_input;
|
||||||
|
|
||||||
|
text_input_set_header_text(text_input, "Leave empty for default");
|
||||||
|
|
||||||
|
text_input_set_validator(text_input, desktop_settings_scene_change_name_validator, NULL);
|
||||||
|
|
||||||
|
text_input_set_minimum_length(text_input, 0);
|
||||||
|
|
||||||
|
text_input_set_result_callback(
|
||||||
|
text_input,
|
||||||
|
desktop_settings_scene_change_name_text_input_callback,
|
||||||
|
app,
|
||||||
|
app->device_name,
|
||||||
|
FURI_HAL_VERSION_ARRAY_NAME_LENGTH,
|
||||||
|
true);
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewTextInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool desktop_settings_scene_change_name_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
consumed = true;
|
||||||
|
switch(event.event) {
|
||||||
|
case TextInputResultOk:
|
||||||
|
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneNamePopup);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_settings_scene_change_name_on_exit(void* context) {
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
text_input_reset(app->text_input);
|
||||||
|
}
|
|
@ -9,3 +9,6 @@ ADD_SCENE(desktop_settings, pin_setup, PinSetup)
|
||||||
ADD_SCENE(desktop_settings, pin_setup_howto, PinSetupHowto)
|
ADD_SCENE(desktop_settings, pin_setup_howto, PinSetupHowto)
|
||||||
ADD_SCENE(desktop_settings, pin_setup_howto2, PinSetupHowto2)
|
ADD_SCENE(desktop_settings, pin_setup_howto2, PinSetupHowto2)
|
||||||
ADD_SCENE(desktop_settings, pin_setup_done, PinSetupDone)
|
ADD_SCENE(desktop_settings, pin_setup_done, PinSetupDone)
|
||||||
|
|
||||||
|
ADD_SCENE(desktop_settings, change_name, ChangeName)
|
||||||
|
ADD_SCENE(desktop_settings, name_popup, NamePopup)
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <core/check.h>
|
||||||
|
#include <gui/scene_manager.h>
|
||||||
|
#include <gui/modules/popup.h>
|
||||||
|
|
||||||
|
#include "../desktop_settings_app.h"
|
||||||
|
#include <desktop/desktop_settings.h>
|
||||||
|
#include "desktop_settings_scene.h"
|
||||||
|
|
||||||
|
#define SCENE_EVENT_EXIT (0U)
|
||||||
|
|
||||||
|
static void name_popup_back_callback(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_settings_scene_name_popup_on_enter(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
|
||||||
|
popup_set_context(app->popup, app);
|
||||||
|
popup_set_callback(app->popup, name_popup_back_callback);
|
||||||
|
popup_set_header(app->popup, "Name is set!", 64, 20, AlignCenter, AlignCenter);
|
||||||
|
popup_set_text(
|
||||||
|
app->popup, "Your Flipper will be\nrestarted on exit.", 64, 40, AlignCenter, AlignCenter);
|
||||||
|
popup_set_timeout(app->popup, 2100);
|
||||||
|
popup_enable_timeout(app->popup);
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPopup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool desktop_settings_scene_name_popup_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
DesktopSettingsApp* app = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
switch(event.event) {
|
||||||
|
case SCENE_EVENT_EXIT:
|
||||||
|
scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
app->scene_manager, DesktopSettingsAppSceneStart);
|
||||||
|
consumed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
consumed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void desktop_settings_scene_name_popup_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
#define SCENE_EVENT_SELECT_PIN_SETUP 3
|
#define SCENE_EVENT_SELECT_PIN_SETUP 3
|
||||||
#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 4
|
#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 4
|
||||||
#define SCENE_EVENT_SELECT_BATTERY_DISPLAY 5
|
#define SCENE_EVENT_SELECT_BATTERY_DISPLAY 5
|
||||||
|
#define SCENE_EVENT_SELECT_CHANGE_NAME 6
|
||||||
|
|
||||||
#define AUTO_LOCK_DELAY_COUNT 9
|
#define AUTO_LOCK_DELAY_COUNT 9
|
||||||
const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = {
|
const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = {
|
||||||
|
@ -105,6 +106,8 @@ void desktop_settings_scene_start_on_enter(void* context) {
|
||||||
variable_item_set_current_value_index(item, value_index);
|
variable_item_set_current_value_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, battery_view_count_text[value_index]);
|
variable_item_set_current_value_text(item, battery_view_count_text[value_index]);
|
||||||
|
|
||||||
|
variable_item_list_add(variable_item_list, "Change Flipper Name", 0, NULL, app);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList);
|
view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +142,10 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even
|
||||||
case SCENE_EVENT_SELECT_BATTERY_DISPLAY:
|
case SCENE_EVENT_SELECT_BATTERY_DISPLAY:
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
|
case SCENE_EVENT_SELECT_CHANGE_NAME:
|
||||||
|
scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneChangeName);
|
||||||
|
consumed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return consumed;
|
return consumed;
|
||||||
|
|
|
@ -1,35 +1,10 @@
|
||||||
# How to change Flipper name:
|
# How to change Flipper name:
|
||||||
|
|
||||||
## Instruction
|
## Instruction
|
||||||
1. Read [How to build](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToBuild.md) and [How to install](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md) to know how to build and install firmware
|
1. Go to Settings -> Desktop -> Change Flipper Name
|
||||||
2. Follow how to build instructions to prepare all things before continuing
|
2. Enter your new custom name for your flipper and click `Save`, **name will be saved on microSD card, and will stay same after firmware updates**
|
||||||
3. Run release build to verify all is ok - `./fbt COMPACT=1 DEBUG=0 updater_package`
|
3. You will see a message `Name is set!` and when you exit from settings -> flipper will automatically reboot!
|
||||||
4. Clear build files - `./fbt COMPACT=1 DEBUG=0 updater_package -c`
|
4. After reboot you will see your new custom name in device info and right screen `passport`
|
||||||
5. Run command with extra environment var before `./fbt` that variable should contain your custom name in alphanumeric characters - max length 8 chars
|
5. Done!
|
||||||
`CUSTOM_FLIPPER_NAME=Name ./fbt COMPACT=1 DEBUG=0 updater_package` - where `Name` write your custom name
|
|
||||||
6. Copy `dist/f7-C/f7-update-local` folder to microSD `update/myfw/` and run `update` file on flipper from file manager app (Archive)
|
|
||||||
7. Flash from microSD card only!!!! .dfu update from qFlipper will not work properly since name and serial number will be changed
|
|
||||||
8. Done, you will have custom name, serial number and bluetooth mac address
|
|
||||||
|
|
||||||
9. Also you can skip 5-7 and flash with `CUSTOM_FLIPPER_NAME=Name ./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full`
|
**To reset device name to default - do same steps but do not enter any characters, leave it empty and click** `Save`
|
||||||
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
### I'm using Windows and name changing / building firmware doesn't work
|
|
||||||
- Use PowerShell or VSCode terminal(powershell by default)
|
|
||||||
- Clear build files - `.\fbt.cmd COMPACT=1 DEBUG=0 updater_package -c`
|
|
||||||
- Enter this in same terminal `$Env:CUSTOM_FLIPPER_NAME="Name"`
|
|
||||||
- Run release build - `.\fbt.cmd COMPACT=1 DEBUG=0 updater_package`
|
|
||||||
- Flash as described before (see 6.)
|
|
||||||
- If something still not work - Run powershell or VSCode as Admin
|
|
||||||
### Name stays same for every new build
|
|
||||||
- Clear build files - `./fbt COMPACT=1 DEBUG=0 updater_package -c`
|
|
||||||
- Try again
|
|
||||||
### I want to return my original name and serial number
|
|
||||||
- Flash stock FW or any CFW using microSD card offline update method
|
|
||||||
|
|
||||||
Or
|
|
||||||
- Clear build files - `./fbt COMPACT=1 DEBUG=0 updater_package -c`
|
|
||||||
- Run release build - `./fbt COMPACT=1 DEBUG=0 updater_package`
|
|
||||||
- Copy `dist/f7-C/f7-update-local` folder to microSD `update/myfw/` and run `update` file on flipper from file manager app (Archive)
|
|
||||||
- Flash from microSD card only, .dfu update from qFlipper will not work properly since name and serial number will be changed
|
|
|
@ -1486,6 +1486,7 @@ Function,+,furi_hal_version_get_model_name,const char*,
|
||||||
Function,+,furi_hal_version_get_name_ptr,const char*,
|
Function,+,furi_hal_version_get_name_ptr,const char*,
|
||||||
Function,+,furi_hal_version_get_otp_version,FuriHalVersionOtpVersion,
|
Function,+,furi_hal_version_get_otp_version,FuriHalVersionOtpVersion,
|
||||||
Function,-,furi_hal_version_init,void,
|
Function,-,furi_hal_version_init,void,
|
||||||
|
Function,-,furi_hal_version_set_name,void,const char*
|
||||||
Function,+,furi_hal_version_uid,const uint8_t*,
|
Function,+,furi_hal_version_uid,const uint8_t*,
|
||||||
Function,+,furi_hal_version_uid_size,size_t,
|
Function,+,furi_hal_version_uid_size,size_t,
|
||||||
Function,-,furi_hal_vibro_init,void,
|
Function,-,furi_hal_vibro_init,void,
|
||||||
|
@ -4597,6 +4598,7 @@ Function,+,version_get_gitbranchnum,const char*,const Version*
|
||||||
Function,+,version_get_githash,const char*,const Version*
|
Function,+,version_get_githash,const char*,const Version*
|
||||||
Function,+,version_get_target,uint8_t,const Version*
|
Function,+,version_get_target,uint8_t,const Version*
|
||||||
Function,+,version_get_version,const char*,const Version*
|
Function,+,version_get_version,const char*,const Version*
|
||||||
|
Function,-,version_set_custom_name,void,"Version*, const char*"
|
||||||
Function,-,vfiprintf,int,"FILE*, const char*, __gnuc_va_list"
|
Function,-,vfiprintf,int,"FILE*, const char*, __gnuc_va_list"
|
||||||
Function,-,vfiscanf,int,"FILE*, const char*, __gnuc_va_list"
|
Function,-,vfiscanf,int,"FILE*, const char*, __gnuc_va_list"
|
||||||
Function,-,vfprintf,int,"FILE*, const char*, __gnuc_va_list"
|
Function,-,vfprintf,int,"FILE*, const char*, __gnuc_va_list"
|
||||||
|
|
|
|
@ -90,7 +90,7 @@ typedef struct {
|
||||||
|
|
||||||
static FuriHalVersion furi_hal_version = {0};
|
static FuriHalVersion furi_hal_version = {0};
|
||||||
|
|
||||||
static void furi_hal_version_set_name(const char* name) {
|
void furi_hal_version_set_name(const char* name) {
|
||||||
if(name != NULL) {
|
if(name != NULL) {
|
||||||
strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH);
|
strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH);
|
||||||
snprintf(
|
snprintf(
|
||||||
|
|
|
@ -176,6 +176,10 @@ const char* furi_hal_version_get_device_name_ptr();
|
||||||
*/
|
*/
|
||||||
const char* furi_hal_version_get_ble_local_device_name_ptr();
|
const char* furi_hal_version_get_ble_local_device_name_ptr();
|
||||||
|
|
||||||
|
/** Set flipper name
|
||||||
|
*/
|
||||||
|
void furi_hal_version_set_name(const char* name);
|
||||||
|
|
||||||
/** Get BLE MAC address
|
/** Get BLE MAC address
|
||||||
*
|
*
|
||||||
* @return pointer to BLE MAC address
|
* @return pointer to BLE MAC address
|
||||||
|
|
53
lib/toolbox/namechanger.c
Normal file
53
lib/toolbox/namechanger.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include "namechanger.h"
|
||||||
|
#include <furi_hal_version.h>
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
|
||||||
|
#define TAG "NameChanger"
|
||||||
|
|
||||||
|
bool NameChanger_Init() {
|
||||||
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
|
FuriString* str = furi_string_alloc();
|
||||||
|
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||||
|
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint32_t version;
|
||||||
|
if(!flipper_format_file_open_existing(file, NAMECHANGER_PATH)) break;
|
||||||
|
if(!flipper_format_read_header(file, str, &version)) break;
|
||||||
|
if(furi_string_cmp_str(str, NAMECHANGER_HEADER)) break;
|
||||||
|
if(version != NAMECHANGER_VERSION) break;
|
||||||
|
|
||||||
|
if(!flipper_format_read_string(file, "Name", str)) break;
|
||||||
|
// Check for size
|
||||||
|
size_t temp_string_size = furi_string_size(str);
|
||||||
|
if(temp_string_size > (size_t)8) break;
|
||||||
|
if(temp_string_size < (size_t)2) break;
|
||||||
|
|
||||||
|
// Check for forbidden characters
|
||||||
|
const char* name_ptr = furi_string_get_cstr(str);
|
||||||
|
bool chars_check_failed = false;
|
||||||
|
|
||||||
|
for(; *name_ptr; ++name_ptr) {
|
||||||
|
const char c = *name_ptr;
|
||||||
|
if((c < '0' || c > '9') && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
|
||||||
|
chars_check_failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(chars_check_failed) break;
|
||||||
|
|
||||||
|
// If all checks was good we can set the name
|
||||||
|
version_set_custom_name(NULL, strdup(furi_string_get_cstr(str)));
|
||||||
|
furi_hal_version_set_name(version_get_custom_name(NULL));
|
||||||
|
|
||||||
|
res = true;
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
flipper_format_free(file);
|
||||||
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
furi_string_free(str);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
18
lib/toolbox/namechanger.h
Normal file
18
lib/toolbox/namechanger.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define NAMECHANGER_HEADER "Flipper Name File"
|
||||||
|
#define NAMECHANGER_VERSION 1
|
||||||
|
#define NAMECHANGER_PATH EXT_PATH("dolphin/name.settings")
|
||||||
|
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initializes the name changer. (Load name file, apply changes)
|
||||||
|
bool NameChanger_Init();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -24,18 +24,14 @@ struct Version {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* version of current running firmware (bootloader/flipper) */
|
/* version of current running firmware (bootloader/flipper) */
|
||||||
static const Version version = {
|
static Version version = {
|
||||||
.magic = VERSION_MAGIC,
|
.magic = VERSION_MAGIC,
|
||||||
.major = VERSION_MAJOR,
|
.major = VERSION_MAJOR,
|
||||||
.minor = VERSION_MINOR,
|
.minor = VERSION_MINOR,
|
||||||
.git_hash = GIT_COMMIT,
|
.git_hash = GIT_COMMIT,
|
||||||
.git_branch = GIT_BRANCH,
|
.git_branch = GIT_BRANCH,
|
||||||
.build_date = BUILD_DATE,
|
.build_date = BUILD_DATE,
|
||||||
#ifdef FURI_CUSTOM_FLIPPER_NAME
|
|
||||||
.custom_flipper_name = FURI_CUSTOM_FLIPPER_NAME,
|
|
||||||
#else
|
|
||||||
.custom_flipper_name = NULL,
|
.custom_flipper_name = NULL,
|
||||||
#endif
|
|
||||||
.version = VERSION
|
.version = VERSION
|
||||||
#ifdef FURI_RAM_EXEC
|
#ifdef FURI_RAM_EXEC
|
||||||
" (RAM)"
|
" (RAM)"
|
||||||
|
@ -74,6 +70,12 @@ const char* version_get_custom_name(const Version* v) {
|
||||||
return v ? v->custom_flipper_name : version.custom_flipper_name;
|
return v ? v->custom_flipper_name : version.custom_flipper_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void version_set_custom_name(Version* v, const char* name) {
|
||||||
|
Version* ver = v ? v : &version;
|
||||||
|
ver->custom_flipper_name = name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t version_get_target(const Version* v) {
|
uint8_t version_get_target(const Version* v) {
|
||||||
return v ? v->target : version.target;
|
return v ? v->target : version.target;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ const char* version_get_builddate(const Version* v);
|
||||||
*/
|
*/
|
||||||
const char* version_get_version(const Version* v);
|
const char* version_get_version(const Version* v);
|
||||||
|
|
||||||
/** Get custom flipper name if set in ENV
|
/** Get custom flipper name if set in version_set_custom_name
|
||||||
*
|
*
|
||||||
* @param v pointer to Version data. NULL for currently running
|
* @param v pointer to Version data. NULL for currently running
|
||||||
* software.
|
* software.
|
||||||
|
@ -74,6 +74,14 @@ const char* version_get_version(const Version* v);
|
||||||
*/
|
*/
|
||||||
const char* version_get_custom_name(const Version* v);
|
const char* version_get_custom_name(const Version* v);
|
||||||
|
|
||||||
|
/** Set custom flipper name
|
||||||
|
*
|
||||||
|
* @param v pointer to Version data. NULL for currently running
|
||||||
|
* software.
|
||||||
|
* @param name Custom name or NULL
|
||||||
|
*/
|
||||||
|
void version_set_custom_name(Version* v, const char* name);
|
||||||
|
|
||||||
/** Get hardware target this firmware was built for
|
/** Get hardware target this firmware was built for
|
||||||
*
|
*
|
||||||
* @param v pointer to Version data. NULL for currently running
|
* @param v pointer to Version data. NULL for currently running
|
||||||
|
|
|
@ -250,13 +250,6 @@ class Main(App):
|
||||||
)
|
)
|
||||||
bundle_args.extend(self.other_args)
|
bundle_args.extend(self.other_args)
|
||||||
|
|
||||||
log_custom_fz_name = (
|
|
||||||
environ.get("CUSTOM_FLIPPER_NAME", None)
|
|
||||||
or ""
|
|
||||||
)
|
|
||||||
if (log_custom_fz_name != "") and (len(log_custom_fz_name) <= 8) and (log_custom_fz_name.isalnum()) and (log_custom_fz_name.isascii()):
|
|
||||||
self.logger.info(f"Flipper Custom Name is set:\n\tName: {log_custom_fz_name} : length - {len(log_custom_fz_name)} chars")
|
|
||||||
|
|
||||||
if (bundle_result := UpdateMain(no_exit=True)(bundle_args)) == 0:
|
if (bundle_result := UpdateMain(no_exit=True)(bundle_args)) == 0:
|
||||||
self.note_dist_component("update", "dir", bundle_dir)
|
self.note_dist_component("update", "dir", bundle_dir)
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
|
|
|
@ -40,11 +40,6 @@ class GitVersion:
|
||||||
or "unknown"
|
or "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
custom_fz_name = (
|
|
||||||
os.environ.get("CUSTOM_FLIPPER_NAME", None)
|
|
||||||
or ""
|
|
||||||
)
|
|
||||||
|
|
||||||
force_no_dirty = (
|
force_no_dirty = (
|
||||||
os.environ.get("FORCE_NO_DIRTY", None)
|
os.environ.get("FORCE_NO_DIRTY", None)
|
||||||
or ""
|
or ""
|
||||||
|
@ -52,15 +47,6 @@ class GitVersion:
|
||||||
if (force_no_dirty != ""):
|
if (force_no_dirty != ""):
|
||||||
dirty = False
|
dirty = False
|
||||||
|
|
||||||
if (custom_fz_name != "") and (len(custom_fz_name) <= 8) and (custom_fz_name.isalnum()) and (custom_fz_name.isascii()):
|
|
||||||
return {
|
|
||||||
"GIT_COMMIT": commit,
|
|
||||||
"GIT_BRANCH": branch,
|
|
||||||
"FURI_CUSTOM_FLIPPER_NAME": custom_fz_name,
|
|
||||||
"VERSION": version,
|
|
||||||
"BUILD_DIRTY": dirty and 1 or 0,
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return {
|
return {
|
||||||
"GIT_COMMIT": commit,
|
"GIT_COMMIT": commit,
|
||||||
"GIT_BRANCH": branch,
|
"GIT_BRANCH": branch,
|
||||||
|
|
|
@ -100,11 +100,6 @@ vars.AddVariables(
|
||||||
"Version string for updater package",
|
"Version string for updater package",
|
||||||
"${DIST_SUFFIX}",
|
"${DIST_SUFFIX}",
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"CUSTOM_FLIPPER_NAME",
|
|
||||||
"Replaces OTP flipper name with custom string of 8 chars",
|
|
||||||
"",
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"FORCE_NO_DIRTY",
|
"FORCE_NO_DIRTY",
|
||||||
"Force disable dirty status of the build",
|
"Force disable dirty status of the build",
|
||||||
|
|
|
@ -20,7 +20,6 @@ variables_to_forward = [
|
||||||
# CI/CD variables
|
# CI/CD variables
|
||||||
"WORKFLOW_BRANCH_OR_TAG",
|
"WORKFLOW_BRANCH_OR_TAG",
|
||||||
"DIST_SUFFIX",
|
"DIST_SUFFIX",
|
||||||
"CUSTOM_FLIPPER_NAME",
|
|
||||||
"FORCE_NO_DIRTY",
|
"FORCE_NO_DIRTY",
|
||||||
# Python & other tools
|
# Python & other tools
|
||||||
"HOME",
|
"HOME",
|
||||||
|
|
Loading…
Reference in a new issue