[FL-2216, FL-2233] Archive fixes (#987)
* archive: badusb, u2f and various fixes * archive: delete confirmation * badusb: removed empty string check * string pointer check * FuriHal: insomnia overflow assert, fix double insomnia exit in ble. BadUsb: fix uncommitted model. * view update fixes in gpio, badusb, u2f Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
df2d1ad13f
commit
2a52d2d620
@ -39,6 +39,10 @@ ArchiveApp* archive_alloc() {
|
|||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
archive->view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input));
|
archive->view_dispatcher, ArchiveViewTextInput, text_input_get_view(archive->text_input));
|
||||||
|
|
||||||
|
archive->widget = widget_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
archive->view_dispatcher, ArchiveViewWidget, widget_get_view(archive->widget));
|
||||||
|
|
||||||
return archive;
|
return archive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +51,8 @@ void archive_free(ArchiveApp* archive) {
|
|||||||
|
|
||||||
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewBrowser);
|
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewBrowser);
|
||||||
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewTextInput);
|
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewTextInput);
|
||||||
|
view_dispatcher_remove_view(archive->view_dispatcher, ArchiveViewWidget);
|
||||||
|
widget_free(archive->widget);
|
||||||
view_dispatcher_free(archive->view_dispatcher);
|
view_dispatcher_free(archive->view_dispatcher);
|
||||||
scene_manager_free(archive->scene_manager);
|
scene_manager_free(archive->scene_manager);
|
||||||
browser_free(archive->browser);
|
browser_free(archive->browser);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <gui/view_dispatcher.h>
|
#include <gui/view_dispatcher.h>
|
||||||
#include <gui/scene_manager.h>
|
#include <gui/scene_manager.h>
|
||||||
#include <gui/modules/text_input.h>
|
#include <gui/modules/text_input.h>
|
||||||
|
#include <gui/modules/widget.h>
|
||||||
#include <loader/loader.h>
|
#include <loader/loader.h>
|
||||||
|
|
||||||
#include "views/archive_browser_view.h"
|
#include "views/archive_browser_view.h"
|
||||||
@ -15,6 +16,7 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
ArchiveViewBrowser,
|
ArchiveViewBrowser,
|
||||||
ArchiveViewTextInput,
|
ArchiveViewTextInput,
|
||||||
|
ArchiveViewWidget,
|
||||||
ArchiveViewTotal,
|
ArchiveViewTotal,
|
||||||
} ArchiveViewEnum;
|
} ArchiveViewEnum;
|
||||||
|
|
||||||
@ -24,6 +26,7 @@ struct ArchiveApp {
|
|||||||
SceneManager* scene_manager;
|
SceneManager* scene_manager;
|
||||||
ArchiveBrowserView* browser;
|
ArchiveBrowserView* browser;
|
||||||
TextInput* text_input;
|
TextInput* text_input;
|
||||||
|
Widget* widget;
|
||||||
char text_store[MAX_NAME_LEN];
|
char text_store[MAX_NAME_LEN];
|
||||||
char file_extension[MAX_EXT_LEN + 1];
|
char file_extension[MAX_EXT_LEN + 1];
|
||||||
};
|
};
|
||||||
|
74
applications/archive/helpers/archive_apps.c
Normal file
74
applications/archive/helpers/archive_apps.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "archive_files.h"
|
||||||
|
#include "archive_apps.h"
|
||||||
|
#include "archive_browser.h"
|
||||||
|
|
||||||
|
static const char* known_apps[] = {
|
||||||
|
[ArchiveAppTypeU2f] = "u2f",
|
||||||
|
};
|
||||||
|
|
||||||
|
ArchiveAppTypeEnum archive_get_app_type(const char* path) {
|
||||||
|
for(size_t i = 0; i < SIZEOF_ARRAY(known_apps); i++) {
|
||||||
|
if(strncmp(path, known_apps[i], strlen(known_apps[i])) != STRING_FAILURE) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ArchiveAppTypeUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool archive_app_is_available(void* context, const char* path) {
|
||||||
|
furi_assert(path);
|
||||||
|
|
||||||
|
ArchiveAppTypeEnum app = archive_get_app_type(path);
|
||||||
|
|
||||||
|
if(app == ArchiveAppTypeU2f) {
|
||||||
|
FileWorker* file_worker = file_worker_alloc(true);
|
||||||
|
bool file_exists = false;
|
||||||
|
file_worker_is_file_exist(file_worker, "/any/u2f/key.u2f", &file_exists);
|
||||||
|
if(file_exists) {
|
||||||
|
file_worker_is_file_exist(file_worker, "/any/u2f/cnt.u2f", &file_exists);
|
||||||
|
}
|
||||||
|
file_worker_free(file_worker);
|
||||||
|
return file_exists;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool archive_app_read_dir(void* context, const char* path) {
|
||||||
|
furi_assert(context);
|
||||||
|
furi_assert(path);
|
||||||
|
ArchiveBrowserView* browser = context;
|
||||||
|
|
||||||
|
ArchiveAppTypeEnum app = archive_get_app_type(path);
|
||||||
|
|
||||||
|
if(app == ArchiveAppTypeU2f) {
|
||||||
|
archive_add_app_item(browser, "/app:u2f/U2F Token");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void archive_app_delete_file(void* context, const char* path) {
|
||||||
|
furi_assert(context);
|
||||||
|
furi_assert(path);
|
||||||
|
ArchiveBrowserView* browser = context;
|
||||||
|
|
||||||
|
ArchiveAppTypeEnum app = archive_get_app_type(path);
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
if(app == ArchiveAppTypeU2f) {
|
||||||
|
FileWorker* file_worker = file_worker_alloc(true);
|
||||||
|
res = file_worker_remove(file_worker, "/any/u2f/key.u2f");
|
||||||
|
res |= file_worker_remove(file_worker, "/any/u2f/cnt.u2f");
|
||||||
|
file_worker_free(file_worker);
|
||||||
|
|
||||||
|
if(archive_is_favorite("/app:u2f/U2F Token")) {
|
||||||
|
archive_favorites_delete("/app:u2f/U2F Token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res) {
|
||||||
|
archive_file_array_rm_selected(browser);
|
||||||
|
}
|
||||||
|
}
|
21
applications/archive/helpers/archive_apps.h
Normal file
21
applications/archive/helpers/archive_apps.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ArchiveAppTypeU2f,
|
||||||
|
ArchiveAppTypeUnknown,
|
||||||
|
ArchiveAppsTotal,
|
||||||
|
} ArchiveAppTypeEnum;
|
||||||
|
|
||||||
|
static const ArchiveFileTypeEnum app_file_types[] = {
|
||||||
|
[ArchiveAppTypeU2f] = ArchiveFileTypeU2f,
|
||||||
|
[ArchiveAppTypeUnknown] = ArchiveFileTypeUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline const ArchiveFileTypeEnum archive_get_app_filetype(ArchiveAppTypeEnum app) {
|
||||||
|
return app_file_types[app];
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveAppTypeEnum archive_get_app_type(const char* path);
|
||||||
|
bool archive_app_is_available(void* context, const char* path);
|
||||||
|
bool archive_app_read_dir(void* context, const char* path);
|
||||||
|
void archive_app_delete_file(void* context, const char* path);
|
@ -1,5 +1,7 @@
|
|||||||
|
#include "archive_files.h"
|
||||||
|
#include "archive_apps.h"
|
||||||
#include "archive_browser.h"
|
#include "archive_browser.h"
|
||||||
#include "math.h"
|
#include <math.h>
|
||||||
|
|
||||||
void archive_update_offset(ArchiveBrowserView* browser) {
|
void archive_update_offset(ArchiveBrowserView* browser) {
|
||||||
furi_assert(browser);
|
furi_assert(browser);
|
||||||
@ -177,24 +179,53 @@ void archive_set_last_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void archive_add_item(ArchiveBrowserView* browser, FileInfo* file_info, const char* name) {
|
void archive_add_app_item(ArchiveBrowserView* browser, const char* name) {
|
||||||
|
furi_assert(browser);
|
||||||
|
furi_assert(name);
|
||||||
|
|
||||||
|
ArchiveFile_t item;
|
||||||
|
|
||||||
|
string_t full_name;
|
||||||
|
|
||||||
|
string_init_set(full_name, browser->path);
|
||||||
|
string_cat_printf(full_name, "/%s", name);
|
||||||
|
|
||||||
|
char* app_name = strchr(string_get_cstr(full_name), ':');
|
||||||
|
if(app_name == NULL) {
|
||||||
|
string_clear(full_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveFile_t_init(&item);
|
||||||
|
string_init_set_str(item.name, name);
|
||||||
|
set_file_type(&item, NULL, app_name + 1, true);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
|
files_array_push_back(model->files, item);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
ArchiveFile_t_clear(&item);
|
||||||
|
string_clear(full_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void archive_add_file_item(ArchiveBrowserView* browser, FileInfo* file_info, const char* name) {
|
||||||
furi_assert(browser);
|
furi_assert(browser);
|
||||||
furi_assert(file_info);
|
furi_assert(file_info);
|
||||||
furi_assert(name);
|
furi_assert(name);
|
||||||
|
|
||||||
ArchiveFile_t item;
|
ArchiveFile_t item;
|
||||||
|
|
||||||
if(filter_by_extension(file_info, get_tab_ext(archive_get_tab(browser)), name)) {
|
if(filter_by_extension(file_info, archive_get_tab_ext(archive_get_tab(browser)), name)) {
|
||||||
ArchiveFile_t_init(&item);
|
ArchiveFile_t_init(&item);
|
||||||
string_init_set_str(item.name, name);
|
string_init_set_str(item.name, name);
|
||||||
set_file_type(&item, file_info);
|
set_file_type(&item, file_info, archive_get_path(browser), false);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
files_array_push_back(model->files, item);
|
files_array_push_back(model->files, item);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
ArchiveFile_t_clear(&item);
|
ArchiveFile_t_clear(&item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,8 +239,7 @@ void archive_show_file_menu(ArchiveBrowserView* browser, bool show) {
|
|||||||
|
|
||||||
if(show) {
|
if(show) {
|
||||||
ArchiveFile_t* selected = files_array_get(model->files, model->idx);
|
ArchiveFile_t* selected = files_array_get(model->files, model->idx);
|
||||||
selected->fav = archive_is_favorite(
|
selected->fav = archive_is_favorite("%s", string_get_cstr(selected->name));
|
||||||
"%s/%s", string_get_cstr(browser->path), string_get_cstr(selected->name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -245,12 +275,18 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
|
|||||||
|
|
||||||
archive_set_tab(browser, tab);
|
archive_set_tab(browser, tab);
|
||||||
|
|
||||||
if((tab != ArchiveTabFavorites &&
|
const char* path = archive_get_default_path(tab);
|
||||||
!archive_dir_empty(browser, archive_get_default_path(tab))) ||
|
bool tab_empty = true;
|
||||||
(tab == ArchiveTabFavorites && !archive_favorites_count(browser))) {
|
if(tab == ArchiveTabFavorites) {
|
||||||
if(tab != ArchiveTabBrowser) {
|
if(archive_favorites_count(browser) > 0) tab_empty = false;
|
||||||
archive_switch_tab(browser, key);
|
} else if(strncmp(path, "/app:", 5) == 0) {
|
||||||
}
|
if(archive_app_is_available(browser, path)) tab_empty = false;
|
||||||
|
} else {
|
||||||
|
if(archive_dir_not_empty(browser, archive_get_default_path(tab))) tab_empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((tab_empty) && (tab != ArchiveTabBrowser)) {
|
||||||
|
archive_switch_tab(browser, key);
|
||||||
} else {
|
} else {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
@ -277,8 +313,7 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
string_cat(browser->path, "/");
|
string_set(browser->path, name);
|
||||||
string_cat(browser->path, name);
|
|
||||||
|
|
||||||
archive_switch_dir(browser, string_get_cstr(browser->path));
|
archive_switch_dir(browser, string_get_cstr(browser->path));
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ static const char* tab_default_paths[] = {
|
|||||||
[ArchiveTabSubGhz] = "/any/subghz",
|
[ArchiveTabSubGhz] = "/any/subghz",
|
||||||
[ArchiveTabLFRFID] = "/any/lfrfid",
|
[ArchiveTabLFRFID] = "/any/lfrfid",
|
||||||
[ArchiveTabIrda] = "/any/irda",
|
[ArchiveTabIrda] = "/any/irda",
|
||||||
|
[ArchiveTabBadUsb] = "/any/badusb",
|
||||||
|
[ArchiveTabU2f] = "/app:u2f",
|
||||||
[ArchiveTabBrowser] = "/any",
|
[ArchiveTabBrowser] = "/any",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20,30 +22,37 @@ static const char* known_ext[] = {
|
|||||||
[ArchiveFileTypeSubGhz] = ".sub",
|
[ArchiveFileTypeSubGhz] = ".sub",
|
||||||
[ArchiveFileTypeLFRFID] = ".rfid",
|
[ArchiveFileTypeLFRFID] = ".rfid",
|
||||||
[ArchiveFileTypeIrda] = ".ir",
|
[ArchiveFileTypeIrda] = ".ir",
|
||||||
|
[ArchiveFileTypeBadUsb] = ".txt",
|
||||||
|
[ArchiveFileTypeU2f] = "?",
|
||||||
|
[ArchiveFileTypeFolder] = "?",
|
||||||
|
[ArchiveFileTypeUnknown] = "*",
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline const char* get_tab_ext(ArchiveTabEnum tab) {
|
static const ArchiveFileTypeEnum known_type[] = {
|
||||||
switch(tab) {
|
[ArchiveTabFavorites] = ArchiveFileTypeUnknown,
|
||||||
case ArchiveTabIButton:
|
[ArchiveTabIButton] = ArchiveFileTypeIButton,
|
||||||
return known_ext[ArchiveFileTypeIButton];
|
[ArchiveTabNFC] = ArchiveFileTypeNFC,
|
||||||
case ArchiveTabNFC:
|
[ArchiveTabSubGhz] = ArchiveFileTypeSubGhz,
|
||||||
return known_ext[ArchiveFileTypeNFC];
|
[ArchiveTabLFRFID] = ArchiveFileTypeLFRFID,
|
||||||
case ArchiveTabSubGhz:
|
[ArchiveTabIrda] = ArchiveFileTypeIrda,
|
||||||
return known_ext[ArchiveFileTypeSubGhz];
|
[ArchiveTabBadUsb] = ArchiveFileTypeBadUsb,
|
||||||
case ArchiveTabLFRFID:
|
[ArchiveTabU2f] = ArchiveFileTypeU2f,
|
||||||
return known_ext[ArchiveFileTypeLFRFID];
|
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
|
||||||
case ArchiveTabIrda:
|
};
|
||||||
return known_ext[ArchiveFileTypeIrda];
|
|
||||||
default:
|
static inline const ArchiveFileTypeEnum archive_get_tab_filetype(ArchiveTabEnum tab) {
|
||||||
return "*";
|
return known_type[tab];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char* archive_get_tab_ext(ArchiveTabEnum tab) {
|
||||||
|
return known_ext[archive_get_tab_filetype(tab)];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char* archive_get_default_path(ArchiveTabEnum tab) {
|
static inline const char* archive_get_default_path(ArchiveTabEnum tab) {
|
||||||
return tab_default_paths[tab];
|
return tab_default_paths[tab];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_known_app(ArchiveFileTypeEnum type) {
|
inline bool archive_is_known_app(ArchiveFileTypeEnum type) {
|
||||||
return (type != ArchiveFileTypeFolder && type != ArchiveFileTypeUnknown);
|
return (type != ArchiveFileTypeFolder && type != ArchiveFileTypeUnknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +71,8 @@ uint8_t archive_get_depth(ArchiveBrowserView* browser);
|
|||||||
const char* archive_get_path(ArchiveBrowserView* browser);
|
const char* archive_get_path(ArchiveBrowserView* browser);
|
||||||
const char* archive_get_name(ArchiveBrowserView* browser);
|
const char* archive_get_name(ArchiveBrowserView* browser);
|
||||||
|
|
||||||
void archive_add_item(ArchiveBrowserView* browser, FileInfo* file_info, const char* name);
|
void archive_add_app_item(ArchiveBrowserView* browser, const char* name);
|
||||||
|
void archive_add_file_item(ArchiveBrowserView* browser, FileInfo* file_info, const char* name);
|
||||||
void archive_show_file_menu(ArchiveBrowserView* browser, bool show);
|
void archive_show_file_menu(ArchiveBrowserView* browser, bool show);
|
||||||
void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active);
|
void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active);
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
#include "archive_favorites.h"
|
#include "archive_favorites.h"
|
||||||
|
#include "archive_files.h"
|
||||||
|
#include "archive_apps.h"
|
||||||
#include "archive_browser.h"
|
#include "archive_browser.h"
|
||||||
|
|
||||||
uint16_t archive_favorites_count(void* context) {
|
uint16_t archive_favorites_count(void* context) {
|
||||||
@ -46,10 +48,16 @@ static bool archive_favourites_rescan() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file_exists = false;
|
if(string_search(buffer, "/app:") == 0) {
|
||||||
file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists);
|
if(archive_app_is_available(NULL, string_get_cstr(buffer))) {
|
||||||
if(file_exists) {
|
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
|
||||||
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
|
}
|
||||||
|
} else {
|
||||||
|
bool file_exists = false;
|
||||||
|
file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists);
|
||||||
|
if(file_exists) {
|
||||||
|
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,13 +96,22 @@ bool archive_favorites_read(void* context) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file_exists = false;
|
if(string_search(buffer, "/app:") == 0) {
|
||||||
file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists);
|
if(archive_app_is_available(browser, string_get_cstr(buffer))) {
|
||||||
|
archive_add_app_item(browser, string_get_cstr(buffer));
|
||||||
|
} else {
|
||||||
|
need_refresh = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bool file_exists = false;
|
||||||
|
file_worker_is_file_exist(file_worker, string_get_cstr(buffer), &file_exists);
|
||||||
|
|
||||||
|
if(file_exists)
|
||||||
|
archive_add_file_item(browser, &file_info, string_get_cstr(buffer));
|
||||||
|
else
|
||||||
|
need_refresh = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(file_exists)
|
|
||||||
archive_add_item(browser, &file_info, string_get_cstr(buffer));
|
|
||||||
else
|
|
||||||
need_refresh = true;
|
|
||||||
string_reset(buffer);
|
string_reset(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,8 +202,7 @@ bool archive_is_favorite(const char* format, ...) {
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool archive_favorites_rename(const char* file_path, const char* src, const char* dst) {
|
bool archive_favorites_rename(const char* src, const char* dst) {
|
||||||
furi_assert(file_path);
|
|
||||||
furi_assert(src);
|
furi_assert(src);
|
||||||
furi_assert(dst);
|
furi_assert(dst);
|
||||||
|
|
||||||
@ -198,7 +214,7 @@ bool archive_favorites_rename(const char* file_path, const char* src, const char
|
|||||||
string_init(buffer);
|
string_init(buffer);
|
||||||
string_init(path);
|
string_init(path);
|
||||||
|
|
||||||
string_printf(path, "%s/%s", file_path, src);
|
string_printf(path, "%s", src);
|
||||||
bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
bool result = file_worker_open(file_worker, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
|
@ -8,6 +8,6 @@ uint16_t archive_favorites_count(void* context);
|
|||||||
bool archive_favorites_read(void* context);
|
bool archive_favorites_read(void* context);
|
||||||
bool archive_favorites_delete(const char* format, ...);
|
bool archive_favorites_delete(const char* format, ...);
|
||||||
bool archive_is_favorite(const char* format, ...);
|
bool archive_is_favorite(const char* format, ...);
|
||||||
bool archive_favorites_rename(const char* file_path, const char* src, const char* dst);
|
bool archive_favorites_rename(const char* src, const char* dst);
|
||||||
void archive_add_to_favorites(const char* file_path);
|
void archive_add_to_favorites(const char* file_path);
|
||||||
void archive_favorites_save(void* context);
|
void archive_favorites_save(void* context);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#include "archive_files.h"
|
#include "archive_files.h"
|
||||||
|
#include "archive_apps.h"
|
||||||
#include "archive_browser.h"
|
#include "archive_browser.h"
|
||||||
|
|
||||||
#define TAG "Archive"
|
#define TAG "Archive"
|
||||||
|
|
||||||
|
#define ASSETS_DIR "assets"
|
||||||
|
|
||||||
bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name) {
|
bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name) {
|
||||||
furi_assert(file_info);
|
furi_assert(file_info);
|
||||||
furi_assert(tab_ext);
|
furi_assert(tab_ext);
|
||||||
@ -15,7 +18,11 @@ bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* n
|
|||||||
} else if(strstr(name, tab_ext) != NULL) {
|
} else if(strstr(name, tab_ext) != NULL) {
|
||||||
result = true;
|
result = true;
|
||||||
} else if(file_info->flags & FSF_DIRECTORY) {
|
} else if(file_info->flags & FSF_DIRECTORY) {
|
||||||
result = true;
|
if(strstr(name, ASSETS_DIR) != NULL) {
|
||||||
|
result = false; // Skip assets folder in all tabs except browser
|
||||||
|
} else {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -38,21 +45,36 @@ void archive_get_file_extension(char* name, char* ext) {
|
|||||||
strncpy(ext, dot, MAX_EXT_LEN);
|
strncpy(ext, dot, MAX_EXT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_file_type(ArchiveFile_t* file, FileInfo* file_info) {
|
void set_file_type(ArchiveFile_t* file, FileInfo* file_info, const char* path, bool is_app) {
|
||||||
furi_assert(file);
|
furi_assert(file);
|
||||||
furi_assert(file_info);
|
|
||||||
|
|
||||||
for(size_t i = 0; i < SIZEOF_ARRAY(known_ext); i++) {
|
file->is_app = is_app;
|
||||||
if(string_search_str(file->name, known_ext[i], 0) != STRING_FAILURE) {
|
if(is_app) {
|
||||||
file->type = i;
|
file->type = archive_get_app_filetype(archive_get_app_type(path));
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file_info->flags & FSF_DIRECTORY) {
|
|
||||||
file->type = ArchiveFileTypeFolder;
|
|
||||||
} else {
|
} else {
|
||||||
file->type = ArchiveFileTypeUnknown;
|
furi_assert(file_info);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < SIZEOF_ARRAY(known_ext); i++) {
|
||||||
|
if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue;
|
||||||
|
if(string_search_str(file->name, known_ext[i], 0) != STRING_FAILURE) {
|
||||||
|
if(i == ArchiveFileTypeBadUsb) {
|
||||||
|
if(string_search_str(file->name, archive_get_default_path(ArchiveTabBadUsb)) ==
|
||||||
|
0) {
|
||||||
|
file->type = i;
|
||||||
|
return; // *.txt file is a BadUSB script only if it is in BadUSB folder
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file->type = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_info->flags & FSF_DIRECTORY) {
|
||||||
|
file->type = ArchiveFileTypeFolder;
|
||||||
|
} else {
|
||||||
|
file->type = ArchiveFileTypeUnknown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,17 +85,21 @@ bool archive_get_filenames(void* context, const char* path) {
|
|||||||
ArchiveBrowserView* browser = context;
|
ArchiveBrowserView* browser = context;
|
||||||
archive_file_array_rm_all(browser);
|
archive_file_array_rm_all(browser);
|
||||||
|
|
||||||
if(archive_get_tab(browser) != ArchiveTabFavorites) {
|
if(archive_get_tab(browser) == ArchiveTabFavorites) {
|
||||||
res = archive_read_dir(browser, path);
|
|
||||||
} else {
|
|
||||||
res = archive_favorites_read(browser);
|
res = archive_favorites_read(browser);
|
||||||
|
} else if(strncmp(path, "/app:", 5) == 0) {
|
||||||
|
res = archive_app_read_dir(browser, path);
|
||||||
|
} else {
|
||||||
|
res = archive_read_dir(browser, path);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool archive_dir_empty(void* context, const char* path) { // can be simpler?
|
bool archive_dir_not_empty(void* context, const char* path) { // can be simpler?
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
|
|
||||||
|
ArchiveBrowserView* browser = context;
|
||||||
|
|
||||||
FileInfo file_info;
|
FileInfo file_info;
|
||||||
Storage* fs_api = furi_record_open("storage");
|
Storage* fs_api = furi_record_open("storage");
|
||||||
File* directory = storage_file_alloc(fs_api);
|
File* directory = storage_file_alloc(fs_api);
|
||||||
@ -92,8 +118,11 @@ bool archive_dir_empty(void* context, const char* path) { // can be simpler?
|
|||||||
}
|
}
|
||||||
if(files_found) {
|
if(files_found) {
|
||||||
break;
|
break;
|
||||||
} else if(storage_file_get_error(directory) == FSE_OK) {
|
} else if((storage_file_get_error(directory) == FSE_OK) && (name[0])) {
|
||||||
files_found = name[0];
|
if(filter_by_extension(
|
||||||
|
&file_info, archive_get_tab_ext(archive_get_tab(browser)), name)) {
|
||||||
|
files_found = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -114,6 +143,8 @@ bool archive_read_dir(void* context, const char* path) {
|
|||||||
Storage* fs_api = furi_record_open("storage");
|
Storage* fs_api = furi_record_open("storage");
|
||||||
File* directory = storage_file_alloc(fs_api);
|
File* directory = storage_file_alloc(fs_api);
|
||||||
char name[MAX_NAME_LEN];
|
char name[MAX_NAME_LEN];
|
||||||
|
snprintf(name, MAX_NAME_LEN, "%s/", path);
|
||||||
|
size_t path_len = strlen(name);
|
||||||
size_t files_cnt = 0;
|
size_t files_cnt = 0;
|
||||||
|
|
||||||
if(!storage_dir_open(directory, path)) {
|
if(!storage_dir_open(directory, path)) {
|
||||||
@ -123,13 +154,14 @@ bool archive_read_dir(void* context, const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!storage_dir_read(directory, &file_info, name, MAX_NAME_LEN)) {
|
if(!storage_dir_read(directory, &file_info, &name[path_len], MAX_NAME_LEN - path_len)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(files_cnt > MAX_FILES) {
|
if(files_cnt > MAX_FILES) {
|
||||||
break;
|
break;
|
||||||
} else if(storage_file_get_error(directory) == FSE_OK) {
|
} else if(storage_file_get_error(directory) == FSE_OK) {
|
||||||
archive_add_item(browser, &file_info, name);
|
archive_add_file_item(browser, &file_info, name);
|
||||||
++files_cnt;
|
++files_cnt;
|
||||||
} else {
|
} else {
|
||||||
storage_dir_close(directory);
|
storage_dir_close(directory);
|
||||||
|
@ -9,29 +9,38 @@ typedef enum {
|
|||||||
ArchiveFileTypeSubGhz,
|
ArchiveFileTypeSubGhz,
|
||||||
ArchiveFileTypeLFRFID,
|
ArchiveFileTypeLFRFID,
|
||||||
ArchiveFileTypeIrda,
|
ArchiveFileTypeIrda,
|
||||||
|
ArchiveFileTypeBadUsb,
|
||||||
|
ArchiveFileTypeU2f,
|
||||||
ArchiveFileTypeFolder,
|
ArchiveFileTypeFolder,
|
||||||
ArchiveFileTypeUnknown,
|
ArchiveFileTypeUnknown,
|
||||||
AppIdTotal,
|
ArchiveFileTypesTotal,
|
||||||
} ArchiveFileTypeEnum;
|
} ArchiveFileTypeEnum;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
string_t name;
|
string_t name;
|
||||||
ArchiveFileTypeEnum type;
|
ArchiveFileTypeEnum type;
|
||||||
bool fav;
|
bool fav;
|
||||||
|
bool is_app;
|
||||||
} ArchiveFile_t;
|
} ArchiveFile_t;
|
||||||
|
|
||||||
static void ArchiveFile_t_init(ArchiveFile_t* obj) {
|
static void ArchiveFile_t_init(ArchiveFile_t* obj) {
|
||||||
obj->type = ArchiveFileTypeUnknown;
|
obj->type = ArchiveFileTypeUnknown;
|
||||||
|
obj->is_app = false;
|
||||||
|
obj->fav = false;
|
||||||
string_init(obj->name);
|
string_init(obj->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) {
|
static void ArchiveFile_t_init_set(ArchiveFile_t* obj, const ArchiveFile_t* src) {
|
||||||
obj->type = src->type;
|
obj->type = src->type;
|
||||||
|
obj->is_app = src->is_app;
|
||||||
|
obj->fav = src->fav;
|
||||||
string_init_set(obj->name, src->name);
|
string_init_set(obj->name, src->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) {
|
static void ArchiveFile_t_set(ArchiveFile_t* obj, const ArchiveFile_t* src) {
|
||||||
obj->type = src->type;
|
obj->type = src->type;
|
||||||
|
obj->is_app = src->is_app;
|
||||||
|
obj->fav = src->fav;
|
||||||
string_set(obj->name, src->name);
|
string_set(obj->name, src->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,11 +57,11 @@ ARRAY_DEF(
|
|||||||
CLEAR(API_2(ArchiveFile_t_clear))))
|
CLEAR(API_2(ArchiveFile_t_clear))))
|
||||||
|
|
||||||
bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name);
|
bool filter_by_extension(FileInfo* file_info, const char* tab_ext, const char* name);
|
||||||
void set_file_type(ArchiveFile_t* file, FileInfo* file_info);
|
void set_file_type(ArchiveFile_t* file, FileInfo* file_info, const char* path, bool is_app);
|
||||||
void archive_trim_file_path(char* name, bool ext);
|
void archive_trim_file_path(char* name, bool ext);
|
||||||
void archive_get_file_extension(char* name, char* ext);
|
void archive_get_file_extension(char* name, char* ext);
|
||||||
bool archive_get_filenames(void* context, const char* path);
|
bool archive_get_filenames(void* context, const char* path);
|
||||||
bool archive_dir_empty(void* context, const char* path);
|
bool archive_dir_not_empty(void* context, const char* path);
|
||||||
bool archive_read_dir(void* context, const char* path);
|
bool archive_read_dir(void* context, const char* path);
|
||||||
void archive_file_append(const char* path, const char* format, ...);
|
void archive_file_append(const char* path, const char* format, ...);
|
||||||
void archive_delete_file(void* context, const char* format, ...);
|
void archive_delete_file(void* context, const char* format, ...);
|
@ -1,5 +1,6 @@
|
|||||||
#include "../archive_i.h"
|
#include "../archive_i.h"
|
||||||
#include "../helpers/archive_files.h"
|
#include "../helpers/archive_files.h"
|
||||||
|
#include "../helpers/archive_apps.h"
|
||||||
#include "../helpers/archive_favorites.h"
|
#include "../helpers/archive_favorites.h"
|
||||||
#include "../helpers/archive_browser.h"
|
#include "../helpers/archive_browser.h"
|
||||||
#include "../views/archive_browser_view.h"
|
#include "../views/archive_browser_view.h"
|
||||||
@ -12,29 +13,29 @@ static const char* flipper_app_name[] = {
|
|||||||
[ArchiveFileTypeSubGhz] = "Sub-GHz",
|
[ArchiveFileTypeSubGhz] = "Sub-GHz",
|
||||||
[ArchiveFileTypeLFRFID] = "125 kHz RFID",
|
[ArchiveFileTypeLFRFID] = "125 kHz RFID",
|
||||||
[ArchiveFileTypeIrda] = "Infrared",
|
[ArchiveFileTypeIrda] = "Infrared",
|
||||||
|
[ArchiveFileTypeBadUsb] = "Bad USB",
|
||||||
|
[ArchiveFileTypeU2f] = "U2F",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void archive_run_in_app(
|
static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) {
|
||||||
ArchiveBrowserView* browser,
|
|
||||||
ArchiveFile_t* selected,
|
|
||||||
bool full_path_provided) {
|
|
||||||
Loader* loader = furi_record_open("loader");
|
Loader* loader = furi_record_open("loader");
|
||||||
|
|
||||||
string_t full_path;
|
LoaderStatus status;
|
||||||
if(!full_path_provided) {
|
if(selected->is_app) {
|
||||||
string_init_printf(
|
char* param = strrchr(string_get_cstr(selected->name), '/');
|
||||||
full_path, "%s/%s", string_get_cstr(browser->path), string_get_cstr(selected->name));
|
if(param != NULL) {
|
||||||
|
param++;
|
||||||
|
}
|
||||||
|
status = loader_start(loader, flipper_app_name[selected->type], param);
|
||||||
} else {
|
} else {
|
||||||
string_init_set(full_path, selected->name);
|
status = loader_start(
|
||||||
|
loader, flipper_app_name[selected->type], string_get_cstr(selected->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
LoaderStatus status =
|
|
||||||
loader_start(loader, flipper_app_name[selected->type], string_get_cstr(full_path));
|
|
||||||
if(status != LoaderStatusOk) {
|
if(status != LoaderStatusOk) {
|
||||||
FURI_LOG_E(TAG, "loader_start failed: %d", status);
|
FURI_LOG_E(TAG, "loader_start failed: %d", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
string_clear(full_path);
|
|
||||||
furi_record_close("loader");
|
furi_record_close("loader");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,9 +58,8 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
|
|||||||
ArchiveBrowserView* browser = archive->browser;
|
ArchiveBrowserView* browser = archive->browser;
|
||||||
ArchiveFile_t* selected = archive_get_current_file(browser);
|
ArchiveFile_t* selected = archive_get_current_file(browser);
|
||||||
|
|
||||||
const char* path = archive_get_path(browser);
|
|
||||||
const char* name = archive_get_name(browser);
|
const char* name = archive_get_name(browser);
|
||||||
bool known_app = is_known_app(selected->type);
|
bool known_app = archive_is_known_app(selected->type);
|
||||||
bool favorites = archive_get_tab(browser) == ArchiveTabFavorites;
|
bool favorites = archive_get_tab(browser) == ArchiveTabFavorites;
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
|
|||||||
break;
|
break;
|
||||||
case ArchiveBrowserEventFileMenuRun:
|
case ArchiveBrowserEventFileMenuRun:
|
||||||
if(known_app) {
|
if(known_app) {
|
||||||
archive_run_in_app(browser, selected, favorites);
|
archive_run_in_app(browser, selected);
|
||||||
}
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
@ -85,10 +85,10 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
|
|||||||
archive_file_array_rm_selected(browser);
|
archive_file_array_rm_selected(browser);
|
||||||
archive_show_file_menu(browser, false);
|
archive_show_file_menu(browser, false);
|
||||||
} else if(known_app) {
|
} else if(known_app) {
|
||||||
if(archive_is_favorite("%s/%s", path, name)) {
|
if(archive_is_favorite("%s", name)) {
|
||||||
archive_favorites_delete("%s/%s", path, name);
|
archive_favorites_delete("%s", name);
|
||||||
} else {
|
} else {
|
||||||
archive_file_append(ARCHIVE_FAV_PATH, "%s/%s\n", path, name);
|
archive_file_append(ARCHIVE_FAV_PATH, "%s\n", name);
|
||||||
}
|
}
|
||||||
archive_show_file_menu(browser, false);
|
archive_show_file_menu(browser, false);
|
||||||
}
|
}
|
||||||
@ -98,18 +98,13 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
|
|||||||
case ArchiveBrowserEventFileMenuAction:
|
case ArchiveBrowserEventFileMenuAction:
|
||||||
if(favorites) {
|
if(favorites) {
|
||||||
browser->callback(ArchiveBrowserEventEnterFavMove, browser->context);
|
browser->callback(ArchiveBrowserEventEnterFavMove, browser->context);
|
||||||
} else if(known_app) {
|
} else if((known_app) && (selected->is_app == false)) {
|
||||||
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneRename);
|
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneRename);
|
||||||
}
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
case ArchiveBrowserEventFileMenuDelete:
|
case ArchiveBrowserEventFileMenuDelete:
|
||||||
if(favorites) {
|
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete);
|
||||||
archive_delete_file(browser, "%s", name);
|
|
||||||
} else {
|
|
||||||
archive_delete_file(browser, "%s/%s", path, name);
|
|
||||||
}
|
|
||||||
archive_show_file_menu(browser, false);
|
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
case ArchiveBrowserEventEnterDir:
|
case ArchiveBrowserEventEnterDir:
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
ADD_SCENE(archive, browser, Browser)
|
ADD_SCENE(archive, browser, Browser)
|
||||||
ADD_SCENE(archive, rename, Rename)
|
ADD_SCENE(archive, rename, Rename)
|
||||||
|
ADD_SCENE(archive, delete, Delete)
|
||||||
|
70
applications/archive/scenes/archive_scene_delete.c
Normal file
70
applications/archive/scenes/archive_scene_delete.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "../archive_i.h"
|
||||||
|
#include "../helpers/archive_favorites.h"
|
||||||
|
#include "../helpers/archive_files.h"
|
||||||
|
#include "../helpers/archive_apps.h"
|
||||||
|
#include "../helpers/archive_browser.h"
|
||||||
|
|
||||||
|
#define SCENE_DELETE_CUSTOM_EVENT (0UL)
|
||||||
|
#define MAX_TEXT_INPUT_LEN 22
|
||||||
|
|
||||||
|
void archive_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
ArchiveApp* app = (ArchiveApp*)context;
|
||||||
|
if(type == InputTypeShort) {
|
||||||
|
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void archive_scene_delete_on_enter(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
ArchiveApp* app = (ArchiveApp*)context;
|
||||||
|
|
||||||
|
widget_add_button_element(
|
||||||
|
app->widget, GuiButtonTypeLeft, "Back", archive_scene_delete_widget_callback, app);
|
||||||
|
widget_add_button_element(
|
||||||
|
app->widget, GuiButtonTypeRight, "Delete", archive_scene_delete_widget_callback, app);
|
||||||
|
|
||||||
|
ArchiveFile_t* current = archive_get_current_file(app->browser);
|
||||||
|
strlcpy(app->text_store, string_get_cstr(current->name), MAX_NAME_LEN);
|
||||||
|
char* name = strrchr(app->text_store, '/');
|
||||||
|
if(name != NULL) {
|
||||||
|
name++;
|
||||||
|
}
|
||||||
|
|
||||||
|
char delete_str[64];
|
||||||
|
snprintf(delete_str, sizeof(delete_str), "\e#Delete %s?\e#", name);
|
||||||
|
widget_add_text_box_element(app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, delete_str);
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, ArchiveViewWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool archive_scene_delete_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
furi_assert(context);
|
||||||
|
ArchiveApp* app = (ArchiveApp*)context;
|
||||||
|
|
||||||
|
ArchiveBrowserView* browser = app->browser;
|
||||||
|
ArchiveFile_t* selected = archive_get_current_file(browser);
|
||||||
|
const char* name = archive_get_name(browser);
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
if(event.event == GuiButtonTypeRight) {
|
||||||
|
if(selected->is_app) {
|
||||||
|
archive_app_delete_file(browser, name);
|
||||||
|
} else {
|
||||||
|
archive_delete_file(browser, "%s", name);
|
||||||
|
}
|
||||||
|
archive_show_file_menu(browser, false);
|
||||||
|
return scene_manager_previous_scene(app->scene_manager);
|
||||||
|
} else if(event.event == GuiButtonTypeLeft) {
|
||||||
|
return scene_manager_previous_scene(app->scene_manager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void archive_scene_delete_on_exit(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
ArchiveApp* app = (ArchiveApp*)context;
|
||||||
|
|
||||||
|
widget_reset(app->widget);
|
||||||
|
}
|
@ -52,7 +52,8 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
|
|||||||
const char* path = archive_get_path(archive->browser);
|
const char* path = archive_get_path(archive->browser);
|
||||||
const char* name = archive_get_name(archive->browser);
|
const char* name = archive_get_name(archive->browser);
|
||||||
|
|
||||||
string_init_printf(buffer_src, "%s/%s", path, name);
|
string_init_printf(buffer_src, "%s", name);
|
||||||
|
//TODO: take path from src name
|
||||||
string_init_printf(buffer_dst, "%s/%s", path, archive->text_store);
|
string_init_printf(buffer_dst, "%s/%s", path, archive->text_store);
|
||||||
|
|
||||||
// append extension
|
// append extension
|
||||||
@ -64,7 +65,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) {
|
|||||||
furi_record_close("storage");
|
furi_record_close("storage");
|
||||||
|
|
||||||
if(file->fav) {
|
if(file->fav) {
|
||||||
archive_favorites_rename(path, name, string_get_cstr(buffer_dst));
|
archive_favorites_rename(name, string_get_cstr(buffer_dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
string_clear(buffer_src);
|
string_clear(buffer_src);
|
||||||
|
@ -10,6 +10,8 @@ static const char* ArchiveTabNames[] = {
|
|||||||
[ArchiveTabSubGhz] = "Sub-GHz",
|
[ArchiveTabSubGhz] = "Sub-GHz",
|
||||||
[ArchiveTabLFRFID] = "RFID LF",
|
[ArchiveTabLFRFID] = "RFID LF",
|
||||||
[ArchiveTabIrda] = "Infrared",
|
[ArchiveTabIrda] = "Infrared",
|
||||||
|
[ArchiveTabBadUsb] = "Bad USB",
|
||||||
|
[ArchiveTabU2f] = "U2F",
|
||||||
[ArchiveTabBrowser] = "Browser"};
|
[ArchiveTabBrowser] = "Browser"};
|
||||||
|
|
||||||
static const Icon* ArchiveItemIcons[] = {
|
static const Icon* ArchiveItemIcons[] = {
|
||||||
@ -18,6 +20,8 @@ static const Icon* ArchiveItemIcons[] = {
|
|||||||
[ArchiveFileTypeSubGhz] = &I_sub1_10px,
|
[ArchiveFileTypeSubGhz] = &I_sub1_10px,
|
||||||
[ArchiveFileTypeLFRFID] = &I_125_10px,
|
[ArchiveFileTypeLFRFID] = &I_125_10px,
|
||||||
[ArchiveFileTypeIrda] = &I_ir_10px,
|
[ArchiveFileTypeIrda] = &I_ir_10px,
|
||||||
|
[ArchiveFileTypeBadUsb] = &I_badusb_10px,
|
||||||
|
[ArchiveFileTypeU2f] = &I_u2f_10px,
|
||||||
[ArchiveFileTypeFolder] = &I_dir_10px,
|
[ArchiveFileTypeFolder] = &I_dir_10px,
|
||||||
[ArchiveFileTypeUnknown] = &I_unknown_10px,
|
[ArchiveFileTypeUnknown] = &I_unknown_10px,
|
||||||
};
|
};
|
||||||
@ -47,15 +51,20 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
|
|||||||
|
|
||||||
ArchiveFile_t* selected = files_array_get(model->files, model->idx);
|
ArchiveFile_t* selected = files_array_get(model->files, model->idx);
|
||||||
|
|
||||||
if(!is_known_app(selected->type)) {
|
if(!archive_is_known_app(selected->type)) {
|
||||||
string_set_str(menu[0], "---");
|
string_set_str(menu[0], "---");
|
||||||
string_set_str(menu[1], "---");
|
string_set_str(menu[1], "---");
|
||||||
string_set_str(menu[2], "---");
|
string_set_str(menu[2], "---");
|
||||||
} else if(selected->fav) {
|
} else {
|
||||||
|
if(model->tab_idx == ArchiveTabFavorites) {
|
||||||
|
string_set_str(menu[2], "Move");
|
||||||
|
} else if(selected->is_app) {
|
||||||
|
string_set_str(menu[2], "---");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((selected->fav) || (model->tab_idx == ArchiveTabFavorites)) {
|
||||||
string_set_str(menu[1], "Unpin");
|
string_set_str(menu[1], "Unpin");
|
||||||
} else if(model->tab_idx == ArchiveTabFavorites) {
|
|
||||||
string_set_str(menu[1], "Unpin");
|
|
||||||
string_set_str(menu[2], "Move");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < MENU_ITEMS; i++) {
|
for(size_t i = 0; i < MENU_ITEMS; i++) {
|
||||||
@ -102,7 +111,7 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
|
|||||||
ArchiveFile_t* file = files_array_get(model->files, CLAMP(idx, array_size - 1, 0));
|
ArchiveFile_t* file = files_array_get(model->files, CLAMP(idx, array_size - 1, 0));
|
||||||
|
|
||||||
strlcpy(cstr_buff, string_get_cstr(file->name), string_size(file->name) + 1);
|
strlcpy(cstr_buff, string_get_cstr(file->name), string_size(file->name) + 1);
|
||||||
archive_trim_file_path(cstr_buff, is_known_app(file->type));
|
archive_trim_file_path(cstr_buff, archive_is_known_app(file->type));
|
||||||
string_init_set_str(str_buff, cstr_buff);
|
string_init_set_str(str_buff, cstr_buff);
|
||||||
elements_string_fit_width(
|
elements_string_fit_width(
|
||||||
canvas, str_buff, (scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX) - x_offset);
|
canvas, str_buff, (scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX) - x_offset);
|
||||||
|
@ -24,6 +24,8 @@ typedef enum {
|
|||||||
ArchiveTabNFC,
|
ArchiveTabNFC,
|
||||||
ArchiveTabIrda,
|
ArchiveTabIrda,
|
||||||
ArchiveTabIButton,
|
ArchiveTabIButton,
|
||||||
|
ArchiveTabBadUsb,
|
||||||
|
ArchiveTabU2f,
|
||||||
ArchiveTabBrowser,
|
ArchiveTabBrowser,
|
||||||
ArchiveTabTotal,
|
ArchiveTabTotal,
|
||||||
} ArchiveTabEnum;
|
} ArchiveTabEnum;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
|
#include <lib/toolbox/path.h>
|
||||||
|
|
||||||
static bool bad_usb_app_custom_event_callback(void* context, uint32_t event) {
|
static bool bad_usb_app_custom_event_callback(void* context, uint32_t event) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
@ -39,27 +40,34 @@ static bool bad_usb_check_assets() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
BadUsbApp* bad_usb_app_alloc() {
|
BadUsbApp* bad_usb_app_alloc(char* arg) {
|
||||||
BadUsbApp* app = furi_alloc(sizeof(BadUsbApp));
|
BadUsbApp* app = furi_alloc(sizeof(BadUsbApp));
|
||||||
|
|
||||||
|
if(arg != NULL) {
|
||||||
|
string_t filename;
|
||||||
|
string_init(filename);
|
||||||
|
path_extract_filename_no_ext(arg, filename);
|
||||||
|
strncpy(app->file_name, string_get_cstr(filename), BAD_USB_FILE_NAME_LEN);
|
||||||
|
string_clear(filename);
|
||||||
|
}
|
||||||
|
|
||||||
app->gui = furi_record_open("gui");
|
app->gui = furi_record_open("gui");
|
||||||
app->notifications = furi_record_open("notification");
|
app->notifications = furi_record_open("notification");
|
||||||
app->dialogs = furi_record_open("dialogs");
|
app->dialogs = furi_record_open("dialogs");
|
||||||
|
|
||||||
app->view_dispatcher = view_dispatcher_alloc();
|
app->view_dispatcher = view_dispatcher_alloc();
|
||||||
app->scene_manager = scene_manager_alloc(&bad_usb_scene_handlers, app);
|
|
||||||
view_dispatcher_enable_queue(app->view_dispatcher);
|
view_dispatcher_enable_queue(app->view_dispatcher);
|
||||||
|
|
||||||
|
app->scene_manager = scene_manager_alloc(&bad_usb_scene_handlers, app);
|
||||||
|
|
||||||
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
||||||
view_dispatcher_set_tick_event_callback(
|
view_dispatcher_set_tick_event_callback(
|
||||||
app->view_dispatcher, bad_usb_app_tick_event_callback, 500);
|
app->view_dispatcher, bad_usb_app_tick_event_callback, 500);
|
||||||
|
|
||||||
view_dispatcher_set_custom_event_callback(
|
view_dispatcher_set_custom_event_callback(
|
||||||
app->view_dispatcher, bad_usb_app_custom_event_callback);
|
app->view_dispatcher, bad_usb_app_custom_event_callback);
|
||||||
view_dispatcher_set_navigation_event_callback(
|
view_dispatcher_set_navigation_event_callback(
|
||||||
app->view_dispatcher, bad_usb_app_back_event_callback);
|
app->view_dispatcher, bad_usb_app_back_event_callback);
|
||||||
|
|
||||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
|
||||||
|
|
||||||
// Custom Widget
|
// Custom Widget
|
||||||
app->widget = widget_alloc();
|
app->widget = widget_alloc();
|
||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
@ -69,7 +77,11 @@ BadUsbApp* bad_usb_app_alloc() {
|
|||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
app->view_dispatcher, BadUsbAppViewWork, bad_usb_get_view(app->bad_usb_view));
|
app->view_dispatcher, BadUsbAppViewWork, bad_usb_get_view(app->bad_usb_view));
|
||||||
|
|
||||||
if(bad_usb_check_assets()) {
|
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||||
|
|
||||||
|
if(*app->file_name != '\0') {
|
||||||
|
scene_manager_next_scene(app->scene_manager, BadUsbSceneWork);
|
||||||
|
} else if(bad_usb_check_assets()) {
|
||||||
scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect);
|
scene_manager_next_scene(app->scene_manager, BadUsbSceneFileSelect);
|
||||||
} else {
|
} else {
|
||||||
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
|
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
|
||||||
@ -106,7 +118,7 @@ int32_t bad_usb_app(void* p) {
|
|||||||
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
||||||
furi_hal_usb_set_config(&usb_hid);
|
furi_hal_usb_set_config(&usb_hid);
|
||||||
|
|
||||||
BadUsbApp* bad_usb_app = bad_usb_app_alloc();
|
BadUsbApp* bad_usb_app = bad_usb_app_alloc((char*)p);
|
||||||
|
|
||||||
view_dispatcher_run(bad_usb_app->view_dispatcher);
|
view_dispatcher_run(bad_usb_app->view_dispatcher);
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* c
|
|||||||
bad_usb->view, (BadUsbModel * model) {
|
bad_usb->view, (BadUsbModel * model) {
|
||||||
bad_usb->callback = callback;
|
bad_usb->callback = callback;
|
||||||
bad_usb->context = context;
|
bad_usb->context = context;
|
||||||
return false;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ void bad_usb_set_file_name(BadUsb* bad_usb, char* name) {
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
bad_usb->view, (BadUsbModel * model) {
|
bad_usb->view, (BadUsbModel * model) {
|
||||||
model->file_name = name;
|
model->file_name = name;
|
||||||
return false;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +163,6 @@ void bad_usb_set_state(BadUsb* bad_usb, BadUsbState* st) {
|
|||||||
bad_usb->view, (BadUsbModel * model) {
|
bad_usb->view, (BadUsbModel * model) {
|
||||||
memcpy(&(model->state), st, sizeof(BadUsbState));
|
memcpy(&(model->state), st, sizeof(BadUsbState));
|
||||||
model->anim_frame ^= 1;
|
model->anim_frame ^= 1;
|
||||||
return false;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,6 @@ void gpio_usb_uart_update_state(GpioUsbUart* instance, UsbUartConfig* cfg, UsbUa
|
|||||||
model->rx_active = (model->rx_cnt != st->rx_cnt);
|
model->rx_active = (model->rx_cnt != st->rx_cnt);
|
||||||
model->tx_cnt = st->tx_cnt;
|
model->tx_cnt = st->tx_cnt;
|
||||||
model->rx_cnt = st->rx_cnt;
|
model->rx_cnt = st->rx_cnt;
|
||||||
return false;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,6 @@ void u2f_view_set_state(U2fView* u2f, U2fViewMsg msg) {
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
u2f->view, (U2fModel * model) {
|
u2f->view, (U2fModel * model) {
|
||||||
model->display_msg = msg;
|
model->display_msg = msg;
|
||||||
return false;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,9 @@ const uint8_t *_I_125_10px[] = {_I_125_10px_0};
|
|||||||
const uint8_t _I_Nfc_10px_0[] = {0x00,0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,};
|
const uint8_t _I_Nfc_10px_0[] = {0x00,0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,};
|
||||||
const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0};
|
const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0};
|
||||||
|
|
||||||
|
const uint8_t _I_badusb_10px_0[] = {0x01,0x00,0x11,0x00,0x00,0x0f,0xe2,0x01,0xfc,0x80,0xdd,0x20,0x32,0x48,0x08,0x14,0x40,0x23,0xa8,0x08,0xa0,};
|
||||||
|
const uint8_t *_I_badusb_10px[] = {_I_badusb_10px_0};
|
||||||
|
|
||||||
const uint8_t _I_ble_10px_0[] = {0x00,0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,};
|
const uint8_t _I_ble_10px_0[] = {0x00,0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,};
|
||||||
const uint8_t *_I_ble_10px[] = {_I_ble_10px_0};
|
const uint8_t *_I_ble_10px[] = {_I_ble_10px_0};
|
||||||
|
|
||||||
@ -55,6 +58,9 @@ const uint8_t *_I_ir_10px[] = {_I_ir_10px_0};
|
|||||||
const uint8_t _I_sub1_10px_0[] = {0x01,0x00,0x12,0x00,0x81,0x40,0x69,0x30,0x2c,0x2c,0x0b,0x6a,0x01,0x28,0x0c,0x0a,0x65,0x01,0x98,0x40,0x00,0x26,};
|
const uint8_t _I_sub1_10px_0[] = {0x01,0x00,0x12,0x00,0x81,0x40,0x69,0x30,0x2c,0x2c,0x0b,0x6a,0x01,0x28,0x0c,0x0a,0x65,0x01,0x98,0x40,0x00,0x26,};
|
||||||
const uint8_t *_I_sub1_10px[] = {_I_sub1_10px_0};
|
const uint8_t *_I_sub1_10px[] = {_I_sub1_10px_0};
|
||||||
|
|
||||||
|
const uint8_t _I_u2f_10px_0[] = {0x00,0x00,0x00,0xFE,0x01,0x01,0x02,0x0C,0x00,0xF2,0x03,0x92,0x02,0x0C,0x00,0x01,0x02,0xFE,0x01,0x00,0x00,};
|
||||||
|
const uint8_t *_I_u2f_10px[] = {_I_u2f_10px_0};
|
||||||
|
|
||||||
const uint8_t _I_unknown_10px_0[] = {0x01,0x00,0x12,0x00,0xbc,0x40,0x39,0x90,0x0c,0x24,0x03,0x81,0x00,0xb0,0x40,0x26,0x00,0x12,0x00,0x08,0x14,0xc0,};
|
const uint8_t _I_unknown_10px_0[] = {0x01,0x00,0x12,0x00,0xbc,0x40,0x39,0x90,0x0c,0x24,0x03,0x81,0x00,0xb0,0x40,0x26,0x00,0x12,0x00,0x08,0x14,0xc0,};
|
||||||
const uint8_t *_I_unknown_10px[] = {_I_unknown_10px_0};
|
const uint8_t *_I_unknown_10px[] = {_I_unknown_10px_0};
|
||||||
|
|
||||||
@ -624,11 +630,13 @@ const Icon A_Levelup1_128x64 = {.width=128,.height=64,.frame_count=11,.frame_rat
|
|||||||
const Icon A_Levelup2_128x64 = {.width=128,.height=64,.frame_count=11,.frame_rate=2,.frames=_A_Levelup2_128x64};
|
const Icon A_Levelup2_128x64 = {.width=128,.height=64,.frame_count=11,.frame_rate=2,.frames=_A_Levelup2_128x64};
|
||||||
const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px};
|
const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px};
|
||||||
const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px};
|
const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px};
|
||||||
|
const Icon I_badusb_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_badusb_10px};
|
||||||
const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px};
|
const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px};
|
||||||
const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px};
|
const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px};
|
||||||
const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px};
|
const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px};
|
||||||
const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ir_10px};
|
const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ir_10px};
|
||||||
const Icon I_sub1_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_sub1_10px};
|
const Icon I_sub1_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_sub1_10px};
|
||||||
|
const Icon I_u2f_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_u2f_10px};
|
||||||
const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px};
|
const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px};
|
||||||
const Icon I_BLE_Pairing_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_BLE_Pairing_128x64};
|
const Icon I_BLE_Pairing_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_BLE_Pairing_128x64};
|
||||||
const Icon I_Ble_connected_38x34 = {.width=38,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_Ble_connected_38x34};
|
const Icon I_Ble_connected_38x34 = {.width=38,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_Ble_connected_38x34};
|
||||||
|
@ -7,11 +7,13 @@ extern const Icon A_Levelup1_128x64;
|
|||||||
extern const Icon A_Levelup2_128x64;
|
extern const Icon A_Levelup2_128x64;
|
||||||
extern const Icon I_125_10px;
|
extern const Icon I_125_10px;
|
||||||
extern const Icon I_Nfc_10px;
|
extern const Icon I_Nfc_10px;
|
||||||
|
extern const Icon I_badusb_10px;
|
||||||
extern const Icon I_ble_10px;
|
extern const Icon I_ble_10px;
|
||||||
extern const Icon I_dir_10px;
|
extern const Icon I_dir_10px;
|
||||||
extern const Icon I_ibutt_10px;
|
extern const Icon I_ibutt_10px;
|
||||||
extern const Icon I_ir_10px;
|
extern const Icon I_ir_10px;
|
||||||
extern const Icon I_sub1_10px;
|
extern const Icon I_sub1_10px;
|
||||||
|
extern const Icon I_u2f_10px;
|
||||||
extern const Icon I_unknown_10px;
|
extern const Icon I_unknown_10px;
|
||||||
extern const Icon I_BLE_Pairing_128x64;
|
extern const Icon I_BLE_Pairing_128x64;
|
||||||
extern const Icon I_Ble_connected_38x34;
|
extern const Icon I_Ble_connected_38x34;
|
||||||
|
BIN
assets/icons/Archive/badusb_10px.png
Normal file
BIN
assets/icons/Archive/badusb_10px.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 576 B |
BIN
assets/icons/Archive/u2f_10px.png
Normal file
BIN
assets/icons/Archive/u2f_10px.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 583 B |
@ -116,6 +116,7 @@ void ble_glue_init() {
|
|||||||
|
|
||||||
bool ble_glue_wait_for_fus_start(WirelessFwInfo_t* info) {
|
bool ble_glue_wait_for_fus_start(WirelessFwInfo_t* info) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
size_t countdown = 1000;
|
size_t countdown = 1000;
|
||||||
while(countdown > 0) {
|
while(countdown > 0) {
|
||||||
if(ble_glue->status == BleGlueStatusFusStarted) {
|
if(ble_glue->status == BleGlueStatusFusStarted) {
|
||||||
@ -125,13 +126,14 @@ bool ble_glue_wait_for_fus_start(WirelessFwInfo_t* info) {
|
|||||||
countdown--;
|
countdown--;
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ble_glue->status == BleGlueStatusFusStarted) {
|
if(ble_glue->status == BleGlueStatusFusStarted) {
|
||||||
SHCI_GetWirelessFwInfo(info);
|
SHCI_GetWirelessFwInfo(info);
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_E(TAG, "Failed to start FUS");
|
FURI_LOG_E(TAG, "Failed to start FUS");
|
||||||
ble_glue->status = BleGlueStatusBroken;
|
ble_glue->status = BleGlueStatusBroken;
|
||||||
}
|
}
|
||||||
furi_hal_power_insomnia_exit();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,12 +90,14 @@ uint16_t furi_hal_power_insomnia_level() {
|
|||||||
|
|
||||||
void furi_hal_power_insomnia_enter() {
|
void furi_hal_power_insomnia_enter() {
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
|
furi_assert(furi_hal_power.insomnia < UINT8_MAX);
|
||||||
furi_hal_power.insomnia++;
|
furi_hal_power.insomnia++;
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_insomnia_exit() {
|
void furi_hal_power_insomnia_exit() {
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
|
furi_assert(furi_hal_power.insomnia > 0);
|
||||||
furi_hal_power.insomnia--;
|
furi_hal_power.insomnia--;
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ void ble_glue_init() {
|
|||||||
|
|
||||||
bool ble_glue_wait_for_fus_start(WirelessFwInfo_t* info) {
|
bool ble_glue_wait_for_fus_start(WirelessFwInfo_t* info) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
size_t countdown = 1000;
|
size_t countdown = 1000;
|
||||||
while(countdown > 0) {
|
while(countdown > 0) {
|
||||||
if(ble_glue->status == BleGlueStatusFusStarted) {
|
if(ble_glue->status == BleGlueStatusFusStarted) {
|
||||||
@ -125,13 +126,14 @@ bool ble_glue_wait_for_fus_start(WirelessFwInfo_t* info) {
|
|||||||
countdown--;
|
countdown--;
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ble_glue->status == BleGlueStatusFusStarted) {
|
if(ble_glue->status == BleGlueStatusFusStarted) {
|
||||||
SHCI_GetWirelessFwInfo(info);
|
SHCI_GetWirelessFwInfo(info);
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_E(TAG, "Failed to start FUS");
|
FURI_LOG_E(TAG, "Failed to start FUS");
|
||||||
ble_glue->status = BleGlueStatusBroken;
|
ble_glue->status = BleGlueStatusBroken;
|
||||||
}
|
}
|
||||||
furi_hal_power_insomnia_exit();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,12 +90,14 @@ uint16_t furi_hal_power_insomnia_level() {
|
|||||||
|
|
||||||
void furi_hal_power_insomnia_enter() {
|
void furi_hal_power_insomnia_enter() {
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
|
furi_assert(furi_hal_power.insomnia < UINT8_MAX);
|
||||||
furi_hal_power.insomnia++;
|
furi_hal_power.insomnia++;
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_insomnia_exit() {
|
void furi_hal_power_insomnia_exit() {
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
|
furi_assert(furi_hal_power.insomnia > 0);
|
||||||
furi_hal_power.insomnia--;
|
furi_hal_power.insomnia--;
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user