2023-02-07 16:33:05 +00:00
|
|
|
#include <furi_hal_light.h>
|
2021-05-24 13:44:14 +00:00
|
|
|
#include <furi.h>
|
2022-01-05 16:10:18 +00:00
|
|
|
#include <furi_hal.h>
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
#include <storage/storage.h>
|
2022-04-14 12:20:41 +00:00
|
|
|
#include <input/input.h>
|
2021-05-24 13:44:14 +00:00
|
|
|
#include "notification.h"
|
2022-01-05 16:10:18 +00:00
|
|
|
#include "notification_messages.h"
|
|
|
|
#include "notification_app.h"
|
2021-05-24 13:44:14 +00:00
|
|
|
|
2021-11-12 13:04:35 +00:00
|
|
|
#define TAG "NotificationSrv"
|
|
|
|
|
2021-05-24 13:44:14 +00:00
|
|
|
static const uint8_t minimal_delay = 100;
|
|
|
|
static const uint8_t led_off_values[NOTIFICATION_LED_COUNT] = {0x00, 0x00, 0x00};
|
|
|
|
|
|
|
|
static const uint8_t reset_red_mask = 1 << 0;
|
|
|
|
static const uint8_t reset_green_mask = 1 << 1;
|
|
|
|
static const uint8_t reset_blue_mask = 1 << 2;
|
|
|
|
static const uint8_t reset_vibro_mask = 1 << 3;
|
|
|
|
static const uint8_t reset_sound_mask = 1 << 4;
|
|
|
|
static const uint8_t reset_display_mask = 1 << 5;
|
2022-06-09 07:33:46 +00:00
|
|
|
static const uint8_t reset_blink_mask = 1 << 6;
|
2021-05-24 13:44:14 +00:00
|
|
|
|
2023-04-19 09:33:23 +00:00
|
|
|
void notification_vibro_on(bool force);
|
2021-05-24 13:44:14 +00:00
|
|
|
void notification_vibro_off();
|
2023-04-19 09:33:23 +00:00
|
|
|
void notification_sound_on(float freq, float volume, bool force);
|
2021-05-24 13:44:14 +00:00
|
|
|
void notification_sound_off();
|
|
|
|
|
|
|
|
uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value);
|
|
|
|
uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value);
|
|
|
|
uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app);
|
|
|
|
|
2021-07-04 22:03:56 +00:00
|
|
|
void notification_message_save_settings(NotificationApp* app) {
|
2022-07-20 10:56:33 +00:00
|
|
|
NotificationAppMessage m = {
|
|
|
|
.type = SaveSettingsMessage, .back_event = furi_event_flag_alloc()};
|
|
|
|
furi_check(furi_message_queue_put(app->queue, &m, FuriWaitForever) == FuriStatusOk);
|
|
|
|
furi_event_flag_wait(
|
|
|
|
m.back_event, NOTIFICATION_EVENT_COMPLETE, FuriFlagWaitAny, FuriWaitForever);
|
|
|
|
furi_event_flag_free(m.back_event);
|
2021-07-04 22:03:56 +00:00
|
|
|
};
|
|
|
|
|
2021-05-24 13:44:14 +00:00
|
|
|
// internal layer
|
|
|
|
void notification_apply_internal_led_layer(NotificationLedLayer* layer, uint8_t layer_value) {
|
|
|
|
furi_assert(layer);
|
|
|
|
furi_assert(layer->index < LayerMAX);
|
|
|
|
|
|
|
|
// set value
|
|
|
|
layer->value[LayerInternal] = layer_value;
|
|
|
|
|
|
|
|
// apply if current layer is internal
|
|
|
|
if(layer->index == LayerInternal) {
|
2021-08-08 18:03:25 +00:00
|
|
|
furi_hal_light_set(layer->light, layer->value[LayerInternal]);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool notification_is_any_led_layer_internal_and_not_empty(NotificationApp* app) {
|
|
|
|
bool result = false;
|
|
|
|
if((app->led[0].index == LayerInternal) || (app->led[1].index == LayerInternal) ||
|
|
|
|
(app->led[2].index == LayerInternal)) {
|
|
|
|
if((app->led[0].value[LayerInternal] != 0x00) ||
|
|
|
|
(app->led[1].value[LayerInternal] != 0x00) ||
|
|
|
|
(app->led[2].value[LayerInternal] != 0x00)) {
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// notification layer
|
|
|
|
void notification_apply_notification_led_layer(
|
|
|
|
NotificationLedLayer* layer,
|
|
|
|
const uint8_t layer_value) {
|
|
|
|
furi_assert(layer);
|
|
|
|
furi_assert(layer->index < LayerMAX);
|
|
|
|
|
|
|
|
// set value
|
|
|
|
layer->index = LayerNotification;
|
|
|
|
// set layer
|
|
|
|
layer->value[LayerNotification] = layer_value;
|
|
|
|
// apply
|
2021-08-08 18:03:25 +00:00
|
|
|
furi_hal_light_set(layer->light, layer->value[LayerNotification]);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void notification_reset_notification_led_layer(NotificationLedLayer* layer) {
|
|
|
|
furi_assert(layer);
|
|
|
|
furi_assert(layer->index < LayerMAX);
|
|
|
|
|
|
|
|
// set value
|
|
|
|
layer->value[LayerNotification] = 0;
|
|
|
|
// set layer
|
|
|
|
layer->index = LayerInternal;
|
|
|
|
|
|
|
|
// apply
|
2021-08-08 18:03:25 +00:00
|
|
|
furi_hal_light_set(layer->light, layer->value[LayerInternal]);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) {
|
2022-07-06 13:54:08 +00:00
|
|
|
if(reset_mask & reset_blink_mask) {
|
|
|
|
furi_hal_light_blink_stop();
|
|
|
|
}
|
2021-05-24 13:44:14 +00:00
|
|
|
if(reset_mask & reset_red_mask) {
|
|
|
|
notification_reset_notification_led_layer(&app->led[0]);
|
|
|
|
}
|
|
|
|
if(reset_mask & reset_green_mask) {
|
|
|
|
notification_reset_notification_led_layer(&app->led[1]);
|
|
|
|
}
|
|
|
|
if(reset_mask & reset_blue_mask) {
|
|
|
|
notification_reset_notification_led_layer(&app->led[2]);
|
|
|
|
}
|
|
|
|
if(reset_mask & reset_vibro_mask) {
|
|
|
|
notification_vibro_off();
|
|
|
|
}
|
|
|
|
if(reset_mask & reset_sound_mask) {
|
|
|
|
notification_sound_off();
|
|
|
|
}
|
|
|
|
if(reset_mask & reset_display_mask) {
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app));
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void notification_apply_notification_leds(NotificationApp* app, const uint8_t* values) {
|
|
|
|
for(uint8_t i = 0; i < NOTIFICATION_LED_COUNT; i++) {
|
|
|
|
notification_apply_notification_led_layer(
|
2021-07-04 22:03:56 +00:00
|
|
|
&app->led[i], notification_settings_get_rgb_led_brightness(app, values[i]));
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// settings
|
|
|
|
uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value) {
|
|
|
|
return (value * app->settings.display_brightness);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value) {
|
|
|
|
return (value * app->settings.led_brightness);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) {
|
2022-07-20 10:56:33 +00:00
|
|
|
return (
|
|
|
|
(float)(app->settings.display_off_delay_ms) /
|
|
|
|
(1000.0f / furi_kernel_get_tick_frequency()));
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// generics
|
2023-04-19 09:33:23 +00:00
|
|
|
void notification_vibro_on(bool force) {
|
|
|
|
if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) {
|
|
|
|
furi_hal_vibro_on(true);
|
|
|
|
}
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void notification_vibro_off() {
|
2021-08-08 18:03:25 +00:00
|
|
|
furi_hal_vibro_on(false);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
2023-04-19 09:33:23 +00:00
|
|
|
void notification_sound_on(float freq, float volume, bool force) {
|
|
|
|
if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) {
|
|
|
|
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
|
|
|
furi_hal_speaker_start(freq, volume);
|
|
|
|
}
|
2022-12-16 22:20:10 +00:00
|
|
|
}
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void notification_sound_off() {
|
2022-12-16 22:20:10 +00:00
|
|
|
if(furi_hal_speaker_is_mine()) {
|
|
|
|
furi_hal_speaker_stop();
|
|
|
|
furi_hal_speaker_release();
|
|
|
|
}
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// display timer
|
|
|
|
static void notification_display_timer(void* ctx) {
|
|
|
|
furi_assert(ctx);
|
|
|
|
NotificationApp* app = ctx;
|
2022-04-29 14:21:12 +00:00
|
|
|
notification_message(app, &sequence_display_backlight_off);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// message processing
|
|
|
|
void notification_process_notification_message(
|
|
|
|
NotificationApp* app,
|
|
|
|
NotificationAppMessage* message) {
|
|
|
|
uint32_t notification_message_index = 0;
|
2023-04-19 09:33:23 +00:00
|
|
|
bool force_volume = false;
|
|
|
|
bool force_vibro = false;
|
2021-05-24 13:44:14 +00:00
|
|
|
const NotificationMessage* notification_message;
|
|
|
|
notification_message = (*message->sequence)[notification_message_index];
|
|
|
|
|
|
|
|
bool led_active = false;
|
|
|
|
uint8_t led_values[NOTIFICATION_LED_COUNT] = {0x00, 0x00, 0x00};
|
|
|
|
bool reset_notifications = true;
|
2021-12-28 15:46:08 +00:00
|
|
|
float speaker_volume_setting = app->settings.speaker_volume;
|
|
|
|
bool vibro_setting = app->settings.vibro_on;
|
|
|
|
float display_brightness_setting = app->settings.display_brightness;
|
2021-05-24 13:44:14 +00:00
|
|
|
|
|
|
|
uint8_t reset_mask = 0;
|
|
|
|
|
|
|
|
while(notification_message != NULL) {
|
|
|
|
switch(notification_message->type) {
|
2022-04-29 14:21:12 +00:00
|
|
|
case NotificationMessageTypeLedDisplayBacklight:
|
2021-05-24 13:44:14 +00:00
|
|
|
// if on - switch on and start timer
|
|
|
|
// if off - switch off and stop timer
|
|
|
|
// on timer - switch off
|
|
|
|
if(notification_message->data.led.value > 0x00) {
|
|
|
|
notification_apply_notification_led_layer(
|
|
|
|
&app->display,
|
2021-12-28 15:46:08 +00:00
|
|
|
notification_message->data.led.value * display_brightness_setting);
|
2021-05-24 13:44:14 +00:00
|
|
|
} else {
|
|
|
|
notification_reset_notification_led_layer(&app->display);
|
2022-07-20 10:56:33 +00:00
|
|
|
if(furi_timer_is_running(app->display_timer)) {
|
|
|
|
furi_timer_stop(app->display_timer);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
reset_mask |= reset_display_mask;
|
|
|
|
break;
|
2022-04-29 14:21:12 +00:00
|
|
|
case NotificationMessageTypeLedDisplayBacklightEnforceOn:
|
2022-04-14 14:05:40 +00:00
|
|
|
furi_assert(app->display_led_lock < UINT8_MAX);
|
|
|
|
app->display_led_lock++;
|
|
|
|
if(app->display_led_lock == 1) {
|
2022-02-24 00:17:40 +00:00
|
|
|
notification_apply_internal_led_layer(
|
|
|
|
&app->display,
|
|
|
|
notification_message->data.led.value * display_brightness_setting);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-29 14:21:12 +00:00
|
|
|
case NotificationMessageTypeLedDisplayBacklightEnforceAuto:
|
2022-04-14 14:05:40 +00:00
|
|
|
furi_assert(app->display_led_lock > 0);
|
|
|
|
app->display_led_lock--;
|
|
|
|
if(app->display_led_lock == 0) {
|
2022-02-24 00:17:40 +00:00
|
|
|
notification_apply_internal_led_layer(
|
|
|
|
&app->display,
|
|
|
|
notification_message->data.led.value * display_brightness_setting);
|
|
|
|
}
|
|
|
|
break;
|
2021-05-24 13:44:14 +00:00
|
|
|
case NotificationMessageTypeLedRed:
|
|
|
|
// store and send on delay or after seq
|
|
|
|
led_active = true;
|
|
|
|
led_values[0] = notification_message->data.led.value;
|
2022-04-21 12:33:03 +00:00
|
|
|
app->led[0].value_last[LayerNotification] = led_values[0];
|
2021-05-24 13:44:14 +00:00
|
|
|
reset_mask |= reset_red_mask;
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedGreen:
|
|
|
|
// store and send on delay or after seq
|
|
|
|
led_active = true;
|
|
|
|
led_values[1] = notification_message->data.led.value;
|
2022-04-21 12:33:03 +00:00
|
|
|
app->led[1].value_last[LayerNotification] = led_values[1];
|
2021-05-24 13:44:14 +00:00
|
|
|
reset_mask |= reset_green_mask;
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedBlue:
|
|
|
|
// store and send on delay or after seq
|
|
|
|
led_active = true;
|
|
|
|
led_values[2] = notification_message->data.led.value;
|
2022-04-21 12:33:03 +00:00
|
|
|
app->led[2].value_last[LayerNotification] = led_values[2];
|
2021-05-24 13:44:14 +00:00
|
|
|
reset_mask |= reset_blue_mask;
|
|
|
|
break;
|
2022-06-09 07:33:46 +00:00
|
|
|
case NotificationMessageTypeLedBlinkStart:
|
|
|
|
// store and send on delay or after seq
|
|
|
|
led_active = true;
|
|
|
|
furi_hal_light_blink_start(
|
|
|
|
notification_message->data.led_blink.color,
|
|
|
|
app->settings.led_brightness * 255,
|
|
|
|
notification_message->data.led_blink.on_time,
|
|
|
|
notification_message->data.led_blink.period);
|
|
|
|
reset_mask |= reset_blink_mask;
|
2022-07-06 13:54:08 +00:00
|
|
|
reset_mask |= reset_red_mask;
|
|
|
|
reset_mask |= reset_green_mask;
|
|
|
|
reset_mask |= reset_blue_mask;
|
2022-06-09 07:33:46 +00:00
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedBlinkColor:
|
|
|
|
led_active = true;
|
|
|
|
furi_hal_light_blink_set_color(notification_message->data.led_blink.color);
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedBlinkStop:
|
|
|
|
furi_hal_light_blink_stop();
|
|
|
|
reset_mask &= ~reset_blink_mask;
|
2022-07-06 13:54:08 +00:00
|
|
|
reset_mask |= reset_red_mask;
|
|
|
|
reset_mask |= reset_green_mask;
|
|
|
|
reset_mask |= reset_blue_mask;
|
2022-06-09 07:33:46 +00:00
|
|
|
break;
|
2021-05-24 13:44:14 +00:00
|
|
|
case NotificationMessageTypeVibro:
|
|
|
|
if(notification_message->data.vibro.on) {
|
2023-04-19 09:33:23 +00:00
|
|
|
if(vibro_setting) notification_vibro_on(force_vibro);
|
2021-05-24 13:44:14 +00:00
|
|
|
} else {
|
|
|
|
notification_vibro_off();
|
|
|
|
}
|
|
|
|
reset_mask |= reset_vibro_mask;
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeSoundOn:
|
|
|
|
notification_sound_on(
|
2022-03-23 17:59:20 +00:00
|
|
|
notification_message->data.sound.frequency,
|
2023-04-19 09:33:23 +00:00
|
|
|
notification_message->data.sound.volume * speaker_volume_setting,
|
|
|
|
force_volume);
|
2021-05-24 13:44:14 +00:00
|
|
|
reset_mask |= reset_sound_mask;
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeSoundOff:
|
|
|
|
notification_sound_off();
|
|
|
|
reset_mask |= reset_sound_mask;
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeDelay:
|
|
|
|
if(led_active) {
|
|
|
|
if(notification_is_any_led_layer_internal_and_not_empty(app)) {
|
|
|
|
notification_apply_notification_leds(app, led_off_values);
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_delay_ms(minimal_delay);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
led_active = false;
|
|
|
|
|
|
|
|
notification_apply_notification_leds(app, led_values);
|
|
|
|
reset_mask |= reset_red_mask;
|
|
|
|
reset_mask |= reset_green_mask;
|
|
|
|
reset_mask |= reset_blue_mask;
|
|
|
|
}
|
|
|
|
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_delay_ms(notification_message->data.delay.length);
|
2021-05-24 13:44:14 +00:00
|
|
|
break;
|
|
|
|
case NotificationMessageTypeDoNotReset:
|
|
|
|
reset_notifications = false;
|
|
|
|
break;
|
2021-12-28 15:46:08 +00:00
|
|
|
case NotificationMessageTypeForceSpeakerVolumeSetting:
|
|
|
|
speaker_volume_setting = notification_message->data.forced_settings.speaker_volume;
|
2023-04-19 09:33:23 +00:00
|
|
|
force_volume = true;
|
2021-12-28 15:46:08 +00:00
|
|
|
break;
|
|
|
|
case NotificationMessageTypeForceVibroSetting:
|
|
|
|
vibro_setting = notification_message->data.forced_settings.vibro;
|
2023-04-19 09:33:23 +00:00
|
|
|
force_vibro = true;
|
2021-12-28 15:46:08 +00:00
|
|
|
break;
|
|
|
|
case NotificationMessageTypeForceDisplayBrightnessSetting:
|
|
|
|
display_brightness_setting =
|
|
|
|
notification_message->data.forced_settings.display_brightness;
|
2022-04-21 12:33:03 +00:00
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedBrightnessSettingApply:
|
|
|
|
led_active = true;
|
|
|
|
for(uint8_t i = 0; i < NOTIFICATION_LED_COUNT; i++) {
|
|
|
|
led_values[i] = app->led[i].value_last[LayerNotification];
|
|
|
|
}
|
|
|
|
reset_mask |= reset_red_mask;
|
|
|
|
reset_mask |= reset_green_mask;
|
|
|
|
reset_mask |= reset_blue_mask;
|
|
|
|
break;
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
notification_message_index++;
|
|
|
|
notification_message = (*message->sequence)[notification_message_index];
|
|
|
|
};
|
|
|
|
|
|
|
|
// send and do minimal delay
|
|
|
|
if(led_active) {
|
|
|
|
bool need_minimal_delay = false;
|
|
|
|
if(notification_is_any_led_layer_internal_and_not_empty(app)) {
|
|
|
|
need_minimal_delay = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
notification_apply_notification_leds(app, led_values);
|
|
|
|
reset_mask |= reset_red_mask;
|
|
|
|
reset_mask |= reset_green_mask;
|
|
|
|
reset_mask |= reset_blue_mask;
|
|
|
|
|
2022-07-06 13:54:08 +00:00
|
|
|
if((need_minimal_delay) && (reset_notifications)) {
|
2021-05-24 13:44:14 +00:00
|
|
|
notification_apply_notification_leds(app, led_off_values);
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_delay_ms(minimal_delay);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(reset_notifications) {
|
|
|
|
notification_reset_notification_layer(app, reset_mask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void notification_process_internal_message(NotificationApp* app, NotificationAppMessage* message) {
|
|
|
|
uint32_t notification_message_index = 0;
|
|
|
|
const NotificationMessage* notification_message;
|
|
|
|
notification_message = (*message->sequence)[notification_message_index];
|
|
|
|
|
|
|
|
while(notification_message != NULL) {
|
|
|
|
switch(notification_message->type) {
|
2022-04-29 14:21:12 +00:00
|
|
|
case NotificationMessageTypeLedDisplayBacklight:
|
2021-05-24 13:44:14 +00:00
|
|
|
notification_apply_internal_led_layer(
|
|
|
|
&app->display,
|
|
|
|
notification_settings_get_display_brightness(
|
|
|
|
app, notification_message->data.led.value));
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedRed:
|
2022-04-21 12:33:03 +00:00
|
|
|
app->led[0].value_last[LayerInternal] = notification_message->data.led.value;
|
2021-05-24 13:44:14 +00:00
|
|
|
notification_apply_internal_led_layer(
|
|
|
|
&app->led[0],
|
|
|
|
notification_settings_get_rgb_led_brightness(
|
|
|
|
app, notification_message->data.led.value));
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedGreen:
|
2022-04-21 12:33:03 +00:00
|
|
|
app->led[1].value_last[LayerInternal] = notification_message->data.led.value;
|
2021-05-24 13:44:14 +00:00
|
|
|
notification_apply_internal_led_layer(
|
|
|
|
&app->led[1],
|
|
|
|
notification_settings_get_rgb_led_brightness(
|
|
|
|
app, notification_message->data.led.value));
|
|
|
|
break;
|
|
|
|
case NotificationMessageTypeLedBlue:
|
2022-04-21 12:33:03 +00:00
|
|
|
app->led[2].value_last[LayerInternal] = notification_message->data.led.value;
|
2021-05-24 13:44:14 +00:00
|
|
|
notification_apply_internal_led_layer(
|
|
|
|
&app->led[2],
|
|
|
|
notification_settings_get_rgb_led_brightness(
|
|
|
|
app, notification_message->data.led.value));
|
|
|
|
break;
|
2022-04-21 12:33:03 +00:00
|
|
|
case NotificationMessageTypeLedBrightnessSettingApply:
|
|
|
|
for(uint8_t i = 0; i < NOTIFICATION_LED_COUNT; i++) {
|
|
|
|
uint8_t new_val = notification_settings_get_rgb_led_brightness(
|
|
|
|
app, app->led[i].value_last[LayerInternal]);
|
|
|
|
notification_apply_internal_led_layer(&app->led[i], new_val);
|
|
|
|
}
|
|
|
|
break;
|
2021-05-24 13:44:14 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
notification_message_index++;
|
|
|
|
notification_message = (*message->sequence)[notification_message_index];
|
|
|
|
}
|
2021-07-04 22:03:56 +00:00
|
|
|
}
|
|
|
|
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
static bool notification_load_settings(NotificationApp* app) {
|
2021-07-04 22:03:56 +00:00
|
|
|
NotificationSettings settings;
|
2022-07-26 12:21:51 +00:00
|
|
|
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
2021-07-04 22:03:56 +00:00
|
|
|
const size_t settings_size = sizeof(NotificationSettings);
|
|
|
|
|
2021-11-12 13:04:35 +00:00
|
|
|
FURI_LOG_I(TAG, "loading settings from \"%s\"", NOTIFICATION_SETTINGS_PATH);
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
bool fs_result =
|
|
|
|
storage_file_open(file, NOTIFICATION_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
2021-07-04 22:03:56 +00:00
|
|
|
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
if(fs_result) {
|
|
|
|
uint16_t bytes_count = storage_file_read(file, &settings, settings_size);
|
|
|
|
|
|
|
|
if(bytes_count != settings_size) {
|
|
|
|
fs_result = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(fs_result) {
|
2021-11-12 13:04:35 +00:00
|
|
|
FURI_LOG_I(TAG, "load success");
|
2021-07-04 22:03:56 +00:00
|
|
|
|
|
|
|
if(settings.version != NOTIFICATION_SETTINGS_VERSION) {
|
|
|
|
FURI_LOG_E(
|
2021-11-12 13:04:35 +00:00
|
|
|
TAG, "version(%d != %d) mismatch", settings.version, NOTIFICATION_SETTINGS_VERSION);
|
2021-07-04 22:03:56 +00:00
|
|
|
} else {
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_kernel_lock();
|
2021-07-04 22:03:56 +00:00
|
|
|
memcpy(&app->settings, &settings, settings_size);
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_kernel_unlock();
|
2021-07-04 22:03:56 +00:00
|
|
|
}
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
} else {
|
2021-11-12 13:04:35 +00:00
|
|
|
FURI_LOG_E(TAG, "load failed, %s", storage_file_get_error_desc(file));
|
2021-07-04 22:03:56 +00:00
|
|
|
}
|
|
|
|
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
storage_file_close(file);
|
|
|
|
storage_file_free(file);
|
2022-07-26 12:21:51 +00:00
|
|
|
furi_record_close(RECORD_STORAGE);
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
|
|
|
|
return fs_result;
|
2021-07-04 22:03:56 +00:00
|
|
|
};
|
|
|
|
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
static bool notification_save_settings(NotificationApp* app) {
|
|
|
|
NotificationSettings settings;
|
2022-07-26 12:21:51 +00:00
|
|
|
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
2021-07-04 22:03:56 +00:00
|
|
|
const size_t settings_size = sizeof(NotificationSettings);
|
2021-05-24 13:44:14 +00:00
|
|
|
|
2021-11-12 13:04:35 +00:00
|
|
|
FURI_LOG_I(TAG, "saving settings to \"%s\"", NOTIFICATION_SETTINGS_PATH);
|
2021-07-04 22:03:56 +00:00
|
|
|
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_kernel_lock();
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
memcpy(&settings, &app->settings, settings_size);
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_kernel_unlock();
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
|
|
|
|
bool fs_result =
|
|
|
|
storage_file_open(file, NOTIFICATION_SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS);
|
|
|
|
|
|
|
|
if(fs_result) {
|
|
|
|
uint16_t bytes_count = storage_file_write(file, &settings, settings_size);
|
|
|
|
|
|
|
|
if(bytes_count != settings_size) {
|
|
|
|
fs_result = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(fs_result) {
|
2021-11-12 13:04:35 +00:00
|
|
|
FURI_LOG_I(TAG, "save success");
|
2021-07-04 22:03:56 +00:00
|
|
|
} else {
|
2021-11-12 13:04:35 +00:00
|
|
|
FURI_LOG_E(TAG, "save failed, %s", storage_file_get_error_desc(file));
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
2021-07-04 22:03:56 +00:00
|
|
|
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
storage_file_close(file);
|
|
|
|
storage_file_free(file);
|
2022-07-26 12:21:51 +00:00
|
|
|
furi_record_close(RECORD_STORAGE);
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
|
|
|
|
return fs_result;
|
2021-07-04 22:03:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void input_event_callback(const void* value, void* context) {
|
2022-04-14 12:20:41 +00:00
|
|
|
furi_assert(value);
|
|
|
|
furi_assert(context);
|
2021-07-04 22:03:56 +00:00
|
|
|
NotificationApp* app = context;
|
2022-04-29 14:21:12 +00:00
|
|
|
notification_message(app, &sequence_display_backlight_on);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// App alloc
|
|
|
|
static NotificationApp* notification_app_alloc() {
|
2022-02-18 19:53:46 +00:00
|
|
|
NotificationApp* app = malloc(sizeof(NotificationApp));
|
2022-07-20 10:56:33 +00:00
|
|
|
app->queue = furi_message_queue_alloc(8, sizeof(NotificationAppMessage));
|
|
|
|
app->display_timer = furi_timer_alloc(notification_display_timer, FuriTimerTypeOnce, app);
|
2021-05-24 13:44:14 +00:00
|
|
|
|
2021-06-28 14:42:30 +00:00
|
|
|
app->settings.speaker_volume = 1.0f;
|
2021-05-24 13:44:14 +00:00
|
|
|
app->settings.display_brightness = 1.0f;
|
|
|
|
app->settings.led_brightness = 1.0f;
|
|
|
|
app->settings.display_off_delay_ms = 30000;
|
2021-07-04 22:03:56 +00:00
|
|
|
app->settings.vibro_on = true;
|
2021-05-24 13:44:14 +00:00
|
|
|
|
|
|
|
app->display.value[LayerInternal] = 0x00;
|
|
|
|
app->display.value[LayerNotification] = 0x00;
|
|
|
|
app->display.index = LayerInternal;
|
|
|
|
app->display.light = LightBacklight;
|
|
|
|
|
|
|
|
app->led[0].value[LayerInternal] = 0x00;
|
|
|
|
app->led[0].value[LayerNotification] = 0x00;
|
|
|
|
app->led[0].index = LayerInternal;
|
|
|
|
app->led[0].light = LightRed;
|
|
|
|
|
|
|
|
app->led[1].value[LayerInternal] = 0x00;
|
|
|
|
app->led[1].value[LayerNotification] = 0x00;
|
|
|
|
app->led[1].index = LayerInternal;
|
|
|
|
app->led[1].light = LightGreen;
|
|
|
|
|
|
|
|
app->led[2].value[LayerInternal] = 0x00;
|
|
|
|
app->led[2].value[LayerNotification] = 0x00;
|
|
|
|
app->led[2].index = LayerInternal;
|
|
|
|
app->led[2].light = LightBlue;
|
|
|
|
|
2021-07-04 22:03:56 +00:00
|
|
|
app->settings.version = NOTIFICATION_SETTINGS_VERSION;
|
|
|
|
|
|
|
|
// display backlight control
|
2022-07-26 12:21:51 +00:00
|
|
|
app->event_record = furi_record_open(RECORD_INPUT_EVENTS);
|
2021-11-01 20:35:54 +00:00
|
|
|
furi_pubsub_subscribe(app->event_record, input_event_callback, app);
|
2022-04-29 14:21:12 +00:00
|
|
|
notification_message(app, &sequence_display_backlight_on);
|
2021-07-04 22:03:56 +00:00
|
|
|
|
2021-05-24 13:44:14 +00:00
|
|
|
return app;
|
|
|
|
};
|
|
|
|
|
|
|
|
// App
|
2021-08-07 16:54:42 +00:00
|
|
|
int32_t notification_srv(void* p) {
|
2022-05-06 13:37:10 +00:00
|
|
|
UNUSED(p);
|
2021-05-24 13:44:14 +00:00
|
|
|
NotificationApp* app = notification_app_alloc();
|
|
|
|
|
[FL-1191][FL-1524] Filesystem rework (#568)
* FS-Api: removed datetime manipulation functions and most of the file flags
* Filesystem: common proxy api
* Filesystem: renamed to Storage. Work has begun on a glue layer. Added functions for reentrance.
* Storage: sd mount and sd file open
* Storage: sd file close
* Storage: temporary test app
* Storage: free filedata on close
* Storage: sd file read and write
* Storage: added internal storage (LittleFS)
* Storage: renamed internal commands
* Storage: seek, tell, truncate, size, sync, eof
* Storage: error descriptions
* Storage: directory management api (open, close, read, rewind)
* Storage: common management api (stat, fs_stat, remove, rename, mkdir)
* Dolphin app and Notifications app now use raw storage.
* Storage: storage statuses renamed. Implemented sd card icon.
* Storage: added raw sd-card api.
* Storage settings: work started
* Assets: use new icons approach
* Storage settings: working storage settings
* Storage: completely redesigned api, no longer sticking out FS_Api
* Storage: more simplified api, getting error_id from file is hidden from user, pointer to api is hidden inside file
* Storage: cli info and format commands
* Storage-cli: file list
* Storage: a simpler and more reliable api
* FatFS: slightly lighter and faster config. Also disabled reentrancy and file locking functions. They moved to a storage service.
* Storage-cli: accommodate to the new cli api.
* Storage: filesystem api is separated into internal and common api.
* Cli: added the ability to print the list of free heap blocks
* Storage: uses a list instead of an array to store the StorageFile. Rewrote api calls to use semaphores instead of thread flags.
* Storage settings: added the ability to benchmark the SD card.
* Gui module file select: uses new storage api
* Apps: removed deprecated sd_card_test application
* Args lib: support for enquoted arguments
* Dialogs: a new gui app for simple non-asynchronous apps
* Dialogs: view holder for easy single view work
* File worker: use new storage api
* IButton and lfrrfid apps: save keys to any storage
* Apps: fix ibutton and lfrfid stack, remove sd_card_test.
* SD filesystem: app removed
* File worker: fixed api pointer type
* Subghz: loading assets using the new storage api
* NFC: use the new storage api
* Dialogs: the better api for the message element
* Archive: use new storage api
* Irda: changed assest path, changed app path
* FileWorker: removed unused file_buf_cnt
* Storage: copying and renaming files now works between storages
* Storage cli: read, copy, remove, rename commands
* Archive: removed commented code
* Storage cli: write command
* Applications: add SRV_STORAGE and SRV_DIALOGS
* Internal-storage: removed
* Storage: improved api
* Storage app: changed api pointer from StorageApp to Storage
* Storage: better file_id handling
* Storage: more consistent errors
* Loader: support for NULL icons
* Storage: do nothing with the lfs file or directory if it is not open
* Storage: fix typo
* Storage: minor float usage cleanup, rename some symbols.
* Storage: compact doxygen comments.
Co-authored-by: あく <alleteam@gmail.com>
2021-07-23 12:20:19 +00:00
|
|
|
if(!notification_load_settings(app)) {
|
|
|
|
notification_save_settings(app);
|
|
|
|
}
|
2021-07-04 22:03:56 +00:00
|
|
|
|
2021-05-24 13:44:14 +00:00
|
|
|
notification_vibro_off();
|
|
|
|
notification_sound_off();
|
|
|
|
notification_apply_internal_led_layer(&app->display, 0x00);
|
|
|
|
notification_apply_internal_led_layer(&app->led[0], 0x00);
|
|
|
|
notification_apply_internal_led_layer(&app->led[1], 0x00);
|
|
|
|
notification_apply_internal_led_layer(&app->led[2], 0x00);
|
|
|
|
|
2022-07-26 12:21:51 +00:00
|
|
|
furi_record_create(RECORD_NOTIFICATION, app);
|
2021-05-24 13:44:14 +00:00
|
|
|
|
|
|
|
NotificationAppMessage message;
|
|
|
|
while(1) {
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_check(furi_message_queue_get(app->queue, &message, FuriWaitForever) == FuriStatusOk);
|
2021-05-24 13:44:14 +00:00
|
|
|
|
|
|
|
switch(message.type) {
|
|
|
|
case NotificationLayerMessage:
|
|
|
|
notification_process_notification_message(app, &message);
|
|
|
|
break;
|
|
|
|
case InternalLayerMessage:
|
|
|
|
notification_process_internal_message(app, &message);
|
2021-07-04 22:03:56 +00:00
|
|
|
break;
|
|
|
|
case SaveSettingsMessage:
|
|
|
|
notification_save_settings(app);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(message.back_event != NULL) {
|
2022-07-20 10:56:33 +00:00
|
|
|
furi_event_flag_set(message.back_event, NOTIFICATION_EVENT_COMPLETE);
|
2021-05-24 13:44:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2022-02-18 19:53:46 +00:00
|
|
|
};
|