lets try these

This commit is contained in:
RogueMaster
2022-09-17 06:06:17 -04:00
parent aeeb33c22b
commit 0ff741f7b3
10 changed files with 220 additions and 110 deletions

View File

@@ -47,7 +47,6 @@ typedef enum {
SubGhzLoadKeyStateUnknown,
SubGhzLoadKeyStateOK,
SubGhzLoadKeyStateParseErr,
SubGhzLoadKeyStateOnlyRx,
} SubGhzLoadKeyState;
/** SubGhzLock */
@@ -85,4 +84,4 @@ typedef struct SubGhzPresetDefinition SubGhzPresetDefinition;
typedef enum {
SubGhzViewReceiverModeLive,
SubGhzViewReceiverModeFile,
} SubGhzViewReceiverMode;
} SubGhzViewReceiverMode;

View File

@@ -1,6 +1,5 @@
#include "../subghz_i.h"
#include "../views/receiver.h"
#include <lib/subghz/protocols/raw.h>
#include <lib/subghz/subghz_file_encoder_worker.h>
@@ -112,7 +111,7 @@ bool subghz_scene_decode_raw_start(SubGhz* subghz) {
} while(false);
if(success) {
//FURI_LOG_I(TAG, "Listening at \033[0;33m%s\033[0m.", string_get_cstr(file_name));
FURI_LOG_I(TAG, "Listening at \033[0;33m%s\033[0m.", string_get_cstr(file_name));
file_worker_encoder = subghz_file_encoder_worker_alloc();
if(subghz_file_encoder_worker_start(file_worker_encoder, string_get_cstr(file_name))) {
@@ -175,13 +174,6 @@ void subghz_scene_decode_raw_on_enter(void* context) {
subghz_receiver_set_rx_callback(
subghz->txrx->receiver, subghz_scene_add_to_history_callback, subghz);
// make sure we're not in auto-detect mode, which is only meant for the Read app
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
false);
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
if(decode_raw_state == SubGhzDecodeRawStateStart) {
//Decode RAW to history
subghz_history_reset(subghz->txrx->history);
@@ -238,7 +230,7 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) {
consumed = true;
break;
case SubGhzCustomEventViewReceiverConfig:
FURI_LOG_W(TAG, "No config options");
FURI_LOG_I(TAG, "No config options");
consumed = true;
break;
case SubGhzCustomEventViewReceiverOffDisplay:
@@ -258,7 +250,7 @@ bool subghz_scene_decode_raw_on_event(void* context, SceneManagerEvent event) {
notification_message(subghz->notifications, &sequence_blink_cyan_10);
break;
case SubGhzNotificationStateRxDone:
notification_message(subghz->notifications, &subghz_sequence_rx);
notification_message(subghz->notifications, &subghs_sequence_rx);
subghz->state_notifications = SubGhzNotificationStateRx;
break;
default:

View File

@@ -3,8 +3,9 @@
#include <dolphin/dolphin.h>
#include <lib/subghz/protocols/raw.h>
#include <lib/toolbox/path.h>
#include <stm32wbxx_ll_rtc.h>
#define RAW_FILE_NAME "RAW_"
#define RAW_FILE_NAME "R_"
#define TAG "SubGhzSceneReadRAW"
bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
@@ -114,10 +115,8 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
switch(event.event) {
case SubGhzCustomEventViewReadRAWBack:
// Check if return from config save values
if(subghz->current_scene == SubGhzSceneReceiverConfig) {
//FURI_LOG_I(TAG, "Raw value: %d", subghz->last_setting->detect_raw);
subghz_last_setting_save(
subghz->last_setting, EXT_PATH("subghz/assets/last_used.txt"));
if (subghz->current_scene == SubGhzSceneReceiverConfig) {
subghz_last_setting_save(subghz->last_setting, EXT_PATH("subghz/assets/last_used.txt"));
}
//Stop TX
if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
@@ -182,7 +181,6 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerSet);
subghz->current_scene = SubGhzSceneReceiverConfig;
//FURI_LOG_I(TAG, "Raw value: %d", subghz->last_setting->detect_raw);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig);
consumed = true;
break;
@@ -265,8 +263,28 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
string_t temp_str;
string_init(temp_str);
uint32_t time = LL_RTC_TIME_Get(RTC); // 0x00HHMMSS
uint32_t date = LL_RTC_DATE_Get(RTC); // 0xWWDDMMYY
char strings[1][25];
snprintf(
strings[0],
sizeof(strings[0]),
"%s%.4d%.2d%.2d%.2d%.2d",
"R",
__LL_RTC_CONVERT_BCD2BIN((date >> 0) & 0xFF) + 2000 // YEAR
,
__LL_RTC_CONVERT_BCD2BIN((date >> 8) & 0xFF) // MONTH
,
__LL_RTC_CONVERT_BCD2BIN((date >> 16) & 0xFF) // DAY
,
__LL_RTC_CONVERT_BCD2BIN((time >> 16) & 0xFF) // HOUR
,
__LL_RTC_CONVERT_BCD2BIN((time >> 8) & 0xFF) // DAY
);
string_printf(
temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION);
temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, strings[0], SUBGHZ_APP_EXTENSION);
subghz_protocol_raw_gen_fff_data(subghz->txrx->fff_data, string_get_cstr(temp_str));
string_clear(temp_str);
@@ -287,10 +305,28 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
subghz->current_scene = SubGhzSceneNeedSaving;
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving);
} else {
uint32_t time = LL_RTC_TIME_Get(RTC); // 0x00HHMMSS
uint32_t date = LL_RTC_DATE_Get(RTC); // 0xWWDDMMYY
char strings[1][25];
snprintf(
strings[0],
sizeof(strings[0]),
"%s%.4d%.2d%.2d%.2d%.2d",
"R",
__LL_RTC_CONVERT_BCD2BIN((date >> 0) & 0xFF) + 2000 // YEAR
,
__LL_RTC_CONVERT_BCD2BIN((date >> 8) & 0xFF) // MONTH
,
__LL_RTC_CONVERT_BCD2BIN((date >> 16) & 0xFF) // DAY
,
__LL_RTC_CONVERT_BCD2BIN((time >> 16) & 0xFF) // HOUR
,
__LL_RTC_CONVERT_BCD2BIN((time >> 8) & 0xFF) // DAY
);
//subghz_get_preset_name(subghz, subghz->error_str);
if(subghz_protocol_raw_save_to_file_init(
(SubGhzProtocolDecoderRAW*)subghz->txrx->decoder_result,
RAW_FILE_NAME,
strings[0],
subghz->txrx->preset)) {
DOLPHIN_DEED(DolphinDeedSubGhzRawRec);
if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
@@ -360,4 +396,4 @@ void subghz_scene_read_raw_on_exit(void* context) {
//filter restoration
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
}
}

View File

@@ -1,9 +1,7 @@
#include "../subghz_i.h"
#include "../views/receiver.h"
#define TAG "SubGhzSceneReceiver"
const NotificationSequence subghz_sequence_rx = {
const NotificationSequence subghs_sequence_rx = {
&message_green_255,
&message_vibro_on,
@@ -16,7 +14,7 @@ const NotificationSequence subghz_sequence_rx = {
NULL,
};
const NotificationSequence subghz_sequence_rx_locked = {
const NotificationSequence subghs_sequence_rx_locked = {
&message_green_255,
&message_display_backlight_on,
@@ -100,8 +98,6 @@ static void subghz_scene_add_to_history_callback(
void subghz_scene_receiver_on_enter(void* context) {
SubGhz* subghz = context;
subghz_last_setting_set_receiver_values(subghz->last_setting, subghz->txrx->receiver);
string_t str_buff;
string_init(str_buff);
@@ -140,11 +136,9 @@ void subghz_scene_receiver_on_enter(void* context) {
subghz->state_notifications = SubGhzNotificationStateRx;
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
}
};
if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) ||
(subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) {
// Set values that can be reset after using DetectRAW Scene
subghz_last_setting_set_receiver_values(subghz->last_setting, subghz->txrx->receiver);
subghz_begin(
subghz,
subghz_setting_get_preset_data_by_name(
@@ -163,17 +157,15 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
switch(event.event) {
case SubGhzCustomEventViewReceiverBack:
// Check if return from config save values
if(subghz->current_scene == SubGhzSceneReceiverConfig) {
//FURI_LOG_I(TAG, "Raw value: %d", subghz->last_setting->detect_raw);
subghz_last_setting_save(
subghz->last_setting, EXT_PATH("subghz/assets/last_used.txt"));
if (subghz->current_scene == SubGhzSceneReceiverConfig) {
subghz_last_setting_save(subghz->last_setting, EXT_PATH("subghz/assets/last_used.txt"));
}
// Stop CC1101 Rx
subghz->state_notifications = SubGhzNotificationStateIDLE;
if(subghz->txrx->txrx_state == SubGhzTxRxStateRx) {
subghz_rx_end(subghz);
subghz_sleep(subghz);
}
};
subghz->txrx->hopper_state = SubGhzHopperStateOFF;
subghz->txrx->idx_menu_chosen = 0;
subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz);
@@ -207,10 +199,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
subghz->txrx->idx_menu_chosen =
subghz_view_receiver_get_idx_menu(subghz->subghz_receiver);
scene_manager_set_scene_state(
subghz->scene_manager, SubGhzViewIdReceiver, SubGhzCustomEventManagerSet);
subghz->current_scene = SubGhzSceneReceiverConfig;
//FURI_LOG_I(TAG, "Raw value: %d", subghz->last_setting->detect_raw);
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiverConfig);
consumed = true;
break;
@@ -236,9 +225,9 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
break;
case SubGhzNotificationStateRxDone:
if(subghz->lock != SubGhzLockOn) {
notification_message(subghz->notifications, &subghz_sequence_rx);
notification_message(subghz->notifications, &subghs_sequence_rx);
} else {
notification_message(subghz->notifications, &subghz_sequence_rx_locked);
notification_message(subghz->notifications, &subghs_sequence_rx_locked);
}
subghz->state_notifications = SubGhzNotificationStateRx;
break;
@@ -250,8 +239,5 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
}
void subghz_scene_receiver_on_exit(void* context) {
SubGhz* subghz = context;
//filter restoration
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
UNUSED(context);
}

View File

@@ -2,8 +2,6 @@
#include <lib/subghz/protocols/raw.h>
#define TAG "SubGhzSceneReceiverConfig"
enum SubGhzSettingIndex {
SubGhzSettingIndexFrequency,
SubGhzSettingIndexHopping,
@@ -229,8 +227,7 @@ static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item)
subghz_setting_get_frequency_default_index(subghz->setting));
}
subghz->txrx->hopper_state = hopping_value[index];
subghz->last_setting->hopping = hopping_value[index];
subghz->txrx->hopper_state = subghz->last_setting->hopping = hopping_value[index];
}
static void subghz_scene_receiver_config_var_list_enter_callback(void* context, uint32_t index) {
@@ -244,9 +241,6 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context,
void subghz_scene_receiver_config_on_enter(void* context) {
SubGhz* subghz = context;
subghz_last_setting_set_receiver_values(subghz->last_setting, subghz->txrx->receiver);
VariableItem* item;
uint8_t value_index;
@@ -270,6 +264,20 @@ void subghz_scene_receiver_config_on_enter(void* context) {
(subghz_setting_get_frequency(subghz->setting, value_index) % 1000000) / 10000);
variable_item_set_current_value_text(item, text_buf);
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
item = variable_item_list_add(
subghz->variable_item_list,
"Hopping:",
HOPPING_COUNT,
subghz_scene_receiver_config_set_hopping_running,
subghz);
value_index = subghz_scene_receiver_config_hopper_value_index(
subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, hopping_text[value_index]);
}
item = variable_item_list_add(
subghz->variable_item_list,
"Modulation:",
@@ -284,17 +292,6 @@ void subghz_scene_receiver_config_on_enter(void* context) {
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
item = variable_item_list_add(
subghz->variable_item_list,
"Hopping:",
HOPPING_COUNT,
subghz_scene_receiver_config_set_hopping_running,
subghz);
value_index = subghz_scene_receiver_config_hopper_value_index(
subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, hopping_text[value_index]);
item = variable_item_list_add(
subghz->variable_item_list,
"Detect Raw:",
@@ -307,7 +304,10 @@ void subghz_scene_receiver_config_on_enter(void* context) {
DETECT_RAW_COUNT);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, detect_raw_text[value_index]);
}
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
item = variable_item_list_add(
subghz->variable_item_list,
"RSSI for Raw:",
@@ -321,7 +321,10 @@ void subghz_scene_receiver_config_on_enter(void* context) {
RSSI_THRESHOLD_COUNT);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, rssi_threshold_text[value_index]);
}
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
variable_item_list_add(subghz->variable_item_list, "Lock Keyboard", 1, NULL, NULL);
variable_item_list_set_enter_callback(
subghz->variable_item_list,

View File

@@ -14,6 +14,10 @@ void subghz_scene_show_only_rx_on_enter(void* context) {
const char* header_text = "Transmission is blocked";
const char* message_text = "This frequency is\noutside of default\nrange";
if(!furi_hal_region_is_provisioned()) {
header_text = "Firmware update needed";
message_text = "Please update\nfirmware before\nusing this feature\nflipp.dev/upd";
}
popup_set_header(popup, header_text, 63, 3, AlignCenter, AlignTop);
popup_set_text(popup, message_text, 0, 17, AlignLeft, AlignTop);

View File

@@ -207,7 +207,7 @@ SubGhz* subghz_alloc() {
subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment);
// Setup values
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
subghz_last_setting_set_receiver_values(subghz->last_setting, subghz->txrx->receiver);
subghz_worker_set_overrun_callback(
subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
@@ -331,6 +331,12 @@ void subghz_free(SubGhz* subghz) {
int32_t subghz_app(void* p) {
SubGhz* subghz = subghz_alloc();
if(!furi_hal_region_is_provisioned()) {
subghz_dialog_message_show_only_rx(subghz);
subghz_free(subghz);
return 1;
}
//Load database
bool load_database = subghz_environment_load_keystore(
subghz->txrx->environment, EXT_PATH("subghz/assets/keeloq_mfcodes"));

View File

@@ -16,9 +16,14 @@
#include <notification/notification_messages.h>
#include <flipper_format/flipper_format_i.h>
#include <flipper.pb.h>
#include <pb_decode.h>
#define SUBGHZ_FREQUENCY_RANGE_STR \
"299999755...348000000 or 386999938...464000000 or 778999847...928000000"
#define SUBGHZ_REGION_FILENAME "/int/.region_data"
void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) {
UNUSED(context);
uint32_t frequency = 433920000;
@@ -537,7 +542,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) {
return;
}
}
if(!furi_hal_subghz_is_tx_allowed(frequency)) {
if(!furi_hal_region_is_frequency_allowed(frequency)) {
printf(
"In your settings, only reception on this frequency (%lu) is allowed,\r\n"
"the actual operation of the application is not possible\r\n ",
@@ -760,6 +765,46 @@ static void subghz_cli_command(Cli* cli, string_t args, void* context) {
string_clear(cmd);
}
static bool
subghz_on_system_start_istream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
File* file = istream->state;
uint16_t ret = storage_file_read(file, buf, count);
return (count == ret);
}
static bool subghz_on_system_start_istream_decode_band(
pb_istream_t* stream,
const pb_field_t* field,
void** arg) {
(void)field;
FuriHalRegion* region = *arg;
PB_Region_Band band = {0};
if(!pb_decode(stream, PB_Region_Band_fields, &band)) {
FURI_LOG_E("SubGhzOnStart", "PB Region band decode error: %s", PB_GET_ERROR(stream));
return false;
}
region->bands_count += 1;
region =
realloc(region, sizeof(FuriHalRegion) + sizeof(FuriHalRegionBand) * region->bands_count);
size_t pos = region->bands_count - 1;
region->bands[pos].start = band.start;
region->bands[pos].end = band.end;
region->bands[pos].power_limit = band.power_limit;
region->bands[pos].duty_cycle = band.duty_cycle;
*arg = region;
FURI_LOG_I(
"SubGhzOnStart",
"Add allowed band: start %dHz, stop %dHz, power_limit %ddBm, duty_cycle %d%%",
band.start,
band.end,
band.power_limit,
band.duty_cycle);
return true;
}
void subghz_on_system_start() {
#ifdef SRV_CLI
Cli* cli = furi_record_open(RECORD_CLI);
@@ -770,4 +815,52 @@ void subghz_on_system_start() {
#else
UNUSED(subghz_cli_command);
#endif
#ifdef SRV_STORAGE
Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);
FileInfo fileinfo = {0};
PB_Region pb_region = {0};
pb_region.bands.funcs.decode = subghz_on_system_start_istream_decode_band;
do {
if(storage_common_stat(storage, SUBGHZ_REGION_FILENAME, &fileinfo) != FSE_OK ||
fileinfo.size == 0) {
FURI_LOG_W("SubGhzOnStart", "Region data is missing or empty");
break;
}
if(!storage_file_open(file, SUBGHZ_REGION_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) {
FURI_LOG_E("SubGhzOnStart", "Unable to open region data");
break;
}
pb_istream_t istream = {
.callback = subghz_on_system_start_istream_read,
.state = file,
.errmsg = NULL,
.bytes_left = fileinfo.size,
};
pb_region.bands.arg = malloc(sizeof(FuriHalRegion));
if(!pb_decode(&istream, PB_Region_fields, &pb_region)) {
FURI_LOG_E("SubGhzOnStart", "Invalid region data");
free(pb_region.bands.arg);
break;
}
FuriHalRegion* region = pb_region.bands.arg;
memcpy(
region->country_code,
pb_region.country_code->bytes,
pb_region.country_code->size < 4 ? pb_region.country_code->size : 3);
furi_hal_region_set(region);
} while(0);
pb_release(PB_Region_fields, &pb_region);
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
#else
UNUSED(subghz_cli_command);
#endif
}

View File

@@ -1,7 +1,11 @@
#include "subghz_history.h"
#include <lib/subghz/receiver.h>
#include <lib/subghz/protocols/came.h>
#define SUBGHZ_HISTORY_MAX 65
#include <furi.h>
#include <m-string.h>
#define SUBGHZ_HISTORY_MAX 99
#define TAG "SubGhzHistory"
typedef struct {
@@ -37,9 +41,15 @@ SubGhzHistory* subghz_history_alloc(void) {
void subghz_history_free(SubGhzHistory* instance) {
furi_assert(instance);
// Call method instead of code duplicate
subghz_history_reset(instance);
string_clear(instance->tmp_string);
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
string_clear(item->item_str);
string_clear(item->preset->name);
free(item->preset);
flipper_format_free(item->flipper_string);
item->type = 0;
}
SubGhzHistoryItemArray_clear(instance->history->data);
free(instance->history);
free(instance);
@@ -133,22 +143,16 @@ bool subghz_history_add_to_history(
furi_assert(instance);
furi_assert(context);
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) {
FURI_LOG_W(TAG, "Out of history slots!");
return false;
}
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false;
SubGhzProtocolDecoderBase* decoder_base = context;
if((instance->code_last_hash_data ==
subghz_protocol_decoder_base_get_hash_data(decoder_base)) &&
((furi_get_tick() - instance->last_update_timestamp) < 500)) {
//FURI_LOG_W(TAG, "Too short period for add");
instance->last_update_timestamp = furi_get_tick();
return false;
}
//FURI_LOG_I(TAG, "Add to history. Total: %d", instance->last_index_write + 1);
instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base);
instance->last_update_timestamp = furi_get_tick();

View File

@@ -3,41 +3,28 @@
#include <stdlib.h>
#include <stdbool.h>
#include <furi.h>
#include <stm32wbxx_ll_rtc.h>
void set_random_name(char* name, uint8_t max_name_size) {
static bool rand_generator_inited = false;
if(!rand_generator_inited) {
srand(DWT->CYCCNT);
rand_generator_inited = true;
}
const char* prefix[] = {
"super",
"big",
"little",
"liquid",
"unknown",
"thin",
"thick",
"great",
"my",
};
const char* suffix[] = {
"maslina",
"sus",
"anomalija",
"artefact",
"monolit",
"burer",
"sidorovich",
"habar",
};
// sus is not (sus)pect - this is about super sus
uint8_t prefix_i = rand() % COUNT_OF(prefix);
uint8_t suffix_i = rand() % COUNT_OF(suffix);
snprintf(name, max_name_size, "%s_%s", prefix[prefix_i], suffix[suffix_i]);
uint32_t time = LL_RTC_TIME_Get(RTC); // 0x00HHMMSS
uint32_t date = LL_RTC_DATE_Get(RTC); // 0xWWDDMMYY
char strings[1][25];
snprintf(
strings[0],
18,
"%s%.4d%.2d%.2d%.2d%.2d",
"s",
__LL_RTC_CONVERT_BCD2BIN((date >> 0) & 0xFF) + 2000 // YEAR
,
__LL_RTC_CONVERT_BCD2BIN((date >> 8) & 0xFF) // MONTH
,
__LL_RTC_CONVERT_BCD2BIN((date >> 16) & 0xFF) // DAY
,
__LL_RTC_CONVERT_BCD2BIN((time >> 16) & 0xFF) // HOUR
,
__LL_RTC_CONVERT_BCD2BIN((time >> 8) & 0xFF) // MIN
);
snprintf(name, max_name_size, "%s", strings[0]);
// Set first symbol to upper case
name[0] = name[0] - 0x20;
}
}