Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
commit
e64de44b73
@ -83,4 +83,4 @@ SpacesInParentheses: false
|
|||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
Standard: Cpp03
|
Standard: Cpp03
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
|||||||
2
.github/workflows/build_toolchain.yml
vendored
2
.github/workflows/build_toolchain.yml
vendored
@ -43,4 +43,4 @@ jobs:
|
|||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
cache-from: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache
|
cache-from: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache
|
||||||
cache-to: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache,mode=max
|
cache-to: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache,mode=max
|
||||||
|
|||||||
2
.github/workflows/check_submodules.yml
vendored
2
.github/workflows/check_submodules.yml
vendored
@ -14,4 +14,4 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: assets/protobuf
|
path: assets/protobuf
|
||||||
branch: dev
|
branch: dev
|
||||||
fetch_depth: 50
|
fetch_depth: 50
|
||||||
|
|||||||
@ -149,6 +149,7 @@ const AboutDialogScreen about_screens[] = {
|
|||||||
const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen);
|
const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen);
|
||||||
|
|
||||||
int32_t about_settings_app(void* p) {
|
int32_t about_settings_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
DialogsApp* dialogs = furi_record_open("dialogs");
|
DialogsApp* dialogs = furi_record_open("dialogs");
|
||||||
DialogMessage* message = dialog_message_alloc();
|
DialogMessage* message = dialog_message_alloc();
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
// app enter function
|
// app enter function
|
||||||
extern "C" int32_t accessor_app(void* p) {
|
extern "C" int32_t accessor_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
AccessorApp* app = new AccessorApp();
|
AccessorApp* app = new AccessorApp();
|
||||||
app->run();
|
app->run();
|
||||||
delete app;
|
delete app;
|
||||||
|
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,4 +51,4 @@ private:
|
|||||||
OneWireHost* onewire_host;
|
OneWireHost* onewire_host;
|
||||||
|
|
||||||
NotificationApp* notification;
|
NotificationApp* notification;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -64,7 +64,7 @@ void AccessorAppViewManager::send_event(AccessorEvent* event) {
|
|||||||
furi_check(result == osOK);
|
furi_check(result == osOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t AccessorAppViewManager::previous_view_callback(void* context) {
|
uint32_t AccessorAppViewManager::previous_view_callback(void*) {
|
||||||
if(event_queue != NULL) {
|
if(event_queue != NULL) {
|
||||||
AccessorEvent event;
|
AccessorEvent event;
|
||||||
event.type = AccessorEvent::Type::Back;
|
event.type = AccessorEvent::Type::Back;
|
||||||
@ -76,4 +76,4 @@ uint32_t AccessorAppViewManager::previous_view_callback(void* context) {
|
|||||||
|
|
||||||
void AccessorAppViewManager::add_view(ViewType view_type, View* view) {
|
void AccessorAppViewManager::add_view(ViewType view_type, View* view) {
|
||||||
view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view);
|
view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,4 +36,4 @@ private:
|
|||||||
// view elements
|
// view elements
|
||||||
Submenu* submenu;
|
Submenu* submenu;
|
||||||
Popup* popup;
|
Popup* popup;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -27,4 +27,4 @@ private:
|
|||||||
static int _wiegandType;
|
static int _wiegandType;
|
||||||
static unsigned long _code;
|
static unsigned long _code;
|
||||||
static unsigned long _codeHigh;
|
static unsigned long _codeHigh;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,4 +10,4 @@ public:
|
|||||||
virtual void on_exit(AccessorApp* app) = 0;
|
virtual void on_exit(AccessorApp* app) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,4 +6,4 @@ public:
|
|||||||
void on_enter(AccessorApp* app) final;
|
void on_enter(AccessorApp* app) final;
|
||||||
bool on_event(AccessorApp* app, AccessorEvent* event) final;
|
bool on_event(AccessorApp* app, AccessorEvent* event) final;
|
||||||
void on_exit(AccessorApp* app) final;
|
void on_exit(AccessorApp* app) final;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -55,6 +55,7 @@ extern void crypto_on_system_start();
|
|||||||
extern void ibutton_on_system_start();
|
extern void ibutton_on_system_start();
|
||||||
extern void infrared_on_system_start();
|
extern void infrared_on_system_start();
|
||||||
extern void lfrfid_on_system_start();
|
extern void lfrfid_on_system_start();
|
||||||
|
extern void music_player_on_system_start();
|
||||||
extern void nfc_on_system_start();
|
extern void nfc_on_system_start();
|
||||||
extern void storage_on_system_start();
|
extern void storage_on_system_start();
|
||||||
extern void subghz_on_system_start();
|
extern void subghz_on_system_start();
|
||||||
@ -280,6 +281,10 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = {
|
|||||||
infrared_on_system_start,
|
infrared_on_system_start,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef APP_MUSIC_PLAYER
|
||||||
|
music_player_on_system_start,
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef APP_NFC
|
#ifdef APP_NFC
|
||||||
nfc_on_system_start,
|
nfc_on_system_start,
|
||||||
#endif
|
#endif
|
||||||
@ -332,7 +337,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
|
|||||||
#ifdef APP_MUSIC_PLAYER
|
#ifdef APP_MUSIC_PLAYER
|
||||||
{.app = music_player_app,
|
{.app = music_player_app,
|
||||||
.name = "Music Player",
|
.name = "Music Player",
|
||||||
.stack_size = 1024,
|
.stack_size = 2048,
|
||||||
.icon = &A_Plugins_14,
|
.icon = &A_Plugins_14,
|
||||||
.flags = FlipperApplicationFlagDefault},
|
.flags = FlipperApplicationFlagDefault},
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -66,6 +66,7 @@ void archive_free(ArchiveApp* archive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t archive_app(void* p) {
|
int32_t archive_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
ArchiveApp* archive = archive_alloc();
|
ArchiveApp* archive = archive_alloc();
|
||||||
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
|
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneBrowser);
|
||||||
view_dispatcher_run(archive->view_dispatcher);
|
view_dispatcher_run(archive->view_dispatcher);
|
||||||
|
|||||||
@ -7,8 +7,8 @@ static const char* known_apps[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ArchiveAppTypeEnum archive_get_app_type(const char* path) {
|
ArchiveAppTypeEnum archive_get_app_type(const char* path) {
|
||||||
for(size_t i = 0; i < SIZEOF_ARRAY(known_apps); i++) {
|
for(size_t i = 0; i < COUNT_OF(known_apps); i++) {
|
||||||
if(strncmp(path, known_apps[i], strlen(known_apps[i])) != STRING_FAILURE) {
|
if(strncmp(path, known_apps[i], strlen(known_apps[i])) == 0) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16,6 +16,7 @@ ArchiveAppTypeEnum archive_get_app_type(const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool archive_app_is_available(void* context, const char* path) {
|
bool archive_app_is_available(void* context, const char* path) {
|
||||||
|
UNUSED(context);
|
||||||
furi_assert(path);
|
furi_assert(path);
|
||||||
|
|
||||||
ArchiveAppTypeEnum app = archive_get_app_type(path);
|
ArchiveAppTypeEnum app = archive_get_app_type(path);
|
||||||
|
|||||||
@ -11,7 +11,7 @@ static const ArchiveFileTypeEnum app_file_types[] = {
|
|||||||
[ArchiveAppTypeUnknown] = ArchiveFileTypeUnknown,
|
[ArchiveAppTypeUnknown] = ArchiveFileTypeUnknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline const ArchiveFileTypeEnum archive_get_app_filetype(ArchiveAppTypeEnum app) {
|
static inline ArchiveFileTypeEnum archive_get_app_filetype(ArchiveAppTypeEnum app) {
|
||||||
return app_file_types[app];
|
return app_file_types[app];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,8 @@
|
|||||||
bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx) {
|
bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx) {
|
||||||
size_t array_size = files_array_size(model->files);
|
size_t array_size = files_array_size(model->files);
|
||||||
|
|
||||||
if((idx >= model->array_offset + array_size) || (idx < model->array_offset)) {
|
if((idx >= (uint32_t)model->array_offset + array_size) ||
|
||||||
|
(idx < (uint32_t)model->array_offset)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,12 +21,14 @@ void archive_update_offset(ArchiveBrowserView* browser) {
|
|||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
uint16_t bounds = model->item_cnt > 3 ? 2 : model->item_cnt;
|
uint16_t bounds = model->item_cnt > 3 ? 2 : model->item_cnt;
|
||||||
|
|
||||||
if(model->item_cnt > 3 && model->item_idx >= model->item_cnt - 1) {
|
if((model->item_cnt > 3u) && (model->item_idx >= ((int32_t)model->item_cnt - 1))) {
|
||||||
model->list_offset = model->item_idx - 3;
|
model->list_offset = model->item_idx - 3;
|
||||||
} else if(model->list_offset < model->item_idx - bounds) {
|
} else if(model->list_offset < model->item_idx - bounds) {
|
||||||
model->list_offset = CLAMP(model->item_idx - 2, model->item_cnt - bounds, 0);
|
model->list_offset =
|
||||||
|
CLAMP(model->item_idx - 2, (int32_t)model->item_cnt - bounds, 0);
|
||||||
} else if(model->list_offset > model->item_idx - bounds) {
|
} else if(model->list_offset > model->item_idx - bounds) {
|
||||||
model->list_offset = CLAMP(model->item_idx - 1, model->item_cnt - bounds, 0);
|
model->list_offset =
|
||||||
|
CLAMP(model->item_idx - 1, (int32_t)model->item_cnt - bounds, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -77,9 +80,10 @@ void archive_set_item_count(ArchiveBrowserView* browser, uint32_t count) {
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
model->item_cnt = count;
|
model->item_cnt = count;
|
||||||
model->item_idx = CLAMP(model->item_idx, model->item_cnt - 1, 0);
|
model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
archive_update_offset(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void archive_file_array_rm_selected(ArchiveBrowserView* browser) {
|
void archive_file_array_rm_selected(ArchiveBrowserView* browser) {
|
||||||
@ -93,7 +97,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) {
|
|||||||
model->item_idx - model->array_offset,
|
model->item_idx - model->array_offset,
|
||||||
model->item_idx - model->array_offset + 1);
|
model->item_idx - model->array_offset + 1);
|
||||||
model->item_cnt--;
|
model->item_cnt--;
|
||||||
model->item_idx = CLAMP(model->item_idx, model->item_cnt - 1, 0);
|
model->item_idx = CLAMP(model->item_idx, (int32_t)model->item_cnt - 1, 0);
|
||||||
items_cnt = model->item_cnt;
|
items_cnt = model->item_cnt;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -112,14 +116,14 @@ void archive_file_array_swap(ArchiveBrowserView* browser, int8_t dir) {
|
|||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
ArchiveFile_t temp;
|
ArchiveFile_t temp;
|
||||||
size_t array_size = files_array_size(model->files) - 1;
|
size_t array_size = files_array_size(model->files) - 1;
|
||||||
uint8_t swap_idx = CLAMP(model->item_idx + dir, array_size, 0);
|
uint8_t swap_idx = CLAMP((size_t)(model->item_idx + dir), array_size, 0u);
|
||||||
|
|
||||||
if(model->item_idx == 0 && dir < 0) {
|
if(model->item_idx == 0 && dir < 0) {
|
||||||
ArchiveFile_t_init(&temp);
|
ArchiveFile_t_init(&temp);
|
||||||
files_array_pop_at(&temp, model->files, array_size);
|
files_array_pop_at(&temp, model->files, array_size);
|
||||||
files_array_push_at(model->files, model->item_idx, temp);
|
files_array_push_at(model->files, model->item_idx, temp);
|
||||||
ArchiveFile_t_clear(&temp);
|
ArchiveFile_t_clear(&temp);
|
||||||
} else if(model->item_idx == array_size && dir > 0) {
|
} else if(((uint32_t)model->item_idx == array_size) && (dir > 0)) {
|
||||||
ArchiveFile_t_init(&temp);
|
ArchiveFile_t_init(&temp);
|
||||||
files_array_pop_at(&temp, model->files, 0);
|
files_array_pop_at(&temp, model->files, 0);
|
||||||
files_array_push_at(model->files, array_size, temp);
|
files_array_push_at(model->files, array_size, temp);
|
||||||
@ -156,7 +160,7 @@ bool archive_file_array_load(ArchiveBrowserView* browser, int8_t dir) {
|
|||||||
} else {
|
} else {
|
||||||
offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 1;
|
offset_new = model->item_idx - FILE_LIST_BUF_LEN / 4 * 1;
|
||||||
}
|
}
|
||||||
offset_new = CLAMP(offset_new, model->item_cnt - FILE_LIST_BUF_LEN, 0);
|
offset_new = CLAMP(offset_new, (int32_t)model->item_cnt - FILE_LIST_BUF_LEN, 0);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -195,7 +199,7 @@ ArchiveFile_t* archive_get_file_at(ArchiveBrowserView* browser, size_t idx) {
|
|||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
idx = CLAMP(idx - model->array_offset, files_array_size(model->files), 0);
|
idx = CLAMP(idx - model->array_offset, files_array_size(model->files), 0u);
|
||||||
selected = files_array_size(model->files) ? files_array_get(model->files, idx) : NULL;
|
selected = files_array_size(model->files) ? files_array_get(model->files, idx) : NULL;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@ -246,6 +250,7 @@ void archive_set_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
void archive_set_last_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) {
|
void archive_set_last_tab(ArchiveBrowserView* browser, ArchiveTabEnum tab) {
|
||||||
|
UNUSED(tab); // FIXME?
|
||||||
furi_assert(browser);
|
furi_assert(browser);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
@ -396,8 +401,6 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
archive_dir_count_items(browser, string_get_cstr(name));
|
|
||||||
|
|
||||||
if(string_cmp(browser->path, name) != 0) {
|
if(string_cmp(browser->path, name) != 0) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
browser->view, (ArchiveBrowserViewModel * model) {
|
browser->view, (ArchiveBrowserViewModel * model) {
|
||||||
@ -410,6 +413,7 @@ void archive_enter_dir(ArchiveBrowserView* browser, string_t name) {
|
|||||||
string_set(browser->path, name);
|
string_set(browser->path, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
archive_dir_count_items(browser, string_get_cstr(name));
|
||||||
archive_switch_dir(browser, string_get_cstr(browser->path));
|
archive_switch_dir(browser, string_get_cstr(browser->path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ static const ArchiveFileTypeEnum known_type[] = {
|
|||||||
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
|
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline const ArchiveFileTypeEnum archive_get_tab_filetype(ArchiveTabEnum tab) {
|
static inline ArchiveFileTypeEnum archive_get_tab_filetype(ArchiveTabEnum tab) {
|
||||||
return known_type[tab];
|
return known_type[tab];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,7 @@ void archive_set_file_type(ArchiveFile_t* file, FileInfo* file_info, const char*
|
|||||||
} else {
|
} else {
|
||||||
furi_assert(file_info);
|
furi_assert(file_info);
|
||||||
|
|
||||||
for(size_t i = 0; i < SIZEOF_ARRAY(known_ext); i++) {
|
for(size_t i = 0; i < COUNT_OF(known_ext); i++) {
|
||||||
if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue;
|
if((known_ext[i][0] == '?') || (known_ext[i][0] == '*')) continue;
|
||||||
if(string_search_str(file->name, known_ext[i], 0) != STRING_FAILURE) {
|
if(string_search_str(file->name, known_ext[i], 0) != STRING_FAILURE) {
|
||||||
if(i == ArchiveFileTypeBadUsb) {
|
if(i == ArchiveFileTypeBadUsb) {
|
||||||
|
|||||||
@ -31,6 +31,7 @@ static void archive_loader_callback(const void* message, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) {
|
static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) {
|
||||||
|
UNUSED(browser);
|
||||||
Loader* loader = furi_record_open("loader");
|
Loader* loader = furi_record_open("loader");
|
||||||
|
|
||||||
LoaderStatus status;
|
LoaderStatus status;
|
||||||
@ -95,6 +96,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(known_app) {
|
if(known_app) {
|
||||||
archive_run_in_app(browser, selected);
|
archive_run_in_app(browser, selected);
|
||||||
}
|
}
|
||||||
|
archive_show_file_menu(browser, false);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
case ArchiveBrowserEventFileMenuPin:
|
case ArchiveBrowserEventFileMenuPin:
|
||||||
|
|||||||
@ -106,17 +106,17 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
|
|||||||
size_t array_size = files_array_size(model->files);
|
size_t array_size = files_array_size(model->files);
|
||||||
bool scrollbar = model->item_cnt > 4;
|
bool scrollbar = model->item_cnt > 4;
|
||||||
|
|
||||||
for(size_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) {
|
for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) {
|
||||||
string_t str_buff;
|
string_t str_buff;
|
||||||
char cstr_buff[MAX_NAME_LEN];
|
char cstr_buff[MAX_NAME_LEN];
|
||||||
size_t idx = CLAMP(i + model->list_offset, model->item_cnt, 0);
|
int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u);
|
||||||
uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0;
|
uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0;
|
||||||
|
|
||||||
ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading;
|
ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading;
|
||||||
|
|
||||||
if(archive_is_item_in_array(model, idx)) {
|
if(archive_is_item_in_array(model, idx)) {
|
||||||
ArchiveFile_t* file =
|
ArchiveFile_t* file = files_array_get(
|
||||||
files_array_get(model->files, CLAMP(idx - model->array_offset, array_size - 1, 0));
|
model->files, CLAMP(idx - model->array_offset, (int32_t)(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, archive_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);
|
||||||
@ -161,21 +161,21 @@ static void archive_render_status_bar(Canvas* canvas, ArchiveBrowserViewModel* m
|
|||||||
canvas_draw_box(canvas, 107, 0, 20, 13);
|
canvas_draw_box(canvas, 107, 0, 20, 13);
|
||||||
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_draw_frame(canvas, 1, 0, 50, 12);
|
canvas_draw_rframe(canvas, 0, 0, 51, 13, 1); // frame
|
||||||
canvas_draw_line(canvas, 0, 1, 0, 11);
|
canvas_draw_line(canvas, 49, 1, 49, 11); // shadow right
|
||||||
canvas_draw_line(canvas, 1, 12, 49, 12);
|
canvas_draw_line(canvas, 1, 11, 49, 11); // shadow bottom
|
||||||
canvas_draw_str_aligned(canvas, 26, 9, AlignCenter, AlignBottom, tab_name);
|
canvas_draw_str_aligned(canvas, 25, 9, AlignCenter, AlignBottom, tab_name);
|
||||||
|
|
||||||
canvas_draw_frame(canvas, 108, 0, 20, 12);
|
canvas_draw_rframe(canvas, 107, 0, 21, 13, 1);
|
||||||
canvas_draw_line(canvas, 107, 1, 107, 11);
|
canvas_draw_line(canvas, 126, 1, 126, 11);
|
||||||
canvas_draw_line(canvas, 108, 12, 126, 12);
|
canvas_draw_line(canvas, 108, 11, 126, 11);
|
||||||
|
|
||||||
if(model->move_fav) {
|
if(model->move_fav) {
|
||||||
canvas_draw_icon(canvas, 111, 4, &I_ButtonUp_7x4);
|
canvas_draw_icon(canvas, 110, 4, &I_ButtonUp_7x4);
|
||||||
canvas_draw_icon(canvas, 118, 4, &I_ButtonDown_7x4);
|
canvas_draw_icon(canvas, 117, 4, &I_ButtonDown_7x4);
|
||||||
} else {
|
} else {
|
||||||
canvas_draw_icon(canvas, 112, 2, &I_ButtonLeft_4x7);
|
canvas_draw_icon(canvas, 111, 2, &I_ButtonLeft_4x7);
|
||||||
canvas_draw_icon(canvas, 120, 2, &I_ButtonRight_4x7);
|
canvas_draw_icon(canvas, 119, 2, &I_ButtonRight_4x7);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_set_color(canvas, ColorWhite);
|
canvas_set_color(canvas, ColorWhite);
|
||||||
@ -216,7 +216,7 @@ static bool is_file_list_load_required(ArchiveBrowserViewModel* model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(((model->array_offset + array_size) < model->item_cnt) &&
|
if(((model->array_offset + array_size) < model->item_cnt) &&
|
||||||
(model->item_idx > (model->array_offset + array_size - FILE_LIST_BUF_LEN / 4))) {
|
(model->item_idx > (int32_t)(model->array_offset + array_size - FILE_LIST_BUF_LEN / 4))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +347,7 @@ ArchiveBrowserView* browser_alloc() {
|
|||||||
browser->view = view_alloc();
|
browser->view = view_alloc();
|
||||||
view_allocate_model(browser->view, ViewModelTypeLocking, sizeof(ArchiveBrowserViewModel));
|
view_allocate_model(browser->view, ViewModelTypeLocking, sizeof(ArchiveBrowserViewModel));
|
||||||
view_set_context(browser->view, browser);
|
view_set_context(browser->view, browser);
|
||||||
view_set_draw_callback(browser->view, (ViewDrawCallback)archive_view_render);
|
view_set_draw_callback(browser->view, archive_view_render);
|
||||||
view_set_input_callback(browser->view, archive_view_input);
|
view_set_input_callback(browser->view, archive_view_input);
|
||||||
|
|
||||||
string_init(browser->path);
|
string_init(browser->path);
|
||||||
@ -376,4 +376,4 @@ void browser_free(ArchiveBrowserView* browser) {
|
|||||||
|
|
||||||
view_free(browser->view);
|
view_free(browser->view);
|
||||||
free(browser);
|
free(browser);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,8 +13,8 @@
|
|||||||
#define MAX_NAME_LEN 255
|
#define MAX_NAME_LEN 255
|
||||||
#define MAX_EXT_LEN 6
|
#define MAX_EXT_LEN 6
|
||||||
#define FRAME_HEIGHT 12
|
#define FRAME_HEIGHT 12
|
||||||
#define MENU_ITEMS 4
|
#define MENU_ITEMS 4u
|
||||||
#define MOVE_OFFSET 5
|
#define MOVE_OFFSET 5u
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ArchiveTabFavorites,
|
ArchiveTabFavorites,
|
||||||
|
|||||||
@ -31,10 +31,13 @@ void bad_usb_scene_file_select_on_enter(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool bad_usb_scene_file_select_on_event(void* context, SceneManagerEvent event) {
|
bool bad_usb_scene_file_select_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
UNUSED(context);
|
||||||
|
UNUSED(event);
|
||||||
// BadUsbApp* bad_usb = context;
|
// BadUsbApp* bad_usb = context;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bad_usb_scene_file_select_on_exit(void* context) {
|
void bad_usb_scene_file_select_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
// BadUsbApp* bad_usb = context;
|
// BadUsbApp* bad_usb = context;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,6 +142,7 @@ void bad_usb_set_ok_callback(BadUsb* bad_usb, BadUsbOkCallback callback, void* c
|
|||||||
furi_assert(callback);
|
furi_assert(callback);
|
||||||
with_view_model(
|
with_view_model(
|
||||||
bad_usb->view, (BadUsbModel * model) {
|
bad_usb->view, (BadUsbModel * model) {
|
||||||
|
UNUSED(model);
|
||||||
bad_usb->callback = callback;
|
bad_usb->callback = callback;
|
||||||
bad_usb->context = context;
|
bad_usb->context = context;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -13,6 +13,9 @@ static const char* bt_cli_address_types[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) {
|
static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
string_t buffer;
|
string_t buffer;
|
||||||
string_init(buffer);
|
string_init(buffer);
|
||||||
furi_hal_bt_dump_state(buffer);
|
furi_hal_bt_dump_state(buffer);
|
||||||
@ -21,6 +24,7 @@ static void bt_cli_command_hci_info(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) {
|
static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
int channel = 0;
|
int channel = 0;
|
||||||
int power = 0;
|
int power = 0;
|
||||||
|
|
||||||
@ -47,6 +51,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) {
|
static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
int channel = 0;
|
int channel = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -63,7 +68,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) {
|
|||||||
|
|
||||||
while(!cli_cmd_interrupt_received(cli)) {
|
while(!cli_cmd_interrupt_received(cli)) {
|
||||||
osDelay(250);
|
osDelay(250);
|
||||||
printf("RSSI: %6.1f dB\r", furi_hal_bt_get_rssi());
|
printf("RSSI: %6.1f dB\r", (double)furi_hal_bt_get_rssi());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +77,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) {
|
static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
int channel = 0;
|
int channel = 0;
|
||||||
int pattern = 0;
|
int pattern = 0;
|
||||||
int datarate = 1;
|
int datarate = 1;
|
||||||
@ -115,6 +121,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) {
|
static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
int channel = 0;
|
int channel = 0;
|
||||||
int datarate = 1;
|
int datarate = 1;
|
||||||
|
|
||||||
@ -133,11 +140,9 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) {
|
|||||||
printf("Press CTRL+C to stop\r\n");
|
printf("Press CTRL+C to stop\r\n");
|
||||||
furi_hal_bt_start_packet_rx(channel, datarate);
|
furi_hal_bt_start_packet_rx(channel, datarate);
|
||||||
|
|
||||||
float rssi_raw = 0;
|
|
||||||
while(!cli_cmd_interrupt_received(cli)) {
|
while(!cli_cmd_interrupt_received(cli)) {
|
||||||
osDelay(250);
|
osDelay(250);
|
||||||
rssi_raw = furi_hal_bt_get_rssi();
|
printf("RSSI: %03.1f dB\r", (double)furi_hal_bt_get_rssi());
|
||||||
printf("RSSI: %03.1f dB\r", rssi_raw);
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
uint16_t packets_received = furi_hal_bt_stop_packet_test();
|
uint16_t packets_received = furi_hal_bt_stop_packet_test();
|
||||||
@ -152,6 +157,8 @@ static void bt_cli_scan_callback(GapAddress address, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bt_cli_command_scan(Cli* cli, string_t args, void* context) {
|
static void bt_cli_command_scan(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
|
UNUSED(args);
|
||||||
osMessageQueueId_t queue = osMessageQueueNew(20, sizeof(GapAddress), NULL);
|
osMessageQueueId_t queue = osMessageQueueNew(20, sizeof(GapAddress), NULL);
|
||||||
furi_hal_bt_start_scan(bt_cli_scan_callback, queue);
|
furi_hal_bt_start_scan(bt_cli_scan_callback, queue);
|
||||||
|
|
||||||
@ -189,6 +196,7 @@ static void bt_cli_print_usage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void bt_cli(Cli* cli, string_t args, void* context) {
|
static void bt_cli(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
furi_record_open("bt");
|
furi_record_open("bt");
|
||||||
|
|
||||||
string_t cmd;
|
string_t cmd;
|
||||||
|
|||||||
@ -19,10 +19,12 @@ void bt_debug_submenu_callback(void* context, uint32_t index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bt_debug_exit(void* context) {
|
uint32_t bt_debug_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return VIEW_NONE;
|
return VIEW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bt_debug_start_view(void* context) {
|
uint32_t bt_debug_start_view(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return BtDebugAppViewSubmenu;
|
return BtDebugAppViewSubmenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +96,7 @@ void bt_debug_app_free(BtDebugApp* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t bt_debug_app(void* p) {
|
int32_t bt_debug_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
if(furi_hal_bt_get_radio_stack() != FuriHalBtStackHciLayer) {
|
if(furi_hal_bt_get_radio_stack() != FuriHalBtStackHciLayer) {
|
||||||
FURI_LOG_E(TAG, "Incorrect radio stack, replace with HciLayer for tests.");
|
FURI_LOG_E(TAG, "Incorrect radio stack, replace with HciLayer for tests.");
|
||||||
DialogsApp* dialogs = furi_record_open("dialogs");
|
DialogsApp* dialogs = furi_record_open("dialogs");
|
||||||
|
|||||||
@ -141,7 +141,7 @@ BtCarrierTest* bt_carrier_test_alloc() {
|
|||||||
param = bt_test_param_add(
|
param = bt_test_param_add(
|
||||||
bt_carrier_test->bt_test,
|
bt_carrier_test->bt_test,
|
||||||
"Mode",
|
"Mode",
|
||||||
SIZEOF_ARRAY(bt_param_mode),
|
COUNT_OF(bt_param_mode),
|
||||||
bt_carrier_test_mode_changed,
|
bt_carrier_test_mode_changed,
|
||||||
bt_carrier_test);
|
bt_carrier_test);
|
||||||
bt_test_set_current_value_index(param, 0);
|
bt_test_set_current_value_index(param, 0);
|
||||||
@ -151,7 +151,7 @@ BtCarrierTest* bt_carrier_test_alloc() {
|
|||||||
param = bt_test_param_add(
|
param = bt_test_param_add(
|
||||||
bt_carrier_test->bt_test,
|
bt_carrier_test->bt_test,
|
||||||
"Channel",
|
"Channel",
|
||||||
SIZEOF_ARRAY(bt_param_channel),
|
COUNT_OF(bt_param_channel),
|
||||||
bt_carrier_test_channel_changed,
|
bt_carrier_test_channel_changed,
|
||||||
bt_carrier_test);
|
bt_carrier_test);
|
||||||
bt_test_set_current_value_index(param, 0);
|
bt_test_set_current_value_index(param, 0);
|
||||||
@ -162,7 +162,7 @@ BtCarrierTest* bt_carrier_test_alloc() {
|
|||||||
param = bt_test_param_add(
|
param = bt_test_param_add(
|
||||||
bt_carrier_test->bt_test,
|
bt_carrier_test->bt_test,
|
||||||
"Power",
|
"Power",
|
||||||
SIZEOF_ARRAY(bt_param_power),
|
COUNT_OF(bt_param_power),
|
||||||
bt_carrier_test_param_channel,
|
bt_carrier_test_param_channel,
|
||||||
bt_carrier_test);
|
bt_carrier_test);
|
||||||
bt_test_set_current_value_index(param, 0);
|
bt_test_set_current_value_index(param, 0);
|
||||||
|
|||||||
@ -109,7 +109,7 @@ BtPacketTest* bt_packet_test_alloc() {
|
|||||||
param = bt_test_param_add(
|
param = bt_test_param_add(
|
||||||
bt_packet_test->bt_test,
|
bt_packet_test->bt_test,
|
||||||
"Mode",
|
"Mode",
|
||||||
SIZEOF_ARRAY(bt_param_mode),
|
COUNT_OF(bt_param_mode),
|
||||||
bt_packet_test_mode_changed,
|
bt_packet_test_mode_changed,
|
||||||
bt_packet_test);
|
bt_packet_test);
|
||||||
bt_test_set_current_value_index(param, 0);
|
bt_test_set_current_value_index(param, 0);
|
||||||
@ -119,7 +119,7 @@ BtPacketTest* bt_packet_test_alloc() {
|
|||||||
param = bt_test_param_add(
|
param = bt_test_param_add(
|
||||||
bt_packet_test->bt_test,
|
bt_packet_test->bt_test,
|
||||||
"Channel",
|
"Channel",
|
||||||
SIZEOF_ARRAY(bt_param_channel),
|
COUNT_OF(bt_param_channel),
|
||||||
bt_packet_test_channel_changed,
|
bt_packet_test_channel_changed,
|
||||||
bt_packet_test);
|
bt_packet_test);
|
||||||
bt_test_set_current_value_index(param, 0);
|
bt_test_set_current_value_index(param, 0);
|
||||||
@ -129,7 +129,7 @@ BtPacketTest* bt_packet_test_alloc() {
|
|||||||
param = bt_test_param_add(
|
param = bt_test_param_add(
|
||||||
bt_packet_test->bt_test,
|
bt_packet_test->bt_test,
|
||||||
"Data rate",
|
"Data rate",
|
||||||
SIZEOF_ARRAY(bt_param_data_rate),
|
COUNT_OF(bt_param_data_rate),
|
||||||
bt_packet_test_param_channel,
|
bt_packet_test_param_channel,
|
||||||
bt_packet_test);
|
bt_packet_test);
|
||||||
bt_test_set_current_value_index(param, 0);
|
bt_test_set_current_value_index(param, 0);
|
||||||
|
|||||||
@ -99,7 +99,7 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
canvas_draw_str(canvas, 6, 60, model->message);
|
canvas_draw_str(canvas, 6, 60, model->message);
|
||||||
if(model->state == BtTestStateStarted) {
|
if(model->state == BtTestStateStarted) {
|
||||||
if(model->rssi != 0.0f) {
|
if(model->rssi != 0.0f) {
|
||||||
snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", model->rssi);
|
snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi);
|
||||||
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
||||||
}
|
}
|
||||||
} else if(model->state == BtTestStateStopped) {
|
} else if(model->state == BtTestStateStopped) {
|
||||||
|
|||||||
@ -33,10 +33,12 @@ void bt_hid_dialog_callback(DialogExResult result, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bt_hid_exit_confirm_view(void* context) {
|
uint32_t bt_hid_exit_confirm_view(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return BtHidViewExitConfirm;
|
return BtHidViewExitConfirm;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bt_hid_exit(void* context) {
|
uint32_t bt_hid_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return VIEW_NONE;
|
return VIEW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +141,7 @@ void bt_hid_app_free(BtHid* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t bt_hid_app(void* p) {
|
int32_t bt_hid_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
// Switch profile to Hid
|
// Switch profile to Hid
|
||||||
BtHid* app = bt_hid_app_alloc();
|
BtHid* app = bt_hid_app_alloc();
|
||||||
bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
|
bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app);
|
||||||
|
|||||||
@ -76,6 +76,7 @@ void bt_settings_app_free(BtSettingsApp* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern int32_t bt_settings_app(void* p) {
|
extern int32_t bt_settings_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
BtSettingsApp* app = bt_settings_app_alloc();
|
BtSettingsApp* app = bt_settings_app_alloc();
|
||||||
view_dispatcher_run(app->view_dispatcher);
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
bt_settings_save(&app->settings);
|
bt_settings_save(&app->settings);
|
||||||
|
|||||||
@ -130,10 +130,12 @@ void cli_motd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_nl(Cli* cli) {
|
void cli_nl(Cli* cli) {
|
||||||
|
UNUSED(cli);
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_prompt(Cli* cli) {
|
void cli_prompt(Cli* cli) {
|
||||||
|
UNUSED(cli);
|
||||||
printf("\r\n>: %s", string_get_cstr(cli->line));
|
printf("\r\n>: %s", string_get_cstr(cli->line));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@ -451,6 +453,7 @@ void cli_session_close(Cli* cli) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t cli_srv(void* p) {
|
int32_t cli_srv(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
Cli* cli = cli_alloc();
|
Cli* cli = cli_alloc();
|
||||||
|
|
||||||
// Init basic cli commands
|
// Init basic cli commands
|
||||||
|
|||||||
@ -12,6 +12,8 @@
|
|||||||
#define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d"
|
#define CLI_DATE_FORMAT "%.4d-%.2d-%.2d %.2d:%.2d:%.2d %d"
|
||||||
|
|
||||||
void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) {
|
void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
|
UNUSED(last);
|
||||||
printf("%-24s: %s\r\n", key, value);
|
printf("%-24s: %s\r\n", key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,11 +22,14 @@ void cli_command_device_info_callback(const char* key, const char* value, bool l
|
|||||||
* This command is intended to be used by humans
|
* This command is intended to be used by humans
|
||||||
*/
|
*/
|
||||||
void cli_command_device_info(Cli* cli, string_t args, void* context) {
|
void cli_command_device_info(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
furi_hal_info_get(cli_command_device_info_callback, context);
|
furi_hal_info_get(cli_command_device_info_callback, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_help(Cli* cli, string_t args, void* context) {
|
void cli_command_help(Cli* cli, string_t args, void* context) {
|
||||||
(void)args;
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
printf("Commands we have:");
|
printf("Commands we have:");
|
||||||
|
|
||||||
// Command count
|
// Command count
|
||||||
@ -62,6 +67,9 @@ void cli_command_help(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_date(Cli* cli, string_t args, void* context) {
|
void cli_command_date(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
FuriHalRtcDateTime datetime = {0};
|
FuriHalRtcDateTime datetime = {0};
|
||||||
|
|
||||||
if(string_size(args) > 0) {
|
if(string_size(args) > 0) {
|
||||||
@ -135,6 +143,8 @@ void cli_command_log_tx_callback(const uint8_t* buffer, size_t size, void* conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_log(Cli* cli, string_t args, void* context) {
|
void cli_command_log(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1);
|
StreamBufferHandle_t ring = xStreamBufferCreate(CLI_COMMAND_LOG_RING_SIZE, 1);
|
||||||
uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE];
|
uint8_t buffer[CLI_COMMAND_LOG_BUFFER_SIZE];
|
||||||
|
|
||||||
@ -152,6 +162,8 @@ void cli_command_log(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_vibro(Cli* cli, string_t args, void* context) {
|
void cli_command_vibro(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(context);
|
||||||
if(!string_cmp(args, "0")) {
|
if(!string_cmp(args, "0")) {
|
||||||
NotificationApp* notification = furi_record_open("notification");
|
NotificationApp* notification = furi_record_open("notification");
|
||||||
notification_message_block(notification, &sequence_reset_vibro);
|
notification_message_block(notification, &sequence_reset_vibro);
|
||||||
@ -166,6 +178,8 @@ void cli_command_vibro(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_debug(Cli* cli, string_t args, void* context) {
|
void cli_command_debug(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(context);
|
||||||
if(!string_cmp(args, "0")) {
|
if(!string_cmp(args, "0")) {
|
||||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug);
|
furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug);
|
||||||
loader_update_menu();
|
loader_update_menu();
|
||||||
@ -180,6 +194,8 @@ void cli_command_debug(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_led(Cli* cli, string_t args, void* context) {
|
void cli_command_led(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(context);
|
||||||
// Get first word as light name
|
// Get first word as light name
|
||||||
NotificationMessage notification_led_message;
|
NotificationMessage notification_led_message;
|
||||||
string_t light_name;
|
string_t light_name;
|
||||||
@ -233,6 +249,7 @@ void cli_command_led(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_gpio_set(Cli* cli, string_t args, void* context) {
|
void cli_command_gpio_set(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
char pin_names[][4] = {
|
char pin_names[][4] = {
|
||||||
"PC0",
|
"PC0",
|
||||||
"PC1",
|
"PC1",
|
||||||
@ -313,6 +330,8 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
UNUSED(cli);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LL_GPIO_SetPinMode(gpio[num].port, gpio[num].pin, LL_GPIO_MODE_OUTPUT);
|
LL_GPIO_SetPinMode(gpio[num].port, gpio[num].pin, LL_GPIO_MODE_OUTPUT);
|
||||||
@ -325,6 +344,10 @@ void cli_command_gpio_set(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_ps(Cli* cli, string_t args, void* context) {
|
void cli_command_ps(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
const uint8_t threads_num_max = 32;
|
const uint8_t threads_num_max = 32;
|
||||||
osThreadId_t threads_id[threads_num_max];
|
osThreadId_t threads_id[threads_num_max];
|
||||||
uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max);
|
uint8_t thread_num = osThreadEnumerate(threads_id, threads_num_max);
|
||||||
@ -344,6 +367,10 @@ void cli_command_ps(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_free(Cli* cli, string_t args, void* context) {
|
void cli_command_free(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
printf("Free heap size: %d\r\n", memmgr_get_free_heap());
|
printf("Free heap size: %d\r\n", memmgr_get_free_heap());
|
||||||
printf("Total heap size: %d\r\n", memmgr_get_total_heap());
|
printf("Total heap size: %d\r\n", memmgr_get_total_heap());
|
||||||
printf("Minimum heap size: %d\r\n", memmgr_get_minimum_free_heap());
|
printf("Minimum heap size: %d\r\n", memmgr_get_minimum_free_heap());
|
||||||
@ -351,10 +378,18 @@ void cli_command_free(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_free_blocks(Cli* cli, string_t args, void* context) {
|
void cli_command_free_blocks(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
memmgr_heap_printf_free_blocks();
|
memmgr_heap_printf_free_blocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cli_command_i2c(Cli* cli, string_t args, void* context) {
|
void cli_command_i2c(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(cli);
|
||||||
|
UNUSED(args);
|
||||||
|
UNUSED(context);
|
||||||
|
|
||||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
|
furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
|
||||||
printf("Scanning external i2c on PC0(SCL)/PC1(SDA)\r\n"
|
printf("Scanning external i2c on PC0(SCL)/PC1(SDA)\r\n"
|
||||||
"Clock: 100khz, 7bit address\r\n"
|
"Clock: 100khz, 7bit address\r\n"
|
||||||
@ -391,4 +426,4 @@ void cli_commands_init(Cli* cli) {
|
|||||||
cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led, NULL);
|
cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led, NULL);
|
||||||
cli_add_command(cli, "gpio_set", CliCommandFlagDefault, cli_command_gpio_set, NULL);
|
cli_add_command(cli, "gpio_set", CliCommandFlagDefault, cli_command_gpio_set, NULL);
|
||||||
cli_add_command(cli, "i2c", CliCommandFlagDefault, cli_command_i2c, NULL);
|
cli_add_command(cli, "i2c", CliCommandFlagDefault, cli_command_i2c, NULL);
|
||||||
}
|
}
|
||||||
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
#include "cli_i.h"
|
#include "cli_i.h"
|
||||||
|
|
||||||
void cli_commands_init(Cli* cli);
|
void cli_commands_init(Cli* cli);
|
||||||
|
|||||||
@ -86,6 +86,7 @@ static void cli_vcp_deinit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int32_t vcp_worker(void* context) {
|
static int32_t vcp_worker(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
bool tx_idle = true;
|
bool tx_idle = true;
|
||||||
size_t missed_rx = 0;
|
size_t missed_rx = 0;
|
||||||
uint8_t last_tx_pkt_len = 0;
|
uint8_t last_tx_pkt_len = 0;
|
||||||
@ -148,7 +149,7 @@ static int32_t vcp_worker(void* context) {
|
|||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
furi_check(
|
furi_check(
|
||||||
xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, osWaitForever) ==
|
xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, osWaitForever) ==
|
||||||
len);
|
(size_t)len);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef CLI_VCP_DEBUG
|
#ifdef CLI_VCP_DEBUG
|
||||||
@ -275,16 +276,19 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void cli_vcp_tx_stdout(void* _cookie, const char* data, size_t size) {
|
static void cli_vcp_tx_stdout(void* _cookie, const char* data, size_t size) {
|
||||||
|
UNUSED(_cookie);
|
||||||
cli_vcp_tx((const uint8_t*)data, size);
|
cli_vcp_tx((const uint8_t*)data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_state_callback(void* context, uint8_t state) {
|
static void vcp_state_callback(void* context, uint8_t state) {
|
||||||
|
UNUSED(context);
|
||||||
if(state == 0) {
|
if(state == 0) {
|
||||||
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtDisconnect);
|
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtDisconnect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_on_cdc_control_line(void* context, uint8_t state) {
|
static void vcp_on_cdc_control_line(void* context, uint8_t state) {
|
||||||
|
UNUSED(context);
|
||||||
// bit 0: DTR state, bit 1: RTS state
|
// bit 0: DTR state, bit 1: RTS state
|
||||||
bool dtr = state & (1 << 0);
|
bool dtr = state & (1 << 0);
|
||||||
|
|
||||||
@ -296,11 +300,13 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_on_cdc_rx(void* context) {
|
static void vcp_on_cdc_rx(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
uint32_t ret = osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtRx);
|
uint32_t ret = osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtRx);
|
||||||
furi_check((ret & osFlagsError) == 0);
|
furi_check((ret & osFlagsError) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_on_cdc_tx_complete(void* context) {
|
static void vcp_on_cdc_tx_complete(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtTx);
|
osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtTx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -164,6 +164,7 @@ void crypto_cli_decrypt(Cli* cli, string_t args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void crypto_cli_has_key(Cli* cli, string_t args) {
|
void crypto_cli_has_key(Cli* cli, string_t args) {
|
||||||
|
UNUSED(cli);
|
||||||
int key_slot = 0;
|
int key_slot = 0;
|
||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
|
|
||||||
@ -185,6 +186,7 @@ void crypto_cli_has_key(Cli* cli, string_t args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void crypto_cli_store_key(Cli* cli, string_t args) {
|
void crypto_cli_store_key(Cli* cli, string_t args) {
|
||||||
|
UNUSED(cli);
|
||||||
int key_slot = 0;
|
int key_slot = 0;
|
||||||
int key_size = 0;
|
int key_size = 0;
|
||||||
string_t key_type;
|
string_t key_type;
|
||||||
@ -277,6 +279,7 @@ void crypto_cli_store_key(Cli* cli, string_t args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void crypto_cli(Cli* cli, string_t args, void* context) {
|
static void crypto_cli(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
string_t cmd;
|
string_t cmd;
|
||||||
string_init(cmd);
|
string_init(cmd);
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ static void blink_test_update(void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void blink_test_draw_callback(Canvas* canvas, void* ctx) {
|
static void blink_test_draw_callback(Canvas* canvas, void* ctx) {
|
||||||
|
UNUSED(ctx);
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
canvas_draw_str(canvas, 2, 10, "Blink application");
|
canvas_draw_str(canvas, 2, 10, "Blink application");
|
||||||
@ -41,6 +42,7 @@ static void blink_test_input_callback(InputEvent* input_event, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t blink_test_app(void* p) {
|
int32_t blink_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BlinkEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BlinkEvent), NULL);
|
||||||
|
|
||||||
// Configure view port
|
// Configure view port
|
||||||
|
|||||||
@ -70,10 +70,12 @@ static void display_test_submenu_callback(void* context, uint32_t index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t display_test_previous_callback(void* context) {
|
static uint32_t display_test_previous_callback(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return DisplayTestViewSubmenu;
|
return DisplayTestViewSubmenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t display_test_exit_callback(void* context) {
|
static uint32_t display_test_exit_callback(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return VIEW_NONE;
|
return VIEW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,6 +212,7 @@ void display_test_free(DisplayTest* instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t display_test_run(DisplayTest* instance) {
|
int32_t display_test_run(DisplayTest* instance) {
|
||||||
|
UNUSED(instance);
|
||||||
view_dispatcher_switch_to_view(instance->view_dispatcher, DisplayTestViewSubmenu);
|
view_dispatcher_switch_to_view(instance->view_dispatcher, DisplayTestViewSubmenu);
|
||||||
view_dispatcher_run(instance->view_dispatcher);
|
view_dispatcher_run(instance->view_dispatcher);
|
||||||
|
|
||||||
@ -217,6 +220,8 @@ int32_t display_test_run(DisplayTest* instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t display_test_app(void* p) {
|
int32_t display_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
|
|
||||||
DisplayTest* instance = display_test_alloc();
|
DisplayTest* instance = display_test_alloc();
|
||||||
|
|
||||||
int32_t ret = display_test_run(instance);
|
int32_t ret = display_test_run(instance);
|
||||||
|
|||||||
@ -13,6 +13,7 @@ struct ViewDisplayTest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) {
|
static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) {
|
||||||
|
UNUSED(_model);
|
||||||
canvas_draw_str(canvas, 12, 24, "Use < and > to switch tests");
|
canvas_draw_str(canvas, 12, 24, "Use < and > to switch tests");
|
||||||
canvas_draw_str(canvas, 12, 36, "Use ^ and v to switch size");
|
canvas_draw_str(canvas, 12, 36, "Use ^ and v to switch size");
|
||||||
canvas_draw_str(canvas, 32, 48, "Use (o) to flip");
|
canvas_draw_str(canvas, 32, 48, "Use (o) to flip");
|
||||||
|
|||||||
@ -60,6 +60,7 @@ static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t keypad_test_app(void* p) {
|
int32_t keypad_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
|
||||||
furi_check(event_queue);
|
furi_check(event_queue);
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,7 @@ static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t text_box_test_app(void* p) {
|
int32_t text_box_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL);
|
||||||
furi_check(event_queue);
|
furi_check(event_queue);
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ int32_t text_box_test_app(void* p) {
|
|||||||
Gui* gui = furi_record_open("gui");
|
Gui* gui = furi_record_open("gui");
|
||||||
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
|
||||||
|
|
||||||
uint32_t test_renders_num = SIZEOF_ARRAY(text_box_test_render);
|
uint32_t test_renders_num = COUNT_OF(text_box_test_render);
|
||||||
InputEvent event;
|
InputEvent event;
|
||||||
while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
|
while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
|
||||||
TextBoxTestState* state = acquire_mutex_block(&state_mutex);
|
TextBoxTestState* state = acquire_mutex_block(&state_mutex);
|
||||||
|
|||||||
@ -80,11 +80,13 @@ static void uart_echo_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool uart_echo_view_input_callback(InputEvent* event, void* context) {
|
static bool uart_echo_view_input_callback(InputEvent* event, void* context) {
|
||||||
bool consumed = false;
|
UNUSED(event);
|
||||||
return consumed;
|
UNUSED(context);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t uart_echo_exit(void* context) {
|
static uint32_t uart_echo_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return VIEW_NONE;
|
return VIEW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +172,10 @@ static int32_t uart_echo_worker(void* context) {
|
|||||||
|
|
||||||
notification_message(app->notification, &sequence_notification);
|
notification_message(app->notification, &sequence_notification);
|
||||||
with_view_model(
|
with_view_model(
|
||||||
app->view, (UartDumpModel * model) { return true; });
|
app->view, (UartDumpModel * model) {
|
||||||
|
UNUSED(model);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +266,7 @@ static void uart_echo_app_free(UartEchoApp* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t uart_echo_app(void* p) {
|
int32_t uart_echo_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
UartEchoApp* app = uart_echo_app_alloc();
|
UartEchoApp* app = uart_echo_app_alloc();
|
||||||
view_dispatcher_run(app->view_dispatcher);
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
uart_echo_app_free(app);
|
uart_echo_app_free(app);
|
||||||
|
|||||||
@ -18,6 +18,7 @@ typedef struct {
|
|||||||
} UsbMouseEvent;
|
} UsbMouseEvent;
|
||||||
|
|
||||||
static void usb_mouse_render_callback(Canvas* canvas, void* ctx) {
|
static void usb_mouse_render_callback(Canvas* canvas, void* ctx) {
|
||||||
|
UNUSED(ctx);
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
|
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
@ -37,6 +38,7 @@ static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t usb_mouse_app(void* p) {
|
int32_t usb_mouse_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(UsbMouseEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(UsbMouseEvent), NULL);
|
||||||
furi_check(event_queue);
|
furi_check(event_queue);
|
||||||
ViewPort* view_port = view_port_alloc();
|
ViewPort* view_port = view_port_alloc();
|
||||||
|
|||||||
@ -51,6 +51,7 @@ void usb_test_submenu_callback(void* context, uint32_t index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t usb_test_exit(void* context) {
|
uint32_t usb_test_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
return VIEW_NONE;
|
return VIEW_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ void usb_test_app_free(UsbTestApp* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t usb_test_app(void* p) {
|
int32_t usb_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
UsbTestApp* app = usb_test_app_alloc();
|
UsbTestApp* app = usb_test_app_alloc();
|
||||||
|
|
||||||
view_dispatcher_run(app->view_dispatcher);
|
view_dispatcher_run(app->view_dispatcher);
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
|
|
||||||
void vibro_test_draw_callback(Canvas* canvas, void* ctx) {
|
void vibro_test_draw_callback(Canvas* canvas, void* ctx) {
|
||||||
|
UNUSED(ctx);
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
canvas_draw_str(canvas, 2, 10, "Vibro application");
|
canvas_draw_str(canvas, 2, 10, "Vibro application");
|
||||||
@ -22,6 +23,7 @@ void vibro_test_input_callback(InputEvent* input_event, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t vibro_test_app(void* p) {
|
int32_t vibro_test_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL);
|
||||||
|
|
||||||
// Configure view port
|
// Configure view port
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include <gui/view_stack.h>
|
#include <gui/view_stack.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
#include <furi_hal.h>
|
||||||
#include <m-string.h>
|
#include <m-string.h>
|
||||||
#include <portmacro.h>
|
#include <portmacro.h>
|
||||||
#include <dolphin/dolphin.h>
|
#include <dolphin/dolphin.h>
|
||||||
@ -364,6 +365,7 @@ static bool animation_manager_is_valid_idle_animation(
|
|||||||
|
|
||||||
static StorageAnimation*
|
static StorageAnimation*
|
||||||
animation_manager_select_idle_animation(AnimationManager* animation_manager) {
|
animation_manager_select_idle_animation(AnimationManager* animation_manager) {
|
||||||
|
UNUSED(animation_manager);
|
||||||
StorageAnimationList_t animation_list;
|
StorageAnimationList_t animation_list;
|
||||||
StorageAnimationList_init(animation_list);
|
StorageAnimationList_init(animation_list);
|
||||||
animation_storage_fill_animation_list(&animation_list);
|
animation_storage_fill_animation_list(&animation_list);
|
||||||
@ -390,7 +392,7 @@ static StorageAnimation*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t lucky_number = random() % whole_weight;
|
uint32_t lucky_number = furi_hal_random_get() % whole_weight;
|
||||||
uint32_t weight = 0;
|
uint32_t weight = 0;
|
||||||
|
|
||||||
StorageAnimation* selected = NULL;
|
StorageAnimation* selected = NULL;
|
||||||
|
|||||||
@ -130,7 +130,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis
|
|||||||
flipper_format_free(file);
|
flipper_format_free(file);
|
||||||
|
|
||||||
// add hard-coded animations
|
// add hard-coded animations
|
||||||
for(int i = 0; i < dolphin_internal_size; ++i) {
|
for(size_t i = 0; i < dolphin_internal_size; ++i) {
|
||||||
StorageAnimationList_push_back(*animation_list, (StorageAnimation*)&dolphin_internal[i]);
|
StorageAnimationList_push_back(*animation_list, (StorageAnimation*)&dolphin_internal[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ StorageAnimation* animation_storage_find_animation(const char* name) {
|
|||||||
furi_assert(strlen(name));
|
furi_assert(strlen(name));
|
||||||
StorageAnimation* storage_animation = NULL;
|
StorageAnimation* storage_animation = NULL;
|
||||||
|
|
||||||
for(int i = 0; i < dolphin_blocking_size; ++i) {
|
for(size_t i = 0; i < dolphin_blocking_size; ++i) {
|
||||||
if(!strcmp(dolphin_blocking[i].manifest_info.name, name)) {
|
if(!strcmp(dolphin_blocking[i].manifest_info.name, name)) {
|
||||||
storage_animation = (StorageAnimation*)&dolphin_blocking[i];
|
storage_animation = (StorageAnimation*)&dolphin_blocking[i];
|
||||||
break;
|
break;
|
||||||
@ -150,7 +150,7 @@ StorageAnimation* animation_storage_find_animation(const char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!storage_animation) {
|
if(!storage_animation) {
|
||||||
for(int i = 0; i < dolphin_internal_size; ++i) {
|
for(size_t i = 0; i < dolphin_internal_size; ++i) {
|
||||||
if(!strcmp(dolphin_internal[i].manifest_info.name, name)) {
|
if(!strcmp(dolphin_internal[i].manifest_info.name, name)) {
|
||||||
storage_animation = (StorageAnimation*)&dolphin_internal[i];
|
storage_animation = (StorageAnimation*)&dolphin_internal[i];
|
||||||
break;
|
break;
|
||||||
@ -365,7 +365,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo
|
|||||||
animation->frame_bubble_sequences =
|
animation->frame_bubble_sequences =
|
||||||
malloc(sizeof(FrameBubble*) * animation->frame_bubble_sequences_count);
|
malloc(sizeof(FrameBubble*) * animation->frame_bubble_sequences_count);
|
||||||
|
|
||||||
uint32_t current_slot = 0;
|
int32_t current_slot = 0;
|
||||||
for(int i = 0; i < animation->frame_bubble_sequences_count; ++i) {
|
for(int i = 0; i < animation->frame_bubble_sequences_count; ++i) {
|
||||||
FURI_CONST_ASSIGN_PTR(
|
FURI_CONST_ASSIGN_PTR(
|
||||||
animation->frame_bubble_sequences[i], malloc(sizeof(FrameBubble)));
|
animation->frame_bubble_sequences[i], malloc(sizeof(FrameBubble)));
|
||||||
@ -374,7 +374,7 @@ static bool animation_storage_load_bubbles(BubbleAnimation* animation, FlipperFo
|
|||||||
const FrameBubble* bubble = animation->frame_bubble_sequences[0];
|
const FrameBubble* bubble = animation->frame_bubble_sequences[0];
|
||||||
int8_t index = -1;
|
int8_t index = -1;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(!flipper_format_read_uint32(ff, "Slot", ¤t_slot, 1)) break;
|
if(!flipper_format_read_int32(ff, "Slot", ¤t_slot, 1)) break;
|
||||||
if((current_slot != 0) && (index == -1)) break;
|
if((current_slot != 0) && (index == -1)) break;
|
||||||
|
|
||||||
if(current_slot == index) {
|
if(current_slot == index) {
|
||||||
|
|||||||
@ -100,7 +100,8 @@ static const FrameBubble*
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t index = random() % (active ? model->active_bubbles : model->passive_bubbles);
|
uint8_t index =
|
||||||
|
furi_hal_random_get() % (active ? model->active_bubbles : model->passive_bubbles);
|
||||||
const BubbleAnimation* animation = model->current;
|
const BubbleAnimation* animation = model->current;
|
||||||
|
|
||||||
for(int i = 0; i < animation->frame_bubble_sequences_count; ++i) {
|
for(int i = 0; i < animation->frame_bubble_sequences_count; ++i) {
|
||||||
|
|||||||
@ -33,6 +33,7 @@ static void desktop_loader_callback(const void* message, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void desktop_lock_icon_callback(Canvas* canvas, void* context) {
|
static void desktop_lock_icon_callback(Canvas* canvas, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
canvas_draw_icon(canvas, 0, 0, &I_Lock_8x8);
|
canvas_draw_icon(canvas, 0, 0, &I_Lock_8x8);
|
||||||
}
|
}
|
||||||
@ -298,6 +299,7 @@ static bool desktop_is_first_start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t desktop_srv(void* p) {
|
int32_t desktop_srv(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
Desktop* desktop = desktop_alloc();
|
Desktop* desktop = desktop_alloc();
|
||||||
|
|
||||||
bool loaded = LOAD_DESKTOP_SETTINGS(&desktop->settings);
|
bool loaded = LOAD_DESKTOP_SETTINGS(&desktop->settings);
|
||||||
|
|||||||
@ -53,4 +53,5 @@ bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEven
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_settings_scene_pin_disable_on_exit(void* context) {
|
void desktop_settings_scene_pin_disable_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ static void pin_error_back_callback(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void pin_error_done_callback(const PinCode* pin_code, void* context) {
|
static void pin_error_done_callback(const PinCode* pin_code, void* context) {
|
||||||
|
UNUSED(pin_code);
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
DesktopSettingsApp* app = context;
|
DesktopSettingsApp* app = context;
|
||||||
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
|
view_dispatcher_send_custom_event(app->view_dispatcher, SCENE_EVENT_EXIT);
|
||||||
|
|||||||
@ -41,4 +41,5 @@ bool desktop_settings_scene_pin_setup_howto_on_event(void* context, SceneManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_settings_scene_pin_setup_howto_on_exit(void* context) {
|
void desktop_settings_scene_pin_setup_howto_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,5 +47,6 @@ bool desktop_scene_fault_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_scene_fault_on_exit(void* context) {
|
void desktop_scene_fault_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
furi_hal_rtc_set_fault_data(0);
|
furi_hal_rtc_set_fault_data(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,4 +50,5 @@ bool desktop_scene_first_start_on_event(void* context, SceneManagerEvent event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_scene_first_start_on_exit(void* context) {
|
void desktop_scene_first_start_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,4 +81,5 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_scene_lock_menu_on_exit(void* context) {
|
void desktop_scene_lock_menu_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,4 +109,5 @@ bool desktop_scene_locked_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_scene_locked_on_exit(void* context) {
|
void desktop_scene_locked_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,4 +43,5 @@ bool desktop_scene_pin_timeout_on_event(void* context, SceneManagerEvent event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void desktop_scene_pin_timeout_on_exit(void* context) {
|
void desktop_scene_pin_timeout_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,8 @@ static void desktop_view_pin_timeout_timer_callback(TimerHandle_t timer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool desktop_view_pin_timeout_input(InputEvent* event, void* context) {
|
static bool desktop_view_pin_timeout_input(InputEvent* event, void* context) {
|
||||||
|
UNUSED(event);
|
||||||
|
UNUSED(context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ static DialogsApp* dialogs_app_alloc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* message) {
|
static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* message) {
|
||||||
|
UNUSED(app);
|
||||||
switch(message->command) {
|
switch(message->command) {
|
||||||
case DialogsAppCommandFileOpen:
|
case DialogsAppCommandFileOpen:
|
||||||
message->return_data->bool_value =
|
message->return_data->bool_value =
|
||||||
@ -25,6 +26,7 @@ static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* mess
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t dialogs_srv(void* p) {
|
int32_t dialogs_srv(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
DialogsApp* app = dialogs_app_alloc();
|
DialogsApp* app = dialogs_app_alloc();
|
||||||
furi_record_create("dialogs", app);
|
furi_record_create("dialogs", app);
|
||||||
|
|
||||||
|
|||||||
@ -132,4 +132,4 @@ void dialog_message_show_storage_error(DialogsApp* context, const char* error_te
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -70,4 +70,4 @@ void dialog_message_show_storage_error(DialogsApp* context, const char* error_te
|
|||||||
dialog_message_set_buttons(message, "Back", NULL, NULL);
|
dialog_message_set_buttons(message, "Back", NULL, NULL);
|
||||||
dialog_message_show(context, message);
|
dialog_message_show(context, message);
|
||||||
dialog_message_free(message);
|
dialog_message_free(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,4 +12,4 @@ struct DialogsApp {
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -43,4 +43,4 @@ typedef struct {
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -9,4 +9,4 @@ bool dialogs_app_process_module_file_select(const DialogsAppMessageDataFileSelec
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -9,4 +9,4 @@ DialogMessageButton dialogs_app_process_module_message(const DialogsAppMessageDa
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -95,4 +95,4 @@ void view_holder_update(View* view, void* context);
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -118,6 +118,7 @@ void dolphin_event_send_wait(Dolphin* dolphin, DolphinEvent* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dolphin_event_release(Dolphin* dolphin, DolphinEvent* event) {
|
void dolphin_event_release(Dolphin* dolphin, DolphinEvent* event) {
|
||||||
|
UNUSED(dolphin);
|
||||||
if(event->flag) {
|
if(event->flag) {
|
||||||
osEventFlagsSet(event->flag, DOLPHIN_LOCK_EVENT_FLAG);
|
osEventFlagsSet(event->flag, DOLPHIN_LOCK_EVENT_FLAG);
|
||||||
}
|
}
|
||||||
@ -149,6 +150,7 @@ static void dolphin_update_clear_limits_timer_period(Dolphin* dolphin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t dolphin_srv(void* p) {
|
int32_t dolphin_srv(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
Dolphin* dolphin = dolphin_alloc();
|
Dolphin* dolphin = dolphin_alloc();
|
||||||
furi_record_create("dolphin", dolphin);
|
furi_record_create("dolphin", dolphin);
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ typedef struct {
|
|||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t icounter;
|
uint32_t icounter;
|
||||||
uint32_t butthurt;
|
int32_t butthurt;
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
} DolphinStoreData;
|
} DolphinStoreData;
|
||||||
|
|
||||||
|
|||||||
@ -90,6 +90,7 @@ static void render_callback(Canvas* canvas, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t passport_app(void* p) {
|
int32_t passport_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL);
|
osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL);
|
||||||
furi_assert(semaphore);
|
furi_assert(semaphore);
|
||||||
|
|
||||||
|
|||||||
@ -95,6 +95,7 @@ void gpio_app_free(GpioApp* app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t gpio_app(void* p) {
|
int32_t gpio_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
GpioApp* gpio_app = gpio_app_alloc();
|
GpioApp* gpio_app = gpio_app_alloc();
|
||||||
|
|
||||||
view_dispatcher_run(gpio_app->view_dispatcher);
|
view_dispatcher_run(gpio_app->view_dispatcher);
|
||||||
|
|||||||
@ -19,9 +19,12 @@ void gpio_scene_test_on_enter(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool gpio_scene_test_on_event(void* context, SceneManagerEvent event) {
|
bool gpio_scene_test_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
UNUSED(context);
|
||||||
|
UNUSED(event);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_scene_test_on_exit(void* context) {
|
void gpio_scene_test_on_exit(void* context) {
|
||||||
|
UNUSED(context);
|
||||||
gpio_item_configure_all_pins(GpioModeAnalog);
|
gpio_item_configure_all_pins(GpioModeAnalog);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,12 +28,9 @@ static const uint32_t baudrate_list[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) {
|
bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) {
|
||||||
//GpioApp* app = context;
|
UNUSED(context);
|
||||||
bool consumed = false;
|
UNUSED(event);
|
||||||
|
return false;
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
|
||||||
}
|
|
||||||
return consumed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void line_vcp_cb(VariableItem* item) {
|
static void line_vcp_cb(VariableItem* item) {
|
||||||
|
|||||||
@ -101,6 +101,7 @@ static void usb_uart_vcp_init(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
|
static void usb_uart_vcp_deinit(UsbUartBridge* usb_uart, uint8_t vcp_ch) {
|
||||||
|
UNUSED(usb_uart);
|
||||||
furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL);
|
furi_hal_cdc_set_callbacks(vcp_ch, NULL, NULL);
|
||||||
FURI_LOG_I("", "Deinit %d", vcp_ch);
|
FURI_LOG_I("", "Deinit %d", vcp_ch);
|
||||||
if(vcp_ch != 0) {
|
if(vcp_ch != 0) {
|
||||||
@ -120,6 +121,7 @@ static void usb_uart_serial_init(UsbUartBridge* usb_uart, uint8_t uart_ch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void usb_uart_serial_deinit(UsbUartBridge* usb_uart, uint8_t uart_ch) {
|
static void usb_uart_serial_deinit(UsbUartBridge* usb_uart, uint8_t uart_ch) {
|
||||||
|
UNUSED(usb_uart);
|
||||||
furi_hal_uart_set_irq_cb(uart_ch, NULL, NULL);
|
furi_hal_uart_set_irq_cb(uart_ch, NULL, NULL);
|
||||||
if(uart_ch == FuriHalUartIdUSART1)
|
if(uart_ch == FuriHalUartIdUSART1)
|
||||||
furi_hal_console_enable();
|
furi_hal_console_enable();
|
||||||
@ -143,7 +145,7 @@ static void usb_uart_set_baudrate(UsbUartBridge* usb_uart, uint32_t baudrate) {
|
|||||||
|
|
||||||
static void usb_uart_update_ctrl_lines(UsbUartBridge* usb_uart) {
|
static void usb_uart_update_ctrl_lines(UsbUartBridge* usb_uart) {
|
||||||
if(usb_uart->cfg.flow_pins != 0) {
|
if(usb_uart->cfg.flow_pins != 0) {
|
||||||
furi_assert((usb_uart->cfg.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0])));
|
furi_assert((size_t)(usb_uart->cfg.flow_pins - 1) < COUNT_OF(flow_pins));
|
||||||
uint8_t state = furi_hal_cdc_get_ctrl_line_state(usb_uart->cfg.vcp_ch);
|
uint8_t state = furi_hal_cdc_get_ctrl_line_state(usb_uart->cfg.vcp_ch);
|
||||||
|
|
||||||
furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][0], !(state & USB_CDC_BIT_RTS));
|
furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][0], !(state & USB_CDC_BIT_RTS));
|
||||||
@ -171,7 +173,7 @@ static int32_t usb_uart_worker(void* context) {
|
|||||||
usb_uart_serial_init(usb_uart, usb_uart->cfg.uart_ch);
|
usb_uart_serial_init(usb_uart, usb_uart->cfg.uart_ch);
|
||||||
usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate);
|
usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate);
|
||||||
if(usb_uart->cfg.flow_pins != 0) {
|
if(usb_uart->cfg.flow_pins != 0) {
|
||||||
furi_assert((usb_uart->cfg.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0])));
|
furi_assert((size_t)(usb_uart->cfg.flow_pins - 1) < COUNT_OF(flow_pins));
|
||||||
furi_hal_gpio_init_simple(
|
furi_hal_gpio_init_simple(
|
||||||
flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeOutputPushPull);
|
flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeOutputPushPull);
|
||||||
furi_hal_gpio_init_simple(
|
furi_hal_gpio_init_simple(
|
||||||
@ -238,9 +240,7 @@ static int32_t usb_uart_worker(void* context) {
|
|||||||
flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog);
|
flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog);
|
||||||
}
|
}
|
||||||
if(usb_uart->cfg_new.flow_pins != 0) {
|
if(usb_uart->cfg_new.flow_pins != 0) {
|
||||||
furi_assert(
|
furi_assert((size_t)(usb_uart->cfg_new.flow_pins - 1) < COUNT_OF(flow_pins));
|
||||||
(usb_uart->cfg_new.flow_pins - 1) <
|
|
||||||
(sizeof(flow_pins) / sizeof(flow_pins[0])));
|
|
||||||
furi_hal_gpio_init_simple(
|
furi_hal_gpio_init_simple(
|
||||||
flow_pins[usb_uart->cfg_new.flow_pins - 1][0], GpioModeOutputPushPull);
|
flow_pins[usb_uart->cfg_new.flow_pins - 1][0], GpioModeOutputPushPull);
|
||||||
furi_hal_gpio_init_simple(
|
furi_hal_gpio_init_simple(
|
||||||
@ -318,14 +318,18 @@ static void vcp_on_cdc_rx(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_state_callback(void* context, uint8_t state) {
|
static void vcp_state_callback(void* context, uint8_t state) {
|
||||||
|
UNUSED(context);
|
||||||
|
UNUSED(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_on_cdc_control_line(void* context, uint8_t state) {
|
static void vcp_on_cdc_control_line(void* context, uint8_t state) {
|
||||||
|
UNUSED(state);
|
||||||
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
|
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
|
||||||
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtCtrlLineSet);
|
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtCtrlLineSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) {
|
static void vcp_on_line_config(void* context, struct usb_cdc_line_coding* config) {
|
||||||
|
UNUSED(config);
|
||||||
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
|
UsbUartBridge* usb_uart = (UsbUartBridge*)context;
|
||||||
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtLineCfgSet);
|
osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->thread), WorkerEvtLineCfgSet);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,6 +123,7 @@ void gpio_test_set_ok_callback(GpioTest* gpio_test, GpioTestOkCallback callback,
|
|||||||
furi_assert(callback);
|
furi_assert(callback);
|
||||||
with_view_model(
|
with_view_model(
|
||||||
gpio_test->view, (GpioTestModel * model) {
|
gpio_test->view, (GpioTestModel * model) {
|
||||||
|
UNUSED(model);
|
||||||
gpio_test->callback = callback;
|
gpio_test->callback = callback;
|
||||||
gpio_test->context = context;
|
gpio_test->context = context;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -130,6 +130,7 @@ void gpio_usb_uart_set_callback(GpioUsbUart* usb_uart, GpioUsbUartCallback callb
|
|||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
usb_uart->view, (GpioUsbUartModel * model) {
|
usb_uart->view, (GpioUsbUartModel * model) {
|
||||||
|
UNUSED(model);
|
||||||
usb_uart->callback = callback;
|
usb_uart->callback = callback;
|
||||||
usb_uart->context = context;
|
usb_uart->context = context;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -47,10 +47,9 @@ bool gui_redraw_fs(Gui* gui) {
|
|||||||
|
|
||||||
static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
|
static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
|
||||||
ViewPortArray_it_t it;
|
ViewPortArray_it_t it;
|
||||||
uint8_t x;
|
uint8_t left_used = 0;
|
||||||
uint8_t x_used = 0;
|
uint8_t right_used = 0;
|
||||||
uint8_t width;
|
uint8_t width;
|
||||||
ViewPort* view_port;
|
|
||||||
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
|
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
|
||||||
canvas_frame_set(
|
canvas_frame_set(
|
||||||
gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
|
gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
|
||||||
@ -69,100 +68,126 @@ static void gui_redraw_status_bar(Gui* gui, bool need_attention) {
|
|||||||
canvas_set_bitmap_mode(gui->canvas, 0);
|
canvas_set_bitmap_mode(gui->canvas, 0);
|
||||||
|
|
||||||
// Right side
|
// Right side
|
||||||
x = GUI_DISPLAY_WIDTH;
|
uint8_t x = GUI_DISPLAY_WIDTH - 1;
|
||||||
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]);
|
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]);
|
||||||
while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) {
|
while(!ViewPortArray_end_p(it) && right_used < GUI_STATUS_BAR_WIDTH) {
|
||||||
// Render view_port;
|
ViewPort* view_port = *ViewPortArray_ref(it);
|
||||||
view_port = *ViewPortArray_ref(it);
|
|
||||||
if(view_port_is_enabled(view_port)) {
|
if(view_port_is_enabled(view_port)) {
|
||||||
width = view_port_get_width(view_port);
|
width = view_port_get_width(view_port);
|
||||||
if(!width) width = 8;
|
if(!width) width = 8;
|
||||||
x_used += width;
|
// Recalculate next position
|
||||||
|
right_used += (width + 2);
|
||||||
x -= (width + 2);
|
x -= (width + 2);
|
||||||
|
// Prepare work area background
|
||||||
canvas_frame_set(
|
canvas_frame_set(
|
||||||
gui->canvas, x - 3, GUI_STATUS_BAR_Y, width + 5, GUI_STATUS_BAR_HEIGHT);
|
|
||||||
|
|
||||||
canvas_set_color(gui->canvas, ColorWhite);
|
|
||||||
canvas_draw_box(gui->canvas, 2, 1, width + 2, 10);
|
|
||||||
canvas_set_color(gui->canvas, ColorBlack);
|
|
||||||
|
|
||||||
canvas_draw_rframe(
|
|
||||||
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
|
|
||||||
canvas_draw_line(gui->canvas, 1, 1, 1, canvas_height(gui->canvas) - 2);
|
|
||||||
canvas_draw_line(
|
|
||||||
gui->canvas,
|
gui->canvas,
|
||||||
2,
|
x - 1,
|
||||||
canvas_height(gui->canvas) - 2,
|
GUI_STATUS_BAR_Y + 1,
|
||||||
canvas_width(gui->canvas) - 2,
|
width + 2,
|
||||||
canvas_height(gui->canvas) - 2);
|
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
|
||||||
|
canvas_set_color(gui->canvas, ColorWhite);
|
||||||
|
canvas_draw_box(
|
||||||
|
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
|
||||||
|
canvas_set_color(gui->canvas, ColorBlack);
|
||||||
|
// ViewPort draw
|
||||||
canvas_frame_set(
|
canvas_frame_set(
|
||||||
gui->canvas, x, GUI_STATUS_BAR_Y + 1, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
|
gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
|
||||||
|
|
||||||
view_port_draw(view_port, gui->canvas);
|
view_port_draw(view_port, gui->canvas);
|
||||||
}
|
}
|
||||||
ViewPortArray_next(it);
|
ViewPortArray_next(it);
|
||||||
}
|
}
|
||||||
|
// Draw frame around icons on the right
|
||||||
|
if(right_used) {
|
||||||
|
canvas_frame_set(
|
||||||
|
gui->canvas,
|
||||||
|
GUI_DISPLAY_WIDTH - 3 - right_used,
|
||||||
|
GUI_STATUS_BAR_Y,
|
||||||
|
right_used + 3,
|
||||||
|
GUI_STATUS_BAR_HEIGHT);
|
||||||
|
canvas_set_color(gui->canvas, ColorBlack);
|
||||||
|
canvas_draw_rframe(
|
||||||
|
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
|
||||||
|
canvas_draw_line(
|
||||||
|
gui->canvas,
|
||||||
|
canvas_width(gui->canvas) - 2,
|
||||||
|
1,
|
||||||
|
canvas_width(gui->canvas) - 2,
|
||||||
|
canvas_height(gui->canvas) - 2);
|
||||||
|
canvas_draw_line(
|
||||||
|
gui->canvas,
|
||||||
|
1,
|
||||||
|
canvas_height(gui->canvas) - 2,
|
||||||
|
canvas_width(gui->canvas) - 2,
|
||||||
|
canvas_height(gui->canvas) - 2);
|
||||||
|
}
|
||||||
|
|
||||||
// Left side
|
// Left side
|
||||||
x = 0;
|
x = 2;
|
||||||
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]);
|
ViewPortArray_it(it, gui->layers[GuiLayerStatusBarLeft]);
|
||||||
while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) {
|
while(!ViewPortArray_end_p(it) && (right_used + left_used) < GUI_STATUS_BAR_WIDTH) {
|
||||||
// Render view_port;
|
ViewPort* view_port = *ViewPortArray_ref(it);
|
||||||
view_port = *ViewPortArray_ref(it);
|
|
||||||
if(view_port_is_enabled(view_port)) {
|
if(view_port_is_enabled(view_port)) {
|
||||||
width = view_port_get_width(view_port);
|
width = view_port_get_width(view_port);
|
||||||
if(!width) width = 8;
|
if(!width) width = 8;
|
||||||
x_used += width;
|
// Prepare work area background
|
||||||
|
|
||||||
canvas_frame_set(
|
canvas_frame_set(
|
||||||
gui->canvas, 0, GUI_STATUS_BAR_Y, x + width + 5, GUI_STATUS_BAR_HEIGHT);
|
|
||||||
canvas_draw_rframe(
|
|
||||||
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
|
|
||||||
canvas_draw_line(gui->canvas, 1, 1, 1, canvas_height(gui->canvas) - 2);
|
|
||||||
canvas_draw_line(
|
|
||||||
gui->canvas,
|
gui->canvas,
|
||||||
2,
|
x - 1,
|
||||||
canvas_height(gui->canvas) - 2,
|
GUI_STATUS_BAR_Y + 1,
|
||||||
canvas_width(gui->canvas) - 2,
|
width + 2,
|
||||||
canvas_height(gui->canvas) - 2);
|
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
|
||||||
|
|
||||||
canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width + 5, GUI_STATUS_BAR_HEIGHT);
|
|
||||||
|
|
||||||
canvas_set_color(gui->canvas, ColorWhite);
|
canvas_set_color(gui->canvas, ColorWhite);
|
||||||
canvas_draw_box(gui->canvas, 2, 1, width + 2, 10);
|
canvas_draw_box(
|
||||||
|
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
|
||||||
canvas_set_color(gui->canvas, ColorBlack);
|
canvas_set_color(gui->canvas, ColorBlack);
|
||||||
|
// ViewPort draw
|
||||||
canvas_frame_set(
|
canvas_frame_set(
|
||||||
gui->canvas, x + 3, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
|
gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
|
||||||
view_port_draw(view_port, gui->canvas);
|
view_port_draw(view_port, gui->canvas);
|
||||||
|
// Recalculate next position
|
||||||
|
left_used += (width + 2);
|
||||||
x += (width + 2);
|
x += (width + 2);
|
||||||
}
|
}
|
||||||
ViewPortArray_next(it);
|
ViewPortArray_next(it);
|
||||||
}
|
}
|
||||||
|
// Extra notification
|
||||||
if(need_attention) {
|
if(need_attention) {
|
||||||
width = icon_get_width(&I_Attention_5x8);
|
width = icon_get_width(&I_Attention_5x8);
|
||||||
canvas_frame_set(gui->canvas, 0, GUI_STATUS_BAR_Y, x + width + 5, GUI_STATUS_BAR_HEIGHT);
|
// Prepare work area background
|
||||||
|
canvas_frame_set(
|
||||||
|
gui->canvas,
|
||||||
|
x - 1,
|
||||||
|
GUI_STATUS_BAR_Y + 1,
|
||||||
|
width + 2,
|
||||||
|
GUI_STATUS_BAR_WORKAREA_HEIGHT + 2);
|
||||||
|
canvas_set_color(gui->canvas, ColorWhite);
|
||||||
|
canvas_draw_box(gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas));
|
||||||
|
canvas_set_color(gui->canvas, ColorBlack);
|
||||||
|
// Draw Icon
|
||||||
|
canvas_frame_set(
|
||||||
|
gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
|
||||||
|
canvas_draw_icon(gui->canvas, 0, 0, &I_Attention_5x8);
|
||||||
|
// Recalculate next position
|
||||||
|
left_used += (width + 2);
|
||||||
|
x += (width + 2);
|
||||||
|
}
|
||||||
|
// Draw frame around icons on the left
|
||||||
|
if(left_used) {
|
||||||
|
canvas_frame_set(gui->canvas, 0, 0, left_used + 3, GUI_STATUS_BAR_HEIGHT);
|
||||||
canvas_draw_rframe(
|
canvas_draw_rframe(
|
||||||
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
|
gui->canvas, 0, 0, canvas_width(gui->canvas), canvas_height(gui->canvas), 1);
|
||||||
canvas_draw_line(gui->canvas, 1, 1, 1, canvas_height(gui->canvas) - 2);
|
|
||||||
canvas_draw_line(
|
canvas_draw_line(
|
||||||
gui->canvas,
|
gui->canvas,
|
||||||
2,
|
canvas_width(gui->canvas) - 2,
|
||||||
|
1,
|
||||||
|
canvas_width(gui->canvas) - 2,
|
||||||
|
canvas_height(gui->canvas) - 2);
|
||||||
|
canvas_draw_line(
|
||||||
|
gui->canvas,
|
||||||
|
1,
|
||||||
canvas_height(gui->canvas) - 2,
|
canvas_height(gui->canvas) - 2,
|
||||||
canvas_width(gui->canvas) - 2,
|
canvas_width(gui->canvas) - 2,
|
||||||
canvas_height(gui->canvas) - 2);
|
canvas_height(gui->canvas) - 2);
|
||||||
|
|
||||||
canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width + 5, GUI_STATUS_BAR_HEIGHT);
|
|
||||||
|
|
||||||
canvas_set_color(gui->canvas, ColorWhite);
|
|
||||||
canvas_draw_box(gui->canvas, 2, 1, width + 2, 10);
|
|
||||||
canvas_set_color(gui->canvas, ColorBlack);
|
|
||||||
|
|
||||||
canvas_frame_set(
|
|
||||||
gui->canvas, x + 3, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_WORKAREA_HEIGHT);
|
|
||||||
canvas_draw_icon(gui->canvas, 0, 0, &I_Attention_5x8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,6 +494,7 @@ Gui* gui_alloc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t gui_srv(void* p) {
|
int32_t gui_srv(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
Gui* gui = gui_alloc();
|
Gui* gui = gui_alloc();
|
||||||
|
|
||||||
furi_record_create("gui", gui);
|
furi_record_create("gui", gui);
|
||||||
|
|||||||
@ -10,4 +10,4 @@ uint8_t icon_get_height(const Icon* instance) {
|
|||||||
|
|
||||||
const uint8_t* icon_get_data(const Icon* instance) {
|
const uint8_t* icon_get_data(const Icon* instance) {
|
||||||
return instance->frames[0];
|
return instance->frames[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,4 +39,4 @@ const uint8_t* icon_get_data(const Icon* instance);
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -331,7 +331,7 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) {
|
|||||||
ButtonMenuItemArray_it_t it;
|
ButtonMenuItemArray_it_t it;
|
||||||
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
||||||
ButtonMenuItemArray_next(it), ++item_position) {
|
ButtonMenuItemArray_next(it), ++item_position) {
|
||||||
if(ButtonMenuItemArray_cref(it)->index == index) {
|
if((uint32_t)ButtonMenuItemArray_cref(it)->index == index) {
|
||||||
model->position = item_position;
|
model->position = item_position;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,8 +215,8 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
static void button_panel_process_down(ButtonPanel* button_panel) {
|
static void button_panel_process_down(ButtonPanel* button_panel) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
button_panel->view, (ButtonPanelModel * model) {
|
button_panel->view, (ButtonPanelModel * model) {
|
||||||
size_t new_selected_item_x = model->selected_item_x;
|
uint16_t new_selected_item_x = model->selected_item_x;
|
||||||
size_t new_selected_item_y = model->selected_item_y;
|
uint16_t new_selected_item_y = model->selected_item_y;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if(new_selected_item_y >= (model->reserve_y - 1)) return false;
|
if(new_selected_item_y >= (model->reserve_y - 1)) return false;
|
||||||
@ -291,8 +291,8 @@ static void button_panel_process_left(ButtonPanel* button_panel) {
|
|||||||
static void button_panel_process_right(ButtonPanel* button_panel) {
|
static void button_panel_process_right(ButtonPanel* button_panel) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
button_panel->view, (ButtonPanelModel * model) {
|
button_panel->view, (ButtonPanelModel * model) {
|
||||||
size_t new_selected_item_x = model->selected_item_x;
|
uint16_t new_selected_item_x = model->selected_item_x;
|
||||||
size_t new_selected_item_y = model->selected_item_y;
|
uint16_t new_selected_item_y = model->selected_item_y;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if(new_selected_item_x >= (model->reserve_x - 1)) return false;
|
if(new_selected_item_x >= (model->reserve_x - 1)) return false;
|
||||||
|
|||||||
@ -66,4 +66,4 @@ void byte_input_set_header_text(ByteInput* byte_input, const char* text);
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,10 +6,13 @@ struct EmptyScreen {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void empty_screen_view_draw_callback(Canvas* canvas, void* _model) {
|
static void empty_screen_view_draw_callback(Canvas* canvas, void* _model) {
|
||||||
|
UNUSED(_model);
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool empty_screen_view_input_callback(InputEvent* event, void* context) {
|
static bool empty_screen_view_input_callback(InputEvent* event, void* context) {
|
||||||
|
UNUSED(event);
|
||||||
|
UNUSED(context);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,4 +38,4 @@ View* empty_screen_get_view(EmptyScreen* empty_screen);
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -28,4 +28,4 @@ void file_select_set_selected_file(FileSelect* file_select, const char* filename
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -34,6 +34,7 @@ static void loading_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool loading_input_callback(InputEvent* event, void* context) {
|
static bool loading_input_callback(InputEvent* event, void* context) {
|
||||||
|
UNUSED(event);
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,7 +87,7 @@ static void text_box_insert_endline(Canvas* canvas, TextBoxModel* model) {
|
|||||||
model->scroll_num = line_num - 4;
|
model->scroll_num = line_num - 4;
|
||||||
model->scroll_pos = line_num - 5;
|
model->scroll_pos = line_num - 5;
|
||||||
} else {
|
} else {
|
||||||
model->scroll_num = MAX(line_num - 4, 0);
|
model->scroll_num = MAX(line_num - 4, 0u);
|
||||||
model->scroll_pos = 0;
|
model->scroll_pos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,15 +122,15 @@ static const TextInputKey* get_row(uint8_t row_index) {
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char get_selected_char(TextInputModel* model) {
|
static char get_selected_char(TextInputModel* model) {
|
||||||
return get_row(model->selected_row)[model->selected_column].text;
|
return get_row(model->selected_row)[model->selected_column].text;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const bool char_is_lowercase(char letter) {
|
static bool char_is_lowercase(char letter) {
|
||||||
return (letter >= 0x61 && letter <= 0x7A);
|
return (letter >= 0x61 && letter <= 0x7A);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char char_to_uppercase(const char letter) {
|
static char char_to_uppercase(const char letter) {
|
||||||
if(isalpha(letter)) {
|
if(isalpha(letter)) {
|
||||||
return (letter - 0x20);
|
return (letter - 0x20);
|
||||||
} else {
|
} else {
|
||||||
@ -260,6 +260,7 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_up(TextInput* text_input, TextInputModel* model) {
|
static void text_input_handle_up(TextInput* text_input, TextInputModel* model) {
|
||||||
|
UNUSED(text_input);
|
||||||
if(model->selected_row > 0) {
|
if(model->selected_row > 0) {
|
||||||
model->selected_row--;
|
model->selected_row--;
|
||||||
if(model->selected_column > get_row_size(model->selected_row) - 6) {
|
if(model->selected_column > get_row_size(model->selected_row) - 6) {
|
||||||
@ -269,6 +270,7 @@ static void text_input_handle_up(TextInput* text_input, TextInputModel* model) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_down(TextInput* text_input, TextInputModel* model) {
|
static void text_input_handle_down(TextInput* text_input, TextInputModel* model) {
|
||||||
|
UNUSED(text_input);
|
||||||
if(model->selected_row < keyboard_row_count - 1) {
|
if(model->selected_row < keyboard_row_count - 1) {
|
||||||
model->selected_row++;
|
model->selected_row++;
|
||||||
if(model->selected_column > get_row_size(model->selected_row) - 4) {
|
if(model->selected_column > get_row_size(model->selected_row) - 4) {
|
||||||
@ -278,6 +280,7 @@ static void text_input_handle_down(TextInput* text_input, TextInputModel* model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_left(TextInput* text_input, TextInputModel* model) {
|
static void text_input_handle_left(TextInput* text_input, TextInputModel* model) {
|
||||||
|
UNUSED(text_input);
|
||||||
if(model->selected_column > 0) {
|
if(model->selected_column > 0) {
|
||||||
model->selected_column--;
|
model->selected_column--;
|
||||||
} else {
|
} else {
|
||||||
@ -286,6 +289,7 @@ static void text_input_handle_left(TextInput* text_input, TextInputModel* model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void text_input_handle_right(TextInput* text_input, TextInputModel* model) {
|
static void text_input_handle_right(TextInput* text_input, TextInputModel* model) {
|
||||||
|
UNUSED(text_input);
|
||||||
if(model->selected_column < get_row_size(model->selected_row) - 1) {
|
if(model->selected_column < get_row_size(model->selected_row) - 1) {
|
||||||
model->selected_column++;
|
model->selected_column++;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -19,4 +19,4 @@ bool validator_is_file_callback(const char* text, string_t error, void* context)
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -364,6 +364,7 @@ void variable_item_list_set_enter_callback(
|
|||||||
furi_assert(callback);
|
furi_assert(callback);
|
||||||
with_view_model(
|
with_view_model(
|
||||||
variable_item_list->view, (VariableItemListModel * model) {
|
variable_item_list->view, (VariableItemListModel * model) {
|
||||||
|
UNUSED(model);
|
||||||
variable_item_list->callback = callback;
|
variable_item_list->callback = callback;
|
||||||
variable_item_list->context = context;
|
variable_item_list->context = context;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -126,6 +126,7 @@ void view_commit_model(View* view, bool update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void view_icon_animation_callback(IconAnimation* instance, void* context) {
|
void view_icon_animation_callback(IconAnimation* instance, void* context) {
|
||||||
|
UNUSED(instance);
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
View* view = context;
|
View* view = context;
|
||||||
if(view->update_callback) {
|
if(view->update_callback) {
|
||||||
|
|||||||
349
applications/ibutton/ibutton.c
Normal file
349
applications/ibutton/ibutton.c
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
#include "ibutton.h"
|
||||||
|
#include "ibutton_i.h"
|
||||||
|
#include "ibutton/scenes/ibutton_scene.h"
|
||||||
|
|
||||||
|
#include <toolbox/path.h>
|
||||||
|
#include <flipper_format/flipper_format.h>
|
||||||
|
|
||||||
|
static const NotificationSequence* ibutton_notification_sequences[] = {
|
||||||
|
&sequence_error,
|
||||||
|
&sequence_success,
|
||||||
|
&sequence_blink_cyan_10,
|
||||||
|
&sequence_blink_magenta_10,
|
||||||
|
&sequence_blink_yellow_10,
|
||||||
|
&sequence_set_red_255,
|
||||||
|
&sequence_reset_red,
|
||||||
|
&sequence_set_green_255,
|
||||||
|
&sequence_reset_green,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ibutton_make_app_folder(iButton* ibutton) {
|
||||||
|
if(!storage_simply_mkdir(ibutton->storage, IBUTTON_APP_FOLDER)) {
|
||||||
|
dialog_message_show_storage_error(ibutton->dialogs, "Cannot create\napp folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ibutton_load_key_data(iButton* ibutton, string_t key_path) {
|
||||||
|
FlipperFormat* file = flipper_format_file_alloc(ibutton->storage);
|
||||||
|
bool result = false;
|
||||||
|
string_t data;
|
||||||
|
string_init(data);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break;
|
||||||
|
|
||||||
|
// header
|
||||||
|
uint32_t version;
|
||||||
|
if(!flipper_format_read_header(file, data, &version)) break;
|
||||||
|
if(string_cmp_str(data, IBUTTON_APP_FILE_TYPE) != 0) break;
|
||||||
|
if(version != 1) break;
|
||||||
|
|
||||||
|
// key type
|
||||||
|
iButtonKeyType type;
|
||||||
|
if(!flipper_format_read_string(file, "Key type", data)) break;
|
||||||
|
if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break;
|
||||||
|
|
||||||
|
// key data
|
||||||
|
uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0};
|
||||||
|
if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ibutton_key_set_type(ibutton->key, type);
|
||||||
|
ibutton_key_set_data(ibutton->key, key_data, IBUTTON_KEY_DATA_SIZE);
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
flipper_format_free(file);
|
||||||
|
string_clear(data);
|
||||||
|
|
||||||
|
if(!result) {
|
||||||
|
dialog_message_show_storage_error(ibutton->dialogs, "Cannot load\nkey file");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ibutton_custom_event_callback(void* context, uint32_t event) {
|
||||||
|
furi_assert(context);
|
||||||
|
iButton* ibutton = context;
|
||||||
|
return scene_manager_handle_custom_event(ibutton->scene_manager, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ibutton_back_event_callback(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
iButton* ibutton = context;
|
||||||
|
return scene_manager_handle_back_event(ibutton->scene_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ibutton_tick_event_callback(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
iButton* ibutton = context;
|
||||||
|
scene_manager_handle_tick_event(ibutton->scene_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
iButton* ibutton_alloc() {
|
||||||
|
iButton* ibutton = malloc(sizeof(iButton));
|
||||||
|
|
||||||
|
ibutton->scene_manager = scene_manager_alloc(&ibutton_scene_handlers, ibutton);
|
||||||
|
|
||||||
|
ibutton->view_dispatcher = view_dispatcher_alloc();
|
||||||
|
view_dispatcher_enable_queue(ibutton->view_dispatcher);
|
||||||
|
view_dispatcher_set_event_callback_context(ibutton->view_dispatcher, ibutton);
|
||||||
|
view_dispatcher_set_custom_event_callback(
|
||||||
|
ibutton->view_dispatcher, ibutton_custom_event_callback);
|
||||||
|
view_dispatcher_set_navigation_event_callback(
|
||||||
|
ibutton->view_dispatcher, ibutton_back_event_callback);
|
||||||
|
view_dispatcher_set_tick_event_callback(
|
||||||
|
ibutton->view_dispatcher, ibutton_tick_event_callback, 100);
|
||||||
|
|
||||||
|
ibutton->gui = furi_record_open("gui");
|
||||||
|
view_dispatcher_attach_to_gui(
|
||||||
|
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
|
||||||
|
|
||||||
|
ibutton->storage = furi_record_open("storage");
|
||||||
|
ibutton->dialogs = furi_record_open("dialogs");
|
||||||
|
ibutton->notifications = furi_record_open("notification");
|
||||||
|
|
||||||
|
ibutton->key = ibutton_key_alloc();
|
||||||
|
ibutton->key_worker = ibutton_worker_alloc();
|
||||||
|
ibutton_worker_start_thread(ibutton->key_worker);
|
||||||
|
|
||||||
|
ibutton->submenu = submenu_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
ibutton->view_dispatcher, iButtonViewSubmenu, submenu_get_view(ibutton->submenu));
|
||||||
|
|
||||||
|
ibutton->byte_input = byte_input_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
ibutton->view_dispatcher, iButtonViewByteInput, byte_input_get_view(ibutton->byte_input));
|
||||||
|
|
||||||
|
ibutton->text_input = text_input_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
ibutton->view_dispatcher, iButtonViewTextInput, text_input_get_view(ibutton->text_input));
|
||||||
|
|
||||||
|
ibutton->popup = popup_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
ibutton->view_dispatcher, iButtonViewPopup, popup_get_view(ibutton->popup));
|
||||||
|
|
||||||
|
ibutton->widget = widget_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
ibutton->view_dispatcher, iButtonViewWidget, widget_get_view(ibutton->widget));
|
||||||
|
|
||||||
|
ibutton->dialog_ex = dialog_ex_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
ibutton->view_dispatcher, iButtonViewDialogEx, dialog_ex_get_view(ibutton->dialog_ex));
|
||||||
|
|
||||||
|
return ibutton;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ibutton_free(iButton* ibutton) {
|
||||||
|
furi_assert(ibutton);
|
||||||
|
|
||||||
|
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewDialogEx);
|
||||||
|
dialog_ex_free(ibutton->dialog_ex);
|
||||||
|
|
||||||
|
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewWidget);
|
||||||
|
widget_free(ibutton->widget);
|
||||||
|
|
||||||
|
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewPopup);
|
||||||
|
popup_free(ibutton->popup);
|
||||||
|
|
||||||
|
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewTextInput);
|
||||||
|
text_input_free(ibutton->text_input);
|
||||||
|
|
||||||
|
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewByteInput);
|
||||||
|
byte_input_free(ibutton->byte_input);
|
||||||
|
|
||||||
|
view_dispatcher_remove_view(ibutton->view_dispatcher, iButtonViewSubmenu);
|
||||||
|
submenu_free(ibutton->submenu);
|
||||||
|
|
||||||
|
view_dispatcher_free(ibutton->view_dispatcher);
|
||||||
|
scene_manager_free(ibutton->scene_manager);
|
||||||
|
|
||||||
|
furi_record_close("storage");
|
||||||
|
ibutton->storage = NULL;
|
||||||
|
|
||||||
|
furi_record_close("notification");
|
||||||
|
ibutton->notifications = NULL;
|
||||||
|
|
||||||
|
furi_record_close("dialogs");
|
||||||
|
ibutton->dialogs = NULL;
|
||||||
|
|
||||||
|
furi_record_close("gui");
|
||||||
|
ibutton->gui = NULL;
|
||||||
|
|
||||||
|
ibutton_worker_stop_thread(ibutton->key_worker);
|
||||||
|
ibutton_worker_free(ibutton->key_worker);
|
||||||
|
ibutton_key_free(ibutton->key);
|
||||||
|
|
||||||
|
free(ibutton);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ibutton_file_select(iButton* ibutton) {
|
||||||
|
bool success = dialog_file_select_show(
|
||||||
|
ibutton->dialogs,
|
||||||
|
IBUTTON_APP_FOLDER,
|
||||||
|
IBUTTON_APP_EXTENSION,
|
||||||
|
ibutton->file_name,
|
||||||
|
IBUTTON_FILE_NAME_SIZE,
|
||||||
|
ibutton_key_get_name_p(ibutton->key));
|
||||||
|
|
||||||
|
if(success) {
|
||||||
|
string_t key_str;
|
||||||
|
string_init_printf(
|
||||||
|
key_str, "%s/%s%s", IBUTTON_APP_FOLDER, ibutton->file_name, IBUTTON_APP_EXTENSION);
|
||||||
|
success = ibutton_load_key_data(ibutton, key_str);
|
||||||
|
|
||||||
|
if(success) {
|
||||||
|
ibutton_key_set_name(ibutton->key, ibutton->file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
string_clear(key_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ibutton_load_key(iButton* ibutton, const char* key_name) {
|
||||||
|
string_t key_path;
|
||||||
|
string_init_set_str(key_path, key_name);
|
||||||
|
|
||||||
|
const bool success = ibutton_load_key_data(ibutton, key_path);
|
||||||
|
|
||||||
|
if(success) {
|
||||||
|
path_extract_filename_no_ext(key_name, key_path);
|
||||||
|
ibutton_key_set_name(ibutton->key, string_get_cstr(key_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
string_clear(key_path);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ibutton_save_key(iButton* ibutton, const char* key_name) {
|
||||||
|
// Create ibutton directory if necessary
|
||||||
|
ibutton_make_app_folder(ibutton);
|
||||||
|
|
||||||
|
FlipperFormat* file = flipper_format_file_alloc(ibutton->storage);
|
||||||
|
iButtonKey* key = ibutton->key;
|
||||||
|
|
||||||
|
string_t key_file_name;
|
||||||
|
bool result = false;
|
||||||
|
string_init(key_file_name);
|
||||||
|
|
||||||
|
do {
|
||||||
|
// First remove key if it was saved (we rename the key)
|
||||||
|
if(!ibutton_delete_key(ibutton)) break;
|
||||||
|
|
||||||
|
// Save the key
|
||||||
|
ibutton_key_set_name(key, key_name);
|
||||||
|
|
||||||
|
// Set full file name, for new key
|
||||||
|
string_printf(
|
||||||
|
key_file_name,
|
||||||
|
"%s/%s%s",
|
||||||
|
IBUTTON_APP_FOLDER,
|
||||||
|
ibutton_key_get_name_p(key),
|
||||||
|
IBUTTON_APP_EXTENSION);
|
||||||
|
|
||||||
|
// Open file for write
|
||||||
|
if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break;
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
if(!flipper_format_write_header_cstr(file, IBUTTON_APP_FILE_TYPE, 1)) break;
|
||||||
|
|
||||||
|
// Write key type
|
||||||
|
if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom"))
|
||||||
|
break;
|
||||||
|
const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key));
|
||||||
|
if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break;
|
||||||
|
|
||||||
|
// Write data
|
||||||
|
if(!flipper_format_write_comment_cstr(
|
||||||
|
file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8"))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(!flipper_format_write_hex(
|
||||||
|
file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)))
|
||||||
|
break;
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
flipper_format_free(file);
|
||||||
|
|
||||||
|
string_clear(key_file_name);
|
||||||
|
|
||||||
|
if(!result) {
|
||||||
|
dialog_message_show_storage_error(ibutton->dialogs, "Cannot save\nkey file");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ibutton_delete_key(iButton* ibutton) {
|
||||||
|
string_t file_name;
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
string_init_printf(
|
||||||
|
file_name,
|
||||||
|
"%s/%s%s",
|
||||||
|
IBUTTON_APP_FOLDER,
|
||||||
|
ibutton_key_get_name_p(ibutton->key),
|
||||||
|
IBUTTON_APP_EXTENSION);
|
||||||
|
result = storage_simply_remove(ibutton->storage, string_get_cstr(file_name));
|
||||||
|
string_clear(file_name);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ibutton_text_store_set(iButton* ibutton, const char* text, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, text);
|
||||||
|
|
||||||
|
vsnprintf(ibutton->text_store, IBUTTON_TEXT_STORE_SIZE, text, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ibutton_text_store_clear(iButton* ibutton) {
|
||||||
|
memset(ibutton->text_store, 0, IBUTTON_TEXT_STORE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ibutton_switch_to_previous_scene_one_of(
|
||||||
|
iButton* ibutton,
|
||||||
|
const uint32_t* scene_ids,
|
||||||
|
size_t scene_ids_size) {
|
||||||
|
furi_assert(scene_ids_size);
|
||||||
|
SceneManager* scene_manager = ibutton->scene_manager;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < scene_ids_size; ++i) {
|
||||||
|
const uint32_t scene_id = scene_ids[i];
|
||||||
|
if(scene_manager_has_previous_scene(scene_manager, scene_id)) {
|
||||||
|
scene_manager_search_and_switch_to_previous_scene(scene_manager, scene_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ibutton_notification_message(iButton* ibutton, uint32_t message) {
|
||||||
|
furi_assert(message < sizeof(ibutton_notification_sequences) / sizeof(NotificationSequence*));
|
||||||
|
notification_message(ibutton->notifications, ibutton_notification_sequences[message]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ibutton_app(void* p) {
|
||||||
|
iButton* ibutton = ibutton_alloc();
|
||||||
|
|
||||||
|
ibutton_make_app_folder(ibutton);
|
||||||
|
|
||||||
|
if(p && ibutton_load_key(ibutton, (const char*)p)) {
|
||||||
|
// TODO: Display an error if the key from p could not be loaded
|
||||||
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
|
||||||
|
} else {
|
||||||
|
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_dispatcher_run(ibutton->view_dispatcher);
|
||||||
|
|
||||||
|
ibutton_free(ibutton);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#include "ibutton_app.h"
|
|
||||||
|
|
||||||
// app enter function
|
|
||||||
extern "C" int32_t ibutton_app(void* p) {
|
|
||||||
iButtonApp* app = new iButtonApp();
|
|
||||||
app->run(p);
|
|
||||||
delete app;
|
|
||||||
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
3
applications/ibutton/ibutton.h
Normal file
3
applications/ibutton/ibutton.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct iButton iButton;
|
||||||
@ -1,342 +0,0 @@
|
|||||||
#include "ibutton_app.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <m-string.h>
|
|
||||||
#include <toolbox/path.h>
|
|
||||||
#include <flipper_format/flipper_format.h>
|
|
||||||
|
|
||||||
const char* iButtonApp::app_folder = "/any/ibutton";
|
|
||||||
const char* iButtonApp::app_extension = ".ibtn";
|
|
||||||
const char* iButtonApp::app_filetype = "Flipper iButton key";
|
|
||||||
|
|
||||||
void iButtonApp::run(void* args) {
|
|
||||||
iButtonEvent event;
|
|
||||||
bool consumed;
|
|
||||||
bool exit = false;
|
|
||||||
|
|
||||||
make_app_folder();
|
|
||||||
|
|
||||||
if(args && load_key((const char*)args)) {
|
|
||||||
current_scene = Scene::SceneEmulate;
|
|
||||||
}
|
|
||||||
|
|
||||||
scenes[current_scene]->on_enter(this);
|
|
||||||
|
|
||||||
while(!exit) {
|
|
||||||
view.receive_event(&event);
|
|
||||||
|
|
||||||
consumed = scenes[current_scene]->on_event(this, &event);
|
|
||||||
|
|
||||||
if(!consumed) {
|
|
||||||
if(event.type == iButtonEvent::Type::EventTypeBack) {
|
|
||||||
exit = switch_to_previous_scene();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
scenes[current_scene]->on_exit(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonApp::iButtonApp()
|
|
||||||
: notification{"notification"}
|
|
||||||
, storage{"storage"}
|
|
||||||
, dialogs{"dialogs"} {
|
|
||||||
key = ibutton_key_alloc();
|
|
||||||
key_worker = ibutton_worker_alloc();
|
|
||||||
ibutton_worker_start_thread(key_worker);
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonApp::~iButtonApp() {
|
|
||||||
for(std::map<Scene, iButtonScene*>::iterator it = scenes.begin(); it != scenes.end(); ++it) {
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
scenes.clear();
|
|
||||||
|
|
||||||
ibutton_worker_stop_thread(key_worker);
|
|
||||||
ibutton_worker_free(key_worker);
|
|
||||||
ibutton_key_free(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonAppViewManager* iButtonApp::get_view_manager() {
|
|
||||||
return &view;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::switch_to_next_scene(Scene next_scene) {
|
|
||||||
previous_scenes_list.push_front(current_scene);
|
|
||||||
|
|
||||||
if(next_scene != Scene::SceneExit) {
|
|
||||||
scenes[current_scene]->on_exit(this);
|
|
||||||
current_scene = next_scene;
|
|
||||||
scenes[current_scene]->on_enter(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list) {
|
|
||||||
Scene previous_scene = Scene::SceneStart;
|
|
||||||
bool scene_found = false;
|
|
||||||
|
|
||||||
while(!scene_found) {
|
|
||||||
previous_scene = get_previous_scene();
|
|
||||||
for(Scene element : scenes_list) {
|
|
||||||
if(previous_scene == element || previous_scene == Scene::SceneStart) {
|
|
||||||
scene_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scenes[current_scene]->on_exit(this);
|
|
||||||
current_scene = previous_scene;
|
|
||||||
scenes[current_scene]->on_enter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool iButtonApp::switch_to_previous_scene(uint8_t count) {
|
|
||||||
Scene previous_scene = Scene::SceneStart;
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < count; i++) {
|
|
||||||
previous_scene = get_previous_scene();
|
|
||||||
if(previous_scene == Scene::SceneExit) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(previous_scene == Scene::SceneExit) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
scenes[current_scene]->on_exit(this);
|
|
||||||
current_scene = previous_scene;
|
|
||||||
scenes[current_scene]->on_enter(this);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonApp::Scene iButtonApp::get_previous_scene() {
|
|
||||||
Scene scene = previous_scenes_list.front();
|
|
||||||
previous_scenes_list.pop_front();
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonWorker* iButtonApp::get_key_worker() {
|
|
||||||
return key_worker;
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonKey* iButtonApp::get_key() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* iButtonApp::get_file_name() {
|
|
||||||
return file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t iButtonApp::get_file_name_size() {
|
|
||||||
return file_name_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_read() {
|
|
||||||
notification_message(notification, &sequence_blink_cyan_10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_emulate() {
|
|
||||||
notification_message(notification, &sequence_blink_magenta_10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_yellow_blink() {
|
|
||||||
notification_message(notification, &sequence_blink_yellow_10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_error() {
|
|
||||||
notification_message(notification, &sequence_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_success() {
|
|
||||||
notification_message(notification, &sequence_success);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_green_on() {
|
|
||||||
notification_message_block(notification, &sequence_set_green_255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_green_off() {
|
|
||||||
notification_message(notification, &sequence_reset_green);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_red_on() {
|
|
||||||
notification_message_block(notification, &sequence_set_red_255);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::notify_red_off() {
|
|
||||||
notification_message(notification, &sequence_reset_red);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::set_text_store(const char* text...) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, text);
|
|
||||||
|
|
||||||
vsnprintf(text_store, text_store_size, text, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* iButtonApp::get_text_store() {
|
|
||||||
return text_store;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t iButtonApp::get_text_store_size() {
|
|
||||||
return text_store_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// file managment
|
|
||||||
bool iButtonApp::save_key(const char* key_name) {
|
|
||||||
// Create ibutton directory if necessary
|
|
||||||
make_app_folder();
|
|
||||||
|
|
||||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
|
||||||
string_t key_file_name;
|
|
||||||
bool result = false;
|
|
||||||
string_init(key_file_name);
|
|
||||||
|
|
||||||
do {
|
|
||||||
// First remove key if it was saved (we rename the key)
|
|
||||||
if(!delete_key()) break;
|
|
||||||
|
|
||||||
// Save the key
|
|
||||||
ibutton_key_set_name(key, key_name);
|
|
||||||
|
|
||||||
// Set full file name, for new key
|
|
||||||
string_printf(
|
|
||||||
key_file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension);
|
|
||||||
|
|
||||||
// Open file for write
|
|
||||||
if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break;
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
if(!flipper_format_write_header_cstr(file, iButtonApp::app_filetype, 1)) break;
|
|
||||||
|
|
||||||
// Write key type
|
|
||||||
if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom"))
|
|
||||||
break;
|
|
||||||
const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key));
|
|
||||||
if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break;
|
|
||||||
|
|
||||||
// Write data
|
|
||||||
if(!flipper_format_write_comment_cstr(
|
|
||||||
file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8"))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!flipper_format_write_hex(
|
|
||||||
file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)))
|
|
||||||
break;
|
|
||||||
result = true;
|
|
||||||
|
|
||||||
} while(false);
|
|
||||||
|
|
||||||
flipper_format_free(file);
|
|
||||||
|
|
||||||
string_clear(key_file_name);
|
|
||||||
|
|
||||||
if(!result) {
|
|
||||||
dialog_message_show_storage_error(dialogs, "Cannot save\nkey file");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool iButtonApp::load_key_data(string_t key_path) {
|
|
||||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
|
||||||
bool result = false;
|
|
||||||
string_t data;
|
|
||||||
string_init(data);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(!flipper_format_file_open_existing(file, string_get_cstr(key_path))) break;
|
|
||||||
|
|
||||||
// header
|
|
||||||
uint32_t version;
|
|
||||||
if(!flipper_format_read_header(file, data, &version)) break;
|
|
||||||
if(string_cmp_str(data, iButtonApp::app_filetype) != 0) break;
|
|
||||||
if(version != 1) break;
|
|
||||||
|
|
||||||
// key type
|
|
||||||
iButtonKeyType type;
|
|
||||||
if(!flipper_format_read_string(file, "Key type", data)) break;
|
|
||||||
if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break;
|
|
||||||
|
|
||||||
// key data
|
|
||||||
uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0};
|
|
||||||
if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
ibutton_key_set_type(key, type);
|
|
||||||
ibutton_key_set_data(key, key_data, IBUTTON_KEY_DATA_SIZE);
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
} while(false);
|
|
||||||
|
|
||||||
flipper_format_free(file);
|
|
||||||
string_clear(data);
|
|
||||||
|
|
||||||
if(!result) {
|
|
||||||
dialog_message_show_storage_error(dialogs, "Cannot load\nkey file");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool iButtonApp::load_key(const char* key_name) {
|
|
||||||
bool result = false;
|
|
||||||
string_t key_path;
|
|
||||||
|
|
||||||
string_init_set_str(key_path, key_name);
|
|
||||||
|
|
||||||
result = load_key_data(key_path);
|
|
||||||
if(result) {
|
|
||||||
path_extract_filename_no_ext(key_name, key_path);
|
|
||||||
ibutton_key_set_name(key, string_get_cstr(key_path));
|
|
||||||
}
|
|
||||||
string_clear(key_path);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool iButtonApp::load_key() {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
// Input events and views are managed by file_select
|
|
||||||
bool res = dialog_file_select_show(
|
|
||||||
dialogs,
|
|
||||||
app_folder,
|
|
||||||
app_extension,
|
|
||||||
get_file_name(),
|
|
||||||
get_file_name_size(),
|
|
||||||
ibutton_key_get_name_p(key));
|
|
||||||
|
|
||||||
if(res) {
|
|
||||||
string_t key_str;
|
|
||||||
|
|
||||||
// Get key file path
|
|
||||||
string_init_printf(key_str, "%s/%s%s", app_folder, get_file_name(), app_extension);
|
|
||||||
|
|
||||||
result = load_key_data(key_str);
|
|
||||||
if(result) {
|
|
||||||
ibutton_key_set_name(key, get_file_name());
|
|
||||||
}
|
|
||||||
string_clear(key_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool iButtonApp::delete_key() {
|
|
||||||
string_t file_name;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
string_init_printf(
|
|
||||||
file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension);
|
|
||||||
result = storage_simply_remove(storage, string_get_cstr(file_name));
|
|
||||||
string_clear(file_name);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonApp::make_app_folder() {
|
|
||||||
if(!storage_simply_mkdir(storage, app_folder)) {
|
|
||||||
dialog_message_show_storage_error(dialogs, "Cannot create\napp folder");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include "ibutton_view_manager.h"
|
|
||||||
#include "scene/ibutton_scene_generic.h"
|
|
||||||
#include "scene/ibutton_scene_start.h"
|
|
||||||
#include "scene/ibutton_scene_read.h"
|
|
||||||
#include "scene/ibutton_scene_read_crc_error.h"
|
|
||||||
#include "scene/ibutton_scene_read_not_key_error.h"
|
|
||||||
#include "scene/ibutton_scene_read_success.h"
|
|
||||||
#include "scene/ibutton_scene_retry_confirm.h"
|
|
||||||
#include "scene/ibutton_scene_exit_confirm.h"
|
|
||||||
#include "scene/ibutton_scene_read_key_menu.h"
|
|
||||||
#include "scene/ibutton_scene_write.h"
|
|
||||||
#include "scene/ibutton_scene_write_success.h"
|
|
||||||
#include "scene/ibutton_scene_saved_key_menu.h"
|
|
||||||
#include "scene/ibutton_scene_delete_confirm.h"
|
|
||||||
#include "scene/ibutton_scene_delete_success.h"
|
|
||||||
#include "scene/ibutton_scene_emulate.h"
|
|
||||||
#include "scene/ibutton_scene_save_name.h"
|
|
||||||
#include "scene/ibutton_scene_save_success.h"
|
|
||||||
#include "scene/ibutton_scene_info.h"
|
|
||||||
#include "scene/ibutton_scene_select_key.h"
|
|
||||||
#include "scene/ibutton_scene_add_type.h"
|
|
||||||
#include "scene/ibutton_scene_add_value.h"
|
|
||||||
#include <one_wire/ibutton/ibutton_worker.h>
|
|
||||||
#include <notification/notification_messages.h>
|
|
||||||
#include <storage/storage.h>
|
|
||||||
#include <dialogs/dialogs.h>
|
|
||||||
#include <record_controller.hpp>
|
|
||||||
|
|
||||||
class iButtonApp {
|
|
||||||
public:
|
|
||||||
void run(void* args);
|
|
||||||
|
|
||||||
iButtonApp();
|
|
||||||
~iButtonApp();
|
|
||||||
|
|
||||||
enum class Scene : uint8_t {
|
|
||||||
SceneExit,
|
|
||||||
SceneStart,
|
|
||||||
SceneRead,
|
|
||||||
SceneReadNotKeyError,
|
|
||||||
SceneReadCRCError,
|
|
||||||
SceneReadSuccess,
|
|
||||||
SceneRetryConfirm,
|
|
||||||
SceneExitConfirm,
|
|
||||||
SceneReadKeyMenu,
|
|
||||||
SceneWrite,
|
|
||||||
SceneWriteSuccess,
|
|
||||||
SceneEmulate,
|
|
||||||
SceneSavedKeyMenu,
|
|
||||||
SceneDeleteConfirm,
|
|
||||||
SceneDeleteSuccess,
|
|
||||||
SceneSaveName,
|
|
||||||
SceneSaveSuccess,
|
|
||||||
SceneInfo,
|
|
||||||
SceneSelectKey,
|
|
||||||
SceneAddType,
|
|
||||||
SceneAddValue,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char* app_folder;
|
|
||||||
static const char* app_extension;
|
|
||||||
static const char* app_filetype;
|
|
||||||
|
|
||||||
iButtonAppViewManager* get_view_manager();
|
|
||||||
void switch_to_next_scene(Scene index);
|
|
||||||
void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list);
|
|
||||||
bool switch_to_previous_scene(uint8_t count = 1);
|
|
||||||
Scene get_previous_scene();
|
|
||||||
|
|
||||||
const GpioPin* get_ibutton_pin();
|
|
||||||
iButtonWorker* get_key_worker();
|
|
||||||
iButtonKey* get_key();
|
|
||||||
|
|
||||||
void notify_read();
|
|
||||||
void notify_yellow_blink();
|
|
||||||
void notify_emulate();
|
|
||||||
|
|
||||||
void notify_error();
|
|
||||||
void notify_success();
|
|
||||||
void notify_green_on();
|
|
||||||
void notify_green_off();
|
|
||||||
void notify_red_on();
|
|
||||||
void notify_red_off();
|
|
||||||
|
|
||||||
void set_text_store(const char* text...);
|
|
||||||
char* get_text_store();
|
|
||||||
uint8_t get_text_store_size();
|
|
||||||
|
|
||||||
char* get_file_name();
|
|
||||||
uint8_t get_file_name_size();
|
|
||||||
|
|
||||||
bool save_key(const char* key_name);
|
|
||||||
bool load_key();
|
|
||||||
bool load_key(const char* key_name);
|
|
||||||
bool delete_key();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::list<Scene> previous_scenes_list = {Scene::SceneExit};
|
|
||||||
Scene current_scene = Scene::SceneStart;
|
|
||||||
iButtonAppViewManager view;
|
|
||||||
|
|
||||||
std::map<Scene, iButtonScene*> scenes = {
|
|
||||||
{Scene::SceneStart, new iButtonSceneStart()},
|
|
||||||
{Scene::SceneRead, new iButtonSceneRead()},
|
|
||||||
{Scene::SceneReadCRCError, new iButtonSceneReadCRCError()},
|
|
||||||
{Scene::SceneReadNotKeyError, new iButtonSceneReadNotKeyError()},
|
|
||||||
{Scene::SceneReadSuccess, new iButtonSceneReadSuccess()},
|
|
||||||
{Scene::SceneRetryConfirm, new iButtonSceneRetryConfirm()},
|
|
||||||
{Scene::SceneExitConfirm, new iButtonSceneExitConfirm()},
|
|
||||||
{Scene::SceneReadKeyMenu, new iButtonSceneReadKeyMenu()},
|
|
||||||
{Scene::SceneWrite, new iButtonSceneWrite()},
|
|
||||||
{Scene::SceneWriteSuccess, new iButtonSceneWriteSuccess()},
|
|
||||||
{Scene::SceneEmulate, new iButtonSceneEmulate()},
|
|
||||||
{Scene::SceneSavedKeyMenu, new iButtonSceneSavedKeyMenu()},
|
|
||||||
{Scene::SceneDeleteConfirm, new iButtonSceneDeleteConfirm()},
|
|
||||||
{Scene::SceneDeleteSuccess, new iButtonSceneDeleteSuccess()},
|
|
||||||
{Scene::SceneSaveName, new iButtonSceneSaveName()},
|
|
||||||
{Scene::SceneSaveSuccess, new iButtonSceneSaveSuccess()},
|
|
||||||
{Scene::SceneInfo, new iButtonSceneInfo()},
|
|
||||||
{Scene::SceneSelectKey, new iButtonSceneSelectKey()},
|
|
||||||
{Scene::SceneAddType, new iButtonSceneAddType()},
|
|
||||||
{Scene::SceneAddValue, new iButtonSceneAddValue()},
|
|
||||||
};
|
|
||||||
|
|
||||||
iButtonWorker* key_worker;
|
|
||||||
iButtonKey* key;
|
|
||||||
|
|
||||||
RecordController<NotificationApp> notification;
|
|
||||||
RecordController<Storage> storage;
|
|
||||||
RecordController<DialogsApp> dialogs;
|
|
||||||
|
|
||||||
static const uint8_t file_name_size = 100;
|
|
||||||
char file_name[file_name_size];
|
|
||||||
|
|
||||||
static const uint8_t text_store_size = 128;
|
|
||||||
char text_store[text_store_size + 1];
|
|
||||||
|
|
||||||
bool load_key_data(string_t key_path);
|
|
||||||
void make_app_folder();
|
|
||||||
};
|
|
||||||
@ -240,6 +240,7 @@ void ibutton_cli_emulate(Cli* cli, string_t args) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void ibutton_cli(Cli* cli, string_t args, void* context) {
|
static void ibutton_cli(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
string_t cmd;
|
string_t cmd;
|
||||||
string_init(cmd);
|
string_init(cmd);
|
||||||
|
|
||||||
@ -268,6 +269,7 @@ void onewire_cli_print_usage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void onewire_cli_search(Cli* cli) {
|
static void onewire_cli_search(Cli* cli) {
|
||||||
|
UNUSED(cli);
|
||||||
OneWireHost* onewire = onewire_host_alloc();
|
OneWireHost* onewire = onewire_host_alloc();
|
||||||
uint8_t address[8];
|
uint8_t address[8];
|
||||||
bool done = false;
|
bool done = false;
|
||||||
@ -297,6 +299,7 @@ static void onewire_cli_search(Cli* cli) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onewire_cli(Cli* cli, string_t args, void* context) {
|
void onewire_cli(Cli* cli, string_t args, void* context) {
|
||||||
|
UNUSED(context);
|
||||||
string_t cmd;
|
string_t cmd;
|
||||||
string_init(cmd);
|
string_init(cmd);
|
||||||
|
|
||||||
@ -311,4 +314,4 @@ void onewire_cli(Cli* cli, string_t args, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string_clear(cmd);
|
string_clear(cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
12
applications/ibutton/ibutton_custom_event.h
Normal file
12
applications/ibutton/ibutton_custom_event.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum iButtonCustomEvent {
|
||||||
|
// Reserve first 100 events for button types and indexes, starting from 0
|
||||||
|
iButtonCustomEventReserved = 100,
|
||||||
|
|
||||||
|
iButtonCustomEventBack,
|
||||||
|
iButtonCustomEventTextEditResult,
|
||||||
|
iButtonCustomEventByteEditResult,
|
||||||
|
iButtonCustomEventWorkerEmulated,
|
||||||
|
iButtonCustomEventWorkerRead,
|
||||||
|
};
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <gui/modules/dialog_ex.h>
|
|
||||||
#include <gui/modules/widget.h>
|
|
||||||
#include <one_wire/ibutton/ibutton_worker.h>
|
|
||||||
|
|
||||||
class iButtonApp;
|
|
||||||
|
|
||||||
class iButtonEvent {
|
|
||||||
public:
|
|
||||||
// events enum
|
|
||||||
enum class Type : uint8_t {
|
|
||||||
EventTypeTick,
|
|
||||||
EventTypeBack,
|
|
||||||
EventTypeMenuSelected,
|
|
||||||
EventTypeDialogResult,
|
|
||||||
EventTypeTextEditResult,
|
|
||||||
EventTypeByteEditResult,
|
|
||||||
EventTypeWidgetButtonResult,
|
|
||||||
EventTypeWorkerEmulated,
|
|
||||||
EventTypeWorkerRead,
|
|
||||||
EventTypeWorkerWrite,
|
|
||||||
};
|
|
||||||
|
|
||||||
// payload
|
|
||||||
union {
|
|
||||||
uint32_t menu_index;
|
|
||||||
DialogExResult dialog_result;
|
|
||||||
GuiButtonType widget_button_result;
|
|
||||||
iButtonWorkerWriteResult worker_write_result;
|
|
||||||
} payload;
|
|
||||||
|
|
||||||
// event type
|
|
||||||
Type type;
|
|
||||||
};
|
|
||||||
86
applications/ibutton/ibutton_i.h
Normal file
86
applications/ibutton/ibutton_i.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ibutton.h"
|
||||||
|
|
||||||
|
#include <gui/gui.h>
|
||||||
|
#include <gui/view.h>
|
||||||
|
#include <gui/view_dispatcher.h>
|
||||||
|
#include <gui/scene_manager.h>
|
||||||
|
#include <notification/notification_messages.h>
|
||||||
|
|
||||||
|
#include <one_wire/ibutton/ibutton_worker.h>
|
||||||
|
#include <storage/storage.h>
|
||||||
|
#include <dialogs/dialogs.h>
|
||||||
|
|
||||||
|
#include <gui/modules/submenu.h>
|
||||||
|
#include <gui/modules/popup.h>
|
||||||
|
#include <gui/modules/dialog_ex.h>
|
||||||
|
#include <gui/modules/text_input.h>
|
||||||
|
#include <gui/modules/byte_input.h>
|
||||||
|
#include <gui/modules/widget.h>
|
||||||
|
|
||||||
|
#include "ibutton_custom_event.h"
|
||||||
|
#include "scenes/ibutton_scene.h"
|
||||||
|
|
||||||
|
#define IBUTTON_FILE_NAME_SIZE 100
|
||||||
|
#define IBUTTON_TEXT_STORE_SIZE 128
|
||||||
|
|
||||||
|
#define IBUTTON_APP_FOLDER "/any/ibutton"
|
||||||
|
#define IBUTTON_APP_EXTENSION ".ibtn"
|
||||||
|
#define IBUTTON_APP_FILE_TYPE "Flipper iButton key"
|
||||||
|
|
||||||
|
struct iButton {
|
||||||
|
SceneManager* scene_manager;
|
||||||
|
ViewDispatcher* view_dispatcher;
|
||||||
|
|
||||||
|
Gui* gui;
|
||||||
|
Storage* storage;
|
||||||
|
DialogsApp* dialogs;
|
||||||
|
NotificationApp* notifications;
|
||||||
|
|
||||||
|
iButtonWorker* key_worker;
|
||||||
|
iButtonKey* key;
|
||||||
|
|
||||||
|
char file_name[IBUTTON_FILE_NAME_SIZE];
|
||||||
|
char text_store[IBUTTON_TEXT_STORE_SIZE + 1];
|
||||||
|
|
||||||
|
Submenu* submenu;
|
||||||
|
ByteInput* byte_input;
|
||||||
|
TextInput* text_input;
|
||||||
|
Popup* popup;
|
||||||
|
Widget* widget;
|
||||||
|
DialogEx* dialog_ex;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
iButtonViewSubmenu,
|
||||||
|
iButtonViewByteInput,
|
||||||
|
iButtonViewTextInput,
|
||||||
|
iButtonViewPopup,
|
||||||
|
iButtonViewWidget,
|
||||||
|
iButtonViewDialogEx,
|
||||||
|
} iButtonView;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
iButtonNotificationMessageError,
|
||||||
|
iButtonNotificationMessageSuccess,
|
||||||
|
iButtonNotificationMessageRead,
|
||||||
|
iButtonNotificationMessageEmulate,
|
||||||
|
iButtonNotificationMessageYellowBlink,
|
||||||
|
iButtonNotificationMessageRedOn,
|
||||||
|
iButtonNotificationMessageRedOff,
|
||||||
|
iButtonNotificationMessageGreenOn,
|
||||||
|
iButtonNotificationMessageGreenOff,
|
||||||
|
} iButtonNotificationMessage;
|
||||||
|
|
||||||
|
bool ibutton_file_select(iButton* ibutton);
|
||||||
|
bool ibutton_load_key(iButton* ibutton, const char* key_name);
|
||||||
|
bool ibutton_save_key(iButton* ibutton, const char* key_name);
|
||||||
|
bool ibutton_delete_key(iButton* ibutton);
|
||||||
|
void ibutton_text_store_set(iButton* ibutton, const char* text, ...);
|
||||||
|
void ibutton_text_store_clear(iButton* ibutton);
|
||||||
|
void ibutton_switch_to_previous_scene_one_of(
|
||||||
|
iButton* ibutton,
|
||||||
|
const uint32_t* scene_ids,
|
||||||
|
size_t scene_ids_size);
|
||||||
|
void ibutton_notification_message(iButton* ibutton, uint32_t message);
|
||||||
@ -1,140 +0,0 @@
|
|||||||
#include "ibutton_view_manager.h"
|
|
||||||
#include "ibutton_event.h"
|
|
||||||
#include <callback-connector.h>
|
|
||||||
|
|
||||||
iButtonAppViewManager::iButtonAppViewManager() {
|
|
||||||
event_queue = osMessageQueueNew(10, sizeof(iButtonEvent), NULL);
|
|
||||||
|
|
||||||
view_dispatcher = view_dispatcher_alloc();
|
|
||||||
auto callback = cbc::obtain_connector(this, &iButtonAppViewManager::previous_view_callback);
|
|
||||||
|
|
||||||
dialog_ex = dialog_ex_alloc();
|
|
||||||
view_dispatcher_add_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewDialogEx),
|
|
||||||
dialog_ex_get_view(dialog_ex));
|
|
||||||
|
|
||||||
submenu = submenu_alloc();
|
|
||||||
view_dispatcher_add_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewSubmenu),
|
|
||||||
submenu_get_view(submenu));
|
|
||||||
|
|
||||||
text_input = text_input_alloc();
|
|
||||||
view_dispatcher_add_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewTextInput),
|
|
||||||
text_input_get_view(text_input));
|
|
||||||
|
|
||||||
byte_input = byte_input_alloc();
|
|
||||||
view_dispatcher_add_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewByteInput),
|
|
||||||
byte_input_get_view(byte_input));
|
|
||||||
|
|
||||||
popup = popup_alloc();
|
|
||||||
view_dispatcher_add_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewPopup),
|
|
||||||
popup_get_view(popup));
|
|
||||||
|
|
||||||
widget = widget_alloc();
|
|
||||||
view_dispatcher_add_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewWidget),
|
|
||||||
widget_get_view(widget));
|
|
||||||
|
|
||||||
gui = static_cast<Gui*>(furi_record_open("gui"));
|
|
||||||
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
|
||||||
|
|
||||||
//TODO think about that method, seems unsafe and over-engineered
|
|
||||||
view_set_previous_callback(dialog_ex_get_view(dialog_ex), callback);
|
|
||||||
view_set_previous_callback(submenu_get_view(submenu), callback);
|
|
||||||
view_set_previous_callback(text_input_get_view(text_input), callback);
|
|
||||||
view_set_previous_callback(byte_input_get_view(byte_input), callback);
|
|
||||||
view_set_previous_callback(popup_get_view(popup), callback);
|
|
||||||
view_set_previous_callback(widget_get_view(widget), callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
iButtonAppViewManager::~iButtonAppViewManager() {
|
|
||||||
// remove views
|
|
||||||
view_dispatcher_remove_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewDialogEx));
|
|
||||||
view_dispatcher_remove_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewSubmenu));
|
|
||||||
view_dispatcher_remove_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewTextInput));
|
|
||||||
view_dispatcher_remove_view(
|
|
||||||
view_dispatcher, static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewPopup));
|
|
||||||
view_dispatcher_remove_view(
|
|
||||||
view_dispatcher,
|
|
||||||
static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewByteInput));
|
|
||||||
view_dispatcher_remove_view(
|
|
||||||
view_dispatcher, static_cast<uint32_t>(iButtonAppViewManager::Type::iButtonAppViewWidget));
|
|
||||||
|
|
||||||
// free view modules
|
|
||||||
popup_free(popup);
|
|
||||||
text_input_free(text_input);
|
|
||||||
byte_input_free(byte_input);
|
|
||||||
submenu_free(submenu);
|
|
||||||
dialog_ex_free(dialog_ex);
|
|
||||||
widget_free(widget);
|
|
||||||
|
|
||||||
// free dispatcher
|
|
||||||
view_dispatcher_free(view_dispatcher);
|
|
||||||
|
|
||||||
// free event queue
|
|
||||||
osMessageQueueDelete(event_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonAppViewManager::switch_to(Type type) {
|
|
||||||
view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
Submenu* iButtonAppViewManager::get_submenu() {
|
|
||||||
return submenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
Popup* iButtonAppViewManager::get_popup() {
|
|
||||||
return popup;
|
|
||||||
}
|
|
||||||
|
|
||||||
DialogEx* iButtonAppViewManager::get_dialog_ex() {
|
|
||||||
return dialog_ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextInput* iButtonAppViewManager::get_text_input() {
|
|
||||||
return text_input;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteInput* iButtonAppViewManager::get_byte_input() {
|
|
||||||
return byte_input;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget* iButtonAppViewManager::get_widget() {
|
|
||||||
return widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonAppViewManager::receive_event(iButtonEvent* event) {
|
|
||||||
if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) {
|
|
||||||
event->type = iButtonEvent::Type::EventTypeTick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void iButtonAppViewManager::send_event(iButtonEvent* event) {
|
|
||||||
osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0);
|
|
||||||
furi_check(result == osOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t iButtonAppViewManager::previous_view_callback(void* context) {
|
|
||||||
if(event_queue != NULL) {
|
|
||||||
iButtonEvent event;
|
|
||||||
event.type = iButtonEvent::Type::EventTypeBack;
|
|
||||||
send_event(&event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return VIEW_IGNORE;
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <furi.h>
|
|
||||||
#include <gui/view_dispatcher.h>
|
|
||||||
#include <gui/modules/dialog_ex.h>
|
|
||||||
#include <gui/modules/submenu.h>
|
|
||||||
#include <gui/modules/text_input.h>
|
|
||||||
#include <gui/modules/byte_input.h>
|
|
||||||
#include <gui/modules/popup.h>
|
|
||||||
#include <gui/modules/widget.h>
|
|
||||||
#include "ibutton_event.h"
|
|
||||||
|
|
||||||
class iButtonAppViewManager {
|
|
||||||
public:
|
|
||||||
enum class Type : uint8_t {
|
|
||||||
iButtonAppViewTextInput,
|
|
||||||
iButtonAppViewByteInput,
|
|
||||||
iButtonAppViewSubmenu,
|
|
||||||
iButtonAppViewDialogEx,
|
|
||||||
iButtonAppViewPopup,
|
|
||||||
iButtonAppViewWidget,
|
|
||||||
};
|
|
||||||
|
|
||||||
osMessageQueueId_t event_queue;
|
|
||||||
|
|
||||||
iButtonAppViewManager();
|
|
||||||
~iButtonAppViewManager();
|
|
||||||
|
|
||||||
void switch_to(Type type);
|
|
||||||
|
|
||||||
Submenu* get_submenu();
|
|
||||||
Popup* get_popup();
|
|
||||||
DialogEx* get_dialog_ex();
|
|
||||||
TextInput* get_text_input();
|
|
||||||
ByteInput* get_byte_input();
|
|
||||||
Widget* get_widget();
|
|
||||||
|
|
||||||
void receive_event(iButtonEvent* event);
|
|
||||||
void send_event(iButtonEvent* event);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ViewDispatcher* view_dispatcher;
|
|
||||||
DialogEx* dialog_ex;
|
|
||||||
Submenu* submenu;
|
|
||||||
TextInput* text_input;
|
|
||||||
ByteInput* byte_input;
|
|
||||||
Popup* popup;
|
|
||||||
Widget* widget;
|
|
||||||
Gui* gui;
|
|
||||||
|
|
||||||
uint32_t previous_view_callback(void* context);
|
|
||||||
};
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user