diff --git a/applications/services/bt/bt_service/bt_keys_storage.c b/applications/services/bt/bt_service/bt_keys_storage.c index 215f19a89cb..cf06d663ba0 100644 --- a/applications/services/bt/bt_service/bt_keys_storage.c +++ b/applications/services/bt/bt_service/bt_keys_storage.c @@ -72,16 +72,19 @@ bool bt_keys_storage_load(BtKeysStorage* instance) { bool loaded = false; do { // Get payload size + uint8_t magic = 0, version = 0; size_t payload_size = 0; - if(!saved_struct_get_payload_size( - furi_string_get_cstr(instance->file_path), - BT_KEYS_STORAGE_MAGIC, - BT_KEYS_STORAGE_VERSION, - &payload_size)) { + if(!saved_struct_get_metadata( + furi_string_get_cstr(instance->file_path), &magic, &version, &payload_size)) { FURI_LOG_E(TAG, "Failed to read payload size"); break; } + if(magic != BT_KEYS_STORAGE_MAGIC || version != BT_KEYS_STORAGE_VERSION) { + FURI_LOG_E(TAG, "Saved data version is mismatched"); + break; + } + if(payload_size > instance->nvm_sram_buff_size) { FURI_LOG_E(TAG, "Saved data doesn't fit ram buffer"); break; diff --git a/applications/services/bt/bt_settings.c b/applications/services/bt/bt_settings.c index 1eaf6c7d70b..8a505f9e3f6 100644 --- a/applications/services/bt/bt_settings.c +++ b/applications/services/bt/bt_settings.c @@ -15,7 +15,7 @@ bool bt_settings_load(BtSettings* bt_settings) { BT_SETTINGS_PATH, bt_settings, sizeof(BtSettings), BT_SETTINGS_MAGIC, BT_SETTINGS_VERSION); } -bool bt_settings_save(BtSettings* bt_settings) { +bool bt_settings_save(const BtSettings* bt_settings) { furi_assert(bt_settings); return saved_struct_save( diff --git a/applications/services/bt/bt_settings.h b/applications/services/bt/bt_settings.h index 9ed8be89c4a..da43e149879 100644 --- a/applications/services/bt/bt_settings.h +++ b/applications/services/bt/bt_settings.h @@ -15,7 +15,7 @@ typedef struct { bool bt_settings_load(BtSettings* bt_settings); -bool bt_settings_save(BtSettings* bt_settings); +bool bt_settings_save(const BtSettings* bt_settings); #ifdef __cplusplus } diff --git a/applications/services/expansion/expansion_settings.c b/applications/services/expansion/expansion_settings.c index 586bf6e9cf8..691c454a57a 100644 --- a/applications/services/expansion/expansion_settings.c +++ b/applications/services/expansion/expansion_settings.c @@ -19,7 +19,7 @@ bool expansion_settings_load(ExpansionSettings* settings) { EXPANSION_SETTINGS_VERSION); } -bool expansion_settings_save(ExpansionSettings* settings) { +bool expansion_settings_save(const ExpansionSettings* settings) { furi_assert(settings); return saved_struct_save( EXPANSION_SETTINGS_PATH, diff --git a/applications/services/expansion/expansion_settings.h b/applications/services/expansion/expansion_settings.h index e7663f1b957..38e9f8d0258 100644 --- a/applications/services/expansion/expansion_settings.h +++ b/applications/services/expansion/expansion_settings.h @@ -36,7 +36,7 @@ bool expansion_settings_load(ExpansionSettings* settings); * @param[in] settings pointer to an ExpansionSettings instance to save settings from. * @returns true if the settings were successfully saved, false otherwise. */ -bool expansion_settings_save(ExpansionSettings* settings); +bool expansion_settings_save(const ExpansionSettings* settings); #ifdef __cplusplus } diff --git a/lib/toolbox/saved_struct.c b/lib/toolbox/saved_struct.c index e96d5b6cbf5..db7e4de6e41 100644 --- a/lib/toolbox/saved_struct.c +++ b/lib/toolbox/saved_struct.c @@ -13,7 +13,12 @@ typedef struct { uint32_t timestamp; } SavedStructHeader; -bool saved_struct_save(const char* path, void* data, size_t size, uint8_t magic, uint8_t version) { +bool saved_struct_save( + const char* path, + const void* data, + size_t size, + uint8_t magic, + uint8_t version) { furi_check(path); furi_check(data); furi_check(size); @@ -35,7 +40,7 @@ bool saved_struct_save(const char* path, void* data, size_t size, uint8_t magic, if(result) { // Calculate checksum uint8_t checksum = 0; - uint8_t* source = data; + const uint8_t* source = data; for(size_t i = 0; i < size; i++) { checksum += source[i]; } @@ -63,6 +68,10 @@ bool saved_struct_save(const char* path, void* data, size_t size, uint8_t magic, } bool saved_struct_load(const char* path, void* data, size_t size, uint8_t magic, uint8_t version) { + furi_check(path); + furi_check(data); + furi_check(size); + FURI_LOG_I(TAG, "Loading \"%s\"", path); SavedStructHeader header; @@ -126,13 +135,12 @@ bool saved_struct_load(const char* path, void* data, size_t size, uint8_t magic, return result; } -bool saved_struct_get_payload_size( +bool saved_struct_get_metadata( const char* path, - uint8_t magic, - uint8_t version, + uint8_t* magic, + uint8_t* version, size_t* payload_size) { furi_check(path); - furi_check(payload_size); SavedStructHeader header; Storage* storage = furi_record_open(RECORD_STORAGE); @@ -146,26 +154,22 @@ bool saved_struct_get_payload_size( break; } - size_t bytes_count = storage_file_read(file, &header, sizeof(SavedStructHeader)); - if(bytes_count != sizeof(SavedStructHeader)) { + if(storage_file_read(file, &header, sizeof(SavedStructHeader)) != + sizeof(SavedStructHeader)) { FURI_LOG_E(TAG, "Failed to read header"); break; } - if((header.magic != magic) || (header.version != version)) { - FURI_LOG_E( - TAG, - "Magic(%d != %d) or Version(%d != %d) mismatch of file \"%s\"", - header.magic, - magic, - header.version, - version, - path); - break; + if(magic) { + *magic = header.magic; + } + if(version) { + *version = header.version; + } + if(payload_size) { + uint64_t file_size = storage_file_size(file); + *payload_size = file_size - sizeof(SavedStructHeader); } - - uint64_t file_size = storage_file_size(file); - *payload_size = file_size - sizeof(SavedStructHeader); result = true; } while(false); diff --git a/lib/toolbox/saved_struct.h b/lib/toolbox/saved_struct.h index 9ce836564be..5ce53d3cdfb 100644 --- a/lib/toolbox/saved_struct.h +++ b/lib/toolbox/saved_struct.h @@ -1,3 +1,8 @@ +/** + * @file saved_struct.h + * @brief SavedStruct - data serialization/de-serialization + * + */ #pragma once #include @@ -8,14 +13,50 @@ extern "C" { #endif +/** Load data from the file in saved structure format + * + * @param[in] path The path to the file + * @param[out] data Pointer to the memory where to load data + * @param[in] size The size of the data + * @param[in] magic The magic to embed into metadata + * @param[in] version The version to embed into metadata + * + * @return true on success, false otherwise + */ bool saved_struct_load(const char* path, void* data, size_t size, uint8_t magic, uint8_t version); -bool saved_struct_save(const char* path, void* data, size_t size, uint8_t magic, uint8_t version); - -bool saved_struct_get_payload_size( +/** Save data in saved structure format + * + * @param[in] path The path to the file + * @param[in] data Pointer to the memory where data + * @param[in] size The size of the data + * @param[in] magic The magic to embed into metadata + * @param[in] version The version to embed into metadata + * + * @return true on success, false otherwise + */ +bool saved_struct_save( const char* path, + const void* data, + size_t size, uint8_t magic, - uint8_t version, + uint8_t version); + +/** Get SavedStructure file metadata + * + * @param[in] path The path to the file + * @param[out] magic Pointer to store magic or NULL if you don't need it + * @param[out] version Pointer to store version or NULL if you don't need + * it + * @param[out] payload_size Pointer to store payload size or NULL if you don't + * need it + * + * @return true on success, false otherwise + */ +bool saved_struct_get_metadata( + const char* path, + uint8_t* magic, + uint8_t* version, size_t* payload_size); #ifdef __cplusplus diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 95879cde6ff..7a813670596 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -2303,9 +2303,9 @@ Function,+,rpc_system_app_set_callback,void,"RpcAppSystem*, RpcAppSystemCallback Function,+,rpc_system_app_set_error_code,void,"RpcAppSystem*, uint32_t" Function,+,rpc_system_app_set_error_text,void,"RpcAppSystem*, const char*" Function,-,rpmatch,int,const char* -Function,+,saved_struct_get_payload_size,_Bool,"const char*, uint8_t, uint8_t, size_t*" +Function,+,saved_struct_get_metadata,_Bool,"const char*, uint8_t*, uint8_t*, size_t*" Function,+,saved_struct_load,_Bool,"const char*, void*, size_t, uint8_t, uint8_t" -Function,+,saved_struct_save,_Bool,"const char*, void*, size_t, uint8_t, uint8_t" +Function,+,saved_struct_save,_Bool,"const char*, const void*, size_t, uint8_t, uint8_t" Function,-,scalbln,double,"double, long int" Function,-,scalblnf,float,"float, long int" Function,-,scalblnl,long double,"long double, long" diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index e0b7f681831..bfc0507995a 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2866,9 +2866,9 @@ Function,+,rpc_system_app_set_callback,void,"RpcAppSystem*, RpcAppSystemCallback Function,+,rpc_system_app_set_error_code,void,"RpcAppSystem*, uint32_t" Function,+,rpc_system_app_set_error_text,void,"RpcAppSystem*, const char*" Function,-,rpmatch,int,const char* -Function,+,saved_struct_get_payload_size,_Bool,"const char*, uint8_t, uint8_t, size_t*" +Function,+,saved_struct_get_metadata,_Bool,"const char*, uint8_t*, uint8_t*, size_t*" Function,+,saved_struct_load,_Bool,"const char*, void*, size_t, uint8_t, uint8_t" -Function,+,saved_struct_save,_Bool,"const char*, void*, size_t, uint8_t, uint8_t" +Function,+,saved_struct_save,_Bool,"const char*, const void*, size_t, uint8_t, uint8_t" Function,-,scalbln,double,"double, long int" Function,-,scalblnf,float,"float, long int" Function,-,scalblnl,long double,"long double, long"