diff --git a/applications/services/application.fam b/applications/services/application.fam index a1a0429fa..1b69d2388 100644 --- a/applications/services/application.fam +++ b/applications/services/application.fam @@ -11,5 +11,6 @@ App( "desktop", "loader", "power", + "namechanger_srv", ], ) diff --git a/applications/services/namechanger/application.fam b/applications/services/namechanger/application.fam new file mode 100644 index 000000000..2edeb22df --- /dev/null +++ b/applications/services/namechanger/application.fam @@ -0,0 +1,8 @@ +App( + appid="namechanger_srv", + apptype=FlipperAppType.STARTUP, + entry_point="namechanger_on_system_start", + requires=["storage", "cli", "bt"], + conflicts=["updater"], + order=1300, +) diff --git a/applications/services/namechanger/namechanger.c b/applications/services/namechanger/namechanger.c new file mode 100644 index 000000000..6beef8d5e --- /dev/null +++ b/applications/services/namechanger/namechanger.c @@ -0,0 +1,110 @@ +#include "namechanger.h" +#include +#include +#include +#include +#include +#include + +#define TAG "NameChanger" + +static bool namechanger_init() { + Storage* storage = furi_record_open(RECORD_STORAGE); + + // Kostil + velosiped = top ficha + uint8_t timeout = 0; + while(timeout < 11) { + if(storage_sd_status(storage) == FSE_OK) break; + furi_delay_ms(250); + timeout++; + /*if(timeout == 10) { + // Failed to init namechanger, SD card not ready + furi_record_close(RECORD_STORAGE); + return false; + }*/ + } + + 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; +} + +int32_t namechanger_on_system_start(void* p) { + UNUSED(p); + if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { + return 0; + } + + // Wait for all required services to start and create their records + uint8_t timeout = 0; + while(!furi_record_exists(RECORD_CLI_VCP) || !furi_record_exists(RECORD_BT) || + !furi_record_exists(RECORD_STORAGE)) { + timeout++; + if(timeout > 250) { + return 0; + } + furi_delay_ms(5); + } + + // Hehe bad code now here, bad bad bad, very bad, bad example, dont take it, make it better + + if(namechanger_init()) { + CliVcp* cli = furi_record_open(RECORD_CLI_VCP); + cli_vcp_disable(cli); + furi_delay_ms(2); // why i added delays here + cli_vcp_enable(cli); + furi_record_close(RECORD_CLI_VCP); + + furi_delay_ms(3); + Bt* bt = furi_record_open(RECORD_BT); + if(!bt_profile_restore_default(bt)) { + //FURI_LOG_D(TAG, "Failed to touch bluetooth to name change"); + } + furi_record_close(RECORD_BT); + bt = NULL; + furi_delay_ms(3); + } + + return 0; +} diff --git a/applications/services/namechanger/namechanger.h b/applications/services/namechanger/namechanger.h new file mode 100644 index 000000000..5bd5bd8d9 --- /dev/null +++ b/applications/services/namechanger/namechanger.h @@ -0,0 +1,5 @@ +#pragma once + +#define NAMECHANGER_HEADER "Flipper Name File" +#define NAMECHANGER_VERSION 1 +#define NAMECHANGER_PATH EXT_PATH("dolphin/name.settings") diff --git a/applications/settings/desktop_settings/desktop_settings_app.c b/applications/settings/desktop_settings/desktop_settings_app.c index e8bc89957..6897880f5 100644 --- a/applications/settings/desktop_settings/desktop_settings_app.c +++ b/applications/settings/desktop_settings/desktop_settings_app.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/lib/toolbox/version.c b/lib/toolbox/version.c index 876695f07..41e22ce09 100644 --- a/lib/toolbox/version.c +++ b/lib/toolbox/version.c @@ -23,10 +23,11 @@ struct Version { // v 1.1 const char* firmware_origin; const char* git_origin; + const char* custom_flipper_name; }; /* version of current running firmware (bootloader/flipper) */ -static const Version version = { +static Version version = { .magic = VERSION_MAGIC, .major = VERSION_MAJOR, .minor = VERSION_MINOR, @@ -42,6 +43,7 @@ static const Version version = { .build_is_dirty = BUILD_DIRTY, .firmware_origin = FIRMWARE_ORIGIN, .git_origin = GIT_ORIGIN, + .custom_flipper_name = NULL, }; const Version* version_get(void) { @@ -69,6 +71,16 @@ const char* version_get_version(const Version* v) { return v ? v->version : version.version; } +const char* version_get_custom_name(const Version* v) { + 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) { return v ? v->target : version.target; } diff --git a/lib/toolbox/version.h b/lib/toolbox/version.h index 0c04e5c75..568260077 100644 --- a/lib/toolbox/version.h +++ b/lib/toolbox/version.h @@ -2,6 +2,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -64,6 +65,23 @@ const char* version_get_builddate(const Version* v); */ const char* version_get_version(const Version* v); +/** Get custom flipper name if set in version_set_custom_name + * + * @param v pointer to Version data. NULL for currently running + * software. + * + * @return custom name or NULL + */ +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 * * @param v pointer to Version data. NULL for currently running diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index d142a6374..2d62b02eb 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1759,6 +1759,7 @@ Function,+,furi_hal_version_get_ncc_id,const char*, Function,+,furi_hal_version_get_otp_version,FuriHalVersionOtpVersion, Function,+,furi_hal_version_get_srrc_id,const char*, 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_size,size_t, Function,-,furi_hal_vibro_init,void, @@ -3685,6 +3686,7 @@ Function,-,vdiprintf,int,"int, const char*, __gnuc_va_list" Function,-,vdprintf,int,"int, const char*, __gnuc_va_list" Function,+,version_get,const Version*, Function,+,version_get_builddate,const char*,const Version* +Function,+,version_get_custom_name,const char*,const Version* Function,+,version_get_dirty_flag,_Bool,const Version* Function,+,version_get_firmware_origin,const char*,const Version* Function,+,version_get_git_origin,const char*,const Version* @@ -3693,6 +3695,7 @@ Function,+,version_get_gitbranchnum,const char*,const Version* Function,+,version_get_githash,const char*,const Version* Function,+,version_get_target,uint8_t,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,-,vfiscanf,int,"FILE*, const char*, __gnuc_va_list" Function,-,vfprintf,int,"FILE*, const char*, __gnuc_va_list" diff --git a/targets/f7/furi_hal/furi_hal_version.c b/targets/f7/furi_hal/furi_hal_version.c index 2859ae362..b3b9dc222 100644 --- a/targets/f7/furi_hal/furi_hal_version.c +++ b/targets/f7/furi_hal/furi_hal_version.c @@ -90,7 +90,7 @@ typedef struct { 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) { strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); snprintf( diff --git a/targets/furi_hal_include/furi_hal_version.h b/targets/furi_hal_include/furi_hal_version.h index 8e00a7541..a9c794081 100644 --- a/targets/furi_hal_include/furi_hal_version.h +++ b/targets/furi_hal_include/furi_hal_version.h @@ -182,6 +182,10 @@ const char* furi_hal_version_get_device_name_ptr(void); */ const char* furi_hal_version_get_ble_local_device_name_ptr(void); +/** Set flipper name + */ +void furi_hal_version_set_name(const char* name); + /** Get BLE MAC address * * @return pointer to BLE MAC address