Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
commit
e2e4dcc2f8
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@ -96,14 +96,14 @@ jobs:
|
|||||||
|
|
||||||
- name: 'Upload map analyser files to storage'
|
- name: 'Upload map analyser files to storage'
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
uses: keithweaver/aws-s3-github-action@v1.0.0
|
uses: prewk/s3-cp-action@v2
|
||||||
with:
|
with:
|
||||||
source: map_analyser_files/
|
aws_s3_endpoint: "${{ secrets.MAP_REPORT_AWS_ENDPOINT }}"
|
||||||
destination: "s3://${{ secrets.MAP_REPORT_AWS_BUCKET }}/${{steps.names.outputs.random_hash}}"
|
|
||||||
aws_access_key_id: "${{ secrets.MAP_REPORT_AWS_ACCESS_KEY }}"
|
aws_access_key_id: "${{ secrets.MAP_REPORT_AWS_ACCESS_KEY }}"
|
||||||
aws_secret_access_key: "${{ secrets.MAP_REPORT_AWS_SECRET_KEY }}"
|
aws_secret_access_key: "${{ secrets.MAP_REPORT_AWS_SECRET_KEY }}"
|
||||||
aws_region: "${{ secrets.MAP_REPORT_AWS_REGION }}"
|
source: "./map_analyser_files/"
|
||||||
flags: --recursive
|
dest: "s3://${{ secrets.MAP_REPORT_AWS_BUCKET }}/${{steps.names.outputs.random_hash}}"
|
||||||
|
flags: "--recursive --acl public-read"
|
||||||
|
|
||||||
- name: 'Trigger map file reporter'
|
- name: 'Trigger map file reporter'
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
@ -114,7 +114,6 @@ jobs:
|
|||||||
event-type: map-file-analyse
|
event-type: map-file-analyse
|
||||||
client-payload: '{"random_hash": "${{steps.names.outputs.random_hash}}", "event_type": "${{steps.names.outputs.event_type}}"}'
|
client-payload: '{"random_hash": "${{steps.names.outputs.random_hash}}", "event_type": "${{steps.names.outputs.event_type}}"}'
|
||||||
|
|
||||||
|
|
||||||
- name: 'Upload artifacts to update server'
|
- name: 'Upload artifacts to update server'
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
21
.github/workflows/pvs_studio.yml
vendored
21
.github/workflows/pvs_studio.yml
vendored
@ -54,17 +54,16 @@ jobs:
|
|||||||
./fbt COMPACT=1 PVSNOBROWSER=1 firmware_pvs || WARNINGS=1
|
./fbt COMPACT=1 PVSNOBROWSER=1 firmware_pvs || WARNINGS=1
|
||||||
echo "warnings=${WARNINGS}" >> $GITHUB_OUTPUT
|
echo "warnings=${WARNINGS}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: 'Upload artifacts to update server'
|
- name: 'Upload report'
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork && (steps.pvs-warn.outputs.warnings != 0) }}
|
if: ${{ !github.event.pull_request.head.repo.fork && (steps.pvs-warn.outputs.warnings != 0) }}
|
||||||
run: |
|
uses: prewk/s3-cp-action@v2
|
||||||
mkdir -p ~/.ssh
|
with:
|
||||||
ssh-keyscan -p ${{ secrets.RSYNC_DEPLOY_PORT }} -H ${{ secrets.RSYNC_DEPLOY_HOST }} > ~/.ssh/known_hosts
|
aws_s3_endpoint: "${{ secrets.PVS_AWS_ENDPOINT }}"
|
||||||
echo "${{ secrets.RSYNC_DEPLOY_KEY }}" > deploy_key;
|
aws_access_key_id: "${{ secrets.PVS_AWS_ACCESS_KEY }}"
|
||||||
chmod 600 ./deploy_key;
|
aws_secret_access_key: "${{ secrets.PVS_AWS_SECRET_KEY }}"
|
||||||
rsync -avrzP --mkpath \
|
source: "./build/f7-firmware-DC/pvsreport"
|
||||||
-e 'ssh -p ${{ secrets.RSYNC_DEPLOY_PORT }} -i ./deploy_key' \
|
dest: "s3://${{ secrets.PVS_AWS_BUCKET }}/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/"
|
||||||
build/f7-firmware-DC/pvsreport/ ${{ secrets.RSYNC_DEPLOY_USER }}@${{ secrets.RSYNC_DEPLOY_HOST }}:/home/data/firmware-pvs-studio-report/"${BRANCH_NAME}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/";
|
flags: "--recursive --acl public-read"
|
||||||
rm ./deploy_key;
|
|
||||||
|
|
||||||
- name: 'Find Previous Comment'
|
- name: 'Find Previous Comment'
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request && (steps.pvs-warn.outputs.warnings != 0) }}
|
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request && (steps.pvs-warn.outputs.warnings != 0) }}
|
||||||
@ -83,7 +82,7 @@ jobs:
|
|||||||
issue-number: ${{ github.event.pull_request.number }}
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
body: |
|
body: |
|
||||||
**PVS-Studio report for commit `${{steps.names.outputs.commit_sha}}`:**
|
**PVS-Studio report for commit `${{steps.names.outputs.commit_sha}}`:**
|
||||||
- [Report](https://update.flipperzero.one/builds/firmware-pvs-studio-report/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/index.html)
|
- [Report](https://pvs.flipp.dev/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/index.html)
|
||||||
edit-mode: replace
|
edit-mode: replace
|
||||||
|
|
||||||
- name: 'Raise exception'
|
- name: 'Raise exception'
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
App(
|
App(
|
||||||
appid="example_custom_font",
|
appid="example_custom_font",
|
||||||
name="Example: custom font",
|
name="Example: custom font",
|
||||||
apptype=FlipperAppType.EXTERNAL,
|
apptype=FlipperAppType.DEBUG,
|
||||||
entry_point="example_custom_font_main",
|
entry_point="example_custom_font_main",
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
|
|||||||
@ -115,8 +115,12 @@ BadUsbApp* bad_usb_app_alloc(char* arg) {
|
|||||||
|
|
||||||
if(furi_hal_usb_is_locked()) {
|
if(furi_hal_usb_is_locked()) {
|
||||||
app->error = BadUsbAppErrorCloseRpc;
|
app->error = BadUsbAppErrorCloseRpc;
|
||||||
|
app->usb_if_prev = NULL;
|
||||||
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
|
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
|
||||||
} else {
|
} else {
|
||||||
|
app->usb_if_prev = furi_hal_usb_get_config();
|
||||||
|
furi_check(furi_hal_usb_set_config(NULL, NULL));
|
||||||
|
|
||||||
if(!furi_string_empty(app->file_path)) {
|
if(!furi_string_empty(app->file_path)) {
|
||||||
app->bad_usb_script = bad_usb_script_open(app->file_path);
|
app->bad_usb_script = bad_usb_script_open(app->file_path);
|
||||||
bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout);
|
bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout);
|
||||||
@ -138,6 +142,10 @@ void bad_usb_app_free(BadUsbApp* app) {
|
|||||||
app->bad_usb_script = NULL;
|
app->bad_usb_script = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(app->usb_if_prev) {
|
||||||
|
furi_check(furi_hal_usb_set_config(app->usb_if_prev, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWork);
|
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWork);
|
||||||
bad_usb_free(app->bad_usb_view);
|
bad_usb_free(app->bad_usb_view);
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include <gui/modules/variable_item_list.h>
|
#include <gui/modules/variable_item_list.h>
|
||||||
#include <gui/modules/widget.h>
|
#include <gui/modules/widget.h>
|
||||||
#include "views/bad_usb_view.h"
|
#include "views/bad_usb_view.h"
|
||||||
|
#include <furi_hal_usb.h>
|
||||||
|
|
||||||
#define BAD_USB_APP_BASE_FOLDER ANY_PATH("badusb")
|
#define BAD_USB_APP_BASE_FOLDER ANY_PATH("badusb")
|
||||||
#define BAD_USB_APP_PATH_LAYOUT_FOLDER BAD_USB_APP_BASE_FOLDER "/assets/layouts"
|
#define BAD_USB_APP_PATH_LAYOUT_FOLDER BAD_USB_APP_BASE_FOLDER "/assets/layouts"
|
||||||
@ -39,6 +40,8 @@ struct BadUsbApp {
|
|||||||
FuriString* keyboard_layout;
|
FuriString* keyboard_layout;
|
||||||
BadUsb* bad_usb_view;
|
BadUsb* bad_usb_view;
|
||||||
BadUsbScript* bad_usb_script;
|
BadUsbScript* bad_usb_script;
|
||||||
|
|
||||||
|
FuriHalUsbInterface* usb_if_prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@ -490,8 +490,6 @@ static int32_t bad_usb_worker(void* context) {
|
|||||||
BadUsbWorkerState worker_state = BadUsbStateInit;
|
BadUsbWorkerState worker_state = BadUsbStateInit;
|
||||||
int32_t delay_val = 0;
|
int32_t delay_val = 0;
|
||||||
|
|
||||||
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
|
|
||||||
|
|
||||||
FURI_LOG_I(WORKER_TAG, "Init");
|
FURI_LOG_I(WORKER_TAG, "Init");
|
||||||
File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
||||||
bad_usb->line = furi_string_alloc();
|
bad_usb->line = furi_string_alloc();
|
||||||
@ -642,8 +640,6 @@ static int32_t bad_usb_worker(void* context) {
|
|||||||
|
|
||||||
furi_hal_hid_set_state_callback(NULL, NULL);
|
furi_hal_hid_set_state_callback(NULL, NULL);
|
||||||
|
|
||||||
furi_hal_usb_set_config(usb_mode_prev, NULL);
|
|
||||||
|
|
||||||
storage_file_close(script_file);
|
storage_file_close(script_file);
|
||||||
storage_file_free(script_file);
|
storage_file_free(script_file);
|
||||||
furi_string_free(bad_usb->line);
|
furi_string_free(bad_usb->line);
|
||||||
|
|||||||
@ -26,7 +26,7 @@ void nfc_magic_scene_wrong_card_on_enter(void* context) {
|
|||||||
AlignLeft,
|
AlignLeft,
|
||||||
AlignTop,
|
AlignTop,
|
||||||
FontSecondary,
|
FontSecondary,
|
||||||
"Writing is supported\nonly for 4 bytes UID\nMifare CLassic 1k");
|
"Writing is supported\nonly for 4 bytes UID\nMifare Classic 1k");
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
widget, GuiButtonTypeLeft, "Retry", nfc_magic_scene_wrong_card_widget_callback, nfc_magic);
|
widget, GuiButtonTypeLeft, "Retry", nfc_magic_scene_wrong_card_widget_callback, nfc_magic);
|
||||||
|
|
||||||
|
|||||||
@ -58,8 +58,12 @@ bool updater_scene_error_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updater_scene_error_on_exit(void* context) {
|
void updater_scene_error_on_exit(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
Updater* updater = (Updater*)context;
|
Updater* updater = (Updater*)context;
|
||||||
|
|
||||||
widget_reset(updater->widget);
|
widget_reset(updater->widget);
|
||||||
free(updater->pending_update);
|
|
||||||
|
if(updater->loaded_manifest) {
|
||||||
|
update_manifest_free(updater->loaded_manifest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,11 +21,9 @@ void updater_scene_loadcfg_apply_callback(GuiButtonType result, InputType type,
|
|||||||
|
|
||||||
void updater_scene_loadcfg_on_enter(void* context) {
|
void updater_scene_loadcfg_on_enter(void* context) {
|
||||||
Updater* updater = (Updater*)context;
|
Updater* updater = (Updater*)context;
|
||||||
UpdaterManifestProcessingState* pending_upd = updater->pending_update =
|
UpdateManifest* loaded_manifest = updater->loaded_manifest = update_manifest_alloc();
|
||||||
malloc(sizeof(UpdaterManifestProcessingState));
|
|
||||||
pending_upd->manifest = update_manifest_alloc();
|
|
||||||
|
|
||||||
if(update_manifest_init(pending_upd->manifest, furi_string_get_cstr(updater->startup_arg))) {
|
if(update_manifest_init(loaded_manifest, furi_string_get_cstr(updater->startup_arg))) {
|
||||||
widget_add_string_element(
|
widget_add_string_element(
|
||||||
updater->widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, "Update");
|
updater->widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, "Update");
|
||||||
|
|
||||||
@ -37,7 +35,7 @@ void updater_scene_loadcfg_on_enter(void* context) {
|
|||||||
32,
|
32,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
AlignCenter,
|
AlignCenter,
|
||||||
furi_string_get_cstr(pending_upd->manifest->version),
|
furi_string_get_cstr(loaded_manifest->version),
|
||||||
true);
|
true);
|
||||||
|
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
@ -95,13 +93,12 @@ bool updater_scene_loadcfg_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updater_scene_loadcfg_on_exit(void* context) {
|
void updater_scene_loadcfg_on_exit(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
Updater* updater = (Updater*)context;
|
Updater* updater = (Updater*)context;
|
||||||
|
|
||||||
if(updater->pending_update) {
|
|
||||||
update_manifest_free(updater->pending_update->manifest);
|
|
||||||
furi_string_free(updater->pending_update->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
widget_reset(updater->widget);
|
widget_reset(updater->widget);
|
||||||
free(updater->pending_update);
|
|
||||||
|
if(updater->loaded_manifest) {
|
||||||
|
update_manifest_free(updater->loaded_manifest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,12 +33,6 @@ typedef enum {
|
|||||||
UpdaterCustomEventSdUnmounted,
|
UpdaterCustomEventSdUnmounted,
|
||||||
} UpdaterCustomEvent;
|
} UpdaterCustomEvent;
|
||||||
|
|
||||||
typedef struct UpdaterManifestProcessingState {
|
|
||||||
UpdateManifest* manifest;
|
|
||||||
FuriString* message;
|
|
||||||
bool ready_to_be_applied;
|
|
||||||
} UpdaterManifestProcessingState;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// GUI
|
// GUI
|
||||||
Gui* gui;
|
Gui* gui;
|
||||||
@ -49,7 +43,7 @@ typedef struct {
|
|||||||
|
|
||||||
UpdaterMainView* main_view;
|
UpdaterMainView* main_view;
|
||||||
|
|
||||||
UpdaterManifestProcessingState* pending_update;
|
UpdateManifest* loaded_manifest;
|
||||||
UpdatePrepareResult preparation_result;
|
UpdatePrepareResult preparation_result;
|
||||||
|
|
||||||
UpdateTask* update_task;
|
UpdateTask* update_task;
|
||||||
|
|||||||
@ -41,22 +41,22 @@ typedef struct {
|
|||||||
static const UpdateTaskStageGroupMap update_task_stage_progress[] = {
|
static const UpdateTaskStageGroupMap update_task_stage_progress[] = {
|
||||||
[UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0),
|
[UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0),
|
||||||
|
|
||||||
[UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5),
|
[UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 45),
|
||||||
[UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 15),
|
[UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5),
|
||||||
|
|
||||||
[UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15),
|
[UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15),
|
||||||
[UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 60),
|
[UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 35),
|
||||||
[UpdateTaskStageRadioWrite] = STAGE_DEF(UpdateTaskStageGroupRadio, 80),
|
[UpdateTaskStageRadioWrite] = STAGE_DEF(UpdateTaskStageGroupRadio, 60),
|
||||||
[UpdateTaskStageRadioInstall] = STAGE_DEF(UpdateTaskStageGroupRadio, 60),
|
[UpdateTaskStageRadioInstall] = STAGE_DEF(UpdateTaskStageGroupRadio, 30),
|
||||||
[UpdateTaskStageRadioBusy] = STAGE_DEF(UpdateTaskStageGroupRadio, 80),
|
[UpdateTaskStageRadioBusy] = STAGE_DEF(UpdateTaskStageGroupRadio, 5),
|
||||||
|
|
||||||
[UpdateTaskStageOBValidation] = STAGE_DEF(UpdateTaskStageGroupOptionBytes, 10),
|
[UpdateTaskStageOBValidation] = STAGE_DEF(UpdateTaskStageGroupOptionBytes, 2),
|
||||||
|
|
||||||
[UpdateTaskStageValidateDFUImage] = STAGE_DEF(UpdateTaskStageGroupFirmware, 50),
|
[UpdateTaskStageValidateDFUImage] = STAGE_DEF(UpdateTaskStageGroupFirmware, 30),
|
||||||
[UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 200),
|
[UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 150),
|
||||||
[UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 30),
|
[UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 15),
|
||||||
|
|
||||||
[UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 30),
|
[UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5),
|
||||||
|
|
||||||
[UpdateTaskStageResourcesUpdate] = STAGE_DEF(UpdateTaskStageGroupResources, 255),
|
[UpdateTaskStageResourcesUpdate] = STAGE_DEF(UpdateTaskStageGroupResources, 255),
|
||||||
[UpdateTaskStageSplashscreenInstall] = STAGE_DEF(UpdateTaskStageGroupSplashscreen, 5),
|
[UpdateTaskStageSplashscreenInstall] = STAGE_DEF(UpdateTaskStageGroupSplashscreen, 5),
|
||||||
|
|||||||
@ -41,6 +41,14 @@ static bool update_task_pre_update(UpdateTask* update_task) {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UpdateTaskResourcesWeightsFileCleanup = 20,
|
||||||
|
UpdateTaskResourcesWeightsDirCleanup = 20,
|
||||||
|
UpdateTaskResourcesWeightsFileUnpack = 60,
|
||||||
|
} UpdateTaskResourcesWeights;
|
||||||
|
|
||||||
|
#define UPDATE_TASK_RESOURCES_FILE_TO_TOTAL_PERCENT 90
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UpdateTask* update_task;
|
UpdateTask* update_task;
|
||||||
int32_t total_files, processed_files;
|
int32_t total_files, processed_files;
|
||||||
@ -54,33 +62,36 @@ static bool update_task_resource_unpack_cb(const char* name, bool is_directory,
|
|||||||
update_task_set_progress(
|
update_task_set_progress(
|
||||||
unpack_progress->update_task,
|
unpack_progress->update_task,
|
||||||
UpdateTaskStageProgress,
|
UpdateTaskStageProgress,
|
||||||
/* For this stage, last 70% of progress = extraction */
|
/* For this stage, last progress segment = extraction */
|
||||||
30 + (unpack_progress->processed_files * 70) / (unpack_progress->total_files + 1));
|
(UpdateTaskResourcesWeightsFileCleanup + UpdateTaskResourcesWeightsDirCleanup) +
|
||||||
|
(unpack_progress->processed_files * UpdateTaskResourcesWeightsFileUnpack) /
|
||||||
|
(unpack_progress->total_files + 1));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void update_task_cleanup_resources(UpdateTask* update_task, const uint32_t n_tar_entries) {
|
||||||
update_task_cleanup_resources(UpdateTask* update_task, uint32_t n_approx_file_entries) {
|
|
||||||
ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(update_task->storage);
|
ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(update_task->storage);
|
||||||
do {
|
do {
|
||||||
FURI_LOG_I(TAG, "Cleaning up old manifest");
|
FURI_LOG_D(TAG, "Cleaning up old manifest");
|
||||||
if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("Manifest"))) {
|
if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("Manifest"))) {
|
||||||
FURI_LOG_W(TAG, "No existing manifest");
|
FURI_LOG_W(TAG, "No existing manifest");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We got # of entries in TAR file. Approx 1/4th is dir entries, we skip them */
|
const uint32_t n_approx_file_entries =
|
||||||
n_approx_file_entries = n_approx_file_entries * 3 / 4 + 1;
|
n_tar_entries * UPDATE_TASK_RESOURCES_FILE_TO_TOTAL_PERCENT / 100 + 1;
|
||||||
uint32_t n_processed_files = 0;
|
uint32_t n_dir_entries = 1;
|
||||||
|
|
||||||
ResourceManifestEntry* entry_ptr = NULL;
|
ResourceManifestEntry* entry_ptr = NULL;
|
||||||
|
uint32_t n_processed_entries = 0;
|
||||||
while((entry_ptr = resource_manifest_reader_next(manifest_reader))) {
|
while((entry_ptr = resource_manifest_reader_next(manifest_reader))) {
|
||||||
if(entry_ptr->type == ResourceManifestEntryTypeFile) {
|
if(entry_ptr->type == ResourceManifestEntryTypeFile) {
|
||||||
update_task_set_progress(
|
update_task_set_progress(
|
||||||
update_task,
|
update_task,
|
||||||
UpdateTaskStageProgress,
|
UpdateTaskStageProgress,
|
||||||
/* For this stage, first 20% of progress = cleanup files */
|
/* For this stage, first pass = old manifest's file cleanup */
|
||||||
(n_processed_files++ * 20) / (n_approx_file_entries + 1));
|
(n_processed_entries++ * UpdateTaskResourcesWeightsFileCleanup) /
|
||||||
|
n_approx_file_entries);
|
||||||
|
|
||||||
FuriString* file_path = furi_string_alloc();
|
FuriString* file_path = furi_string_alloc();
|
||||||
path_concat(
|
path_concat(
|
||||||
@ -88,16 +99,21 @@ static void
|
|||||||
FURI_LOG_D(TAG, "Removing %s", furi_string_get_cstr(file_path));
|
FURI_LOG_D(TAG, "Removing %s", furi_string_get_cstr(file_path));
|
||||||
storage_simply_remove(update_task->storage, furi_string_get_cstr(file_path));
|
storage_simply_remove(update_task->storage, furi_string_get_cstr(file_path));
|
||||||
furi_string_free(file_path);
|
furi_string_free(file_path);
|
||||||
|
} else if(entry_ptr->type == ResourceManifestEntryTypeDirectory) {
|
||||||
|
n_dir_entries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n_processed_entries = 0;
|
||||||
while((entry_ptr = resource_manifest_reader_previous(manifest_reader))) {
|
while((entry_ptr = resource_manifest_reader_previous(manifest_reader))) {
|
||||||
if(entry_ptr->type == ResourceManifestEntryTypeDirectory) {
|
if(entry_ptr->type == ResourceManifestEntryTypeDirectory) {
|
||||||
update_task_set_progress(
|
update_task_set_progress(
|
||||||
update_task,
|
update_task,
|
||||||
UpdateTaskStageProgress,
|
UpdateTaskStageProgress,
|
||||||
/* For this stage, second 10% of progress = cleanup directories */
|
/* For this stage, second 10% of progress = cleanup directories */
|
||||||
(n_processed_files++ * 10) / (n_approx_file_entries + 1));
|
UpdateTaskResourcesWeightsFileCleanup +
|
||||||
|
(n_processed_entries++ * UpdateTaskResourcesWeightsDirCleanup) /
|
||||||
|
n_dir_entries);
|
||||||
|
|
||||||
FuriString* folder_path = furi_string_alloc();
|
FuriString* folder_path = furi_string_alloc();
|
||||||
File* folder_file = storage_file_alloc(update_task->storage);
|
File* folder_file = storage_file_alloc(update_task->storage);
|
||||||
|
|||||||
@ -340,7 +340,7 @@ static void usb_process_mode_start(FuriHalUsbInterface* interface, void* context
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void usb_process_mode_change(FuriHalUsbInterface* interface, void* context) {
|
static void usb_process_mode_change(FuriHalUsbInterface* interface, void* context) {
|
||||||
if(interface != usb.interface) {
|
if((interface != usb.interface) || (context != usb.interface_context)) {
|
||||||
if(usb.enabled) {
|
if(usb.enabled) {
|
||||||
// Disable current interface
|
// Disable current interface
|
||||||
susp_evt(&udev, 0, 0);
|
susp_evt(&udev, 0, 0);
|
||||||
|
|||||||
@ -237,10 +237,8 @@ void ibutton_worker_emulate_timer_cb(void* context) {
|
|||||||
const LevelDuration level_duration =
|
const LevelDuration level_duration =
|
||||||
protocol_dict_encoder_yield(worker->protocols, worker->protocol_to_encode);
|
protocol_dict_encoder_yield(worker->protocols, worker->protocol_to_encode);
|
||||||
|
|
||||||
const bool level = level_duration_get_level(level_duration);
|
furi_hal_ibutton_emulate_set_next(level_duration_get_duration(level_duration));
|
||||||
|
furi_hal_ibutton_pin_write(level_duration_get_level(level_duration));
|
||||||
furi_hal_ibutton_emulate_set_next(level);
|
|
||||||
furi_hal_ibutton_pin_write(level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ibutton_worker_emulate_timer_start(iButtonWorker* worker) {
|
void ibutton_worker_emulate_timer_start(iButtonWorker* worker) {
|
||||||
|
|||||||
@ -106,6 +106,7 @@ void tar_archive_set_file_callback(TarArchive* archive, tar_unpack_file_cb callb
|
|||||||
static int tar_archive_entry_counter(mtar_t* tar, const mtar_header_t* header, void* param) {
|
static int tar_archive_entry_counter(mtar_t* tar, const mtar_header_t* header, void* param) {
|
||||||
UNUSED(tar);
|
UNUSED(tar);
|
||||||
UNUSED(header);
|
UNUSED(header);
|
||||||
|
furi_assert(param);
|
||||||
int32_t* counter = param;
|
int32_t* counter = param;
|
||||||
(*counter)++;
|
(*counter)++;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
from SCons.Builder import Builder
|
from SCons.Builder import Builder
|
||||||
from SCons.Action import Action
|
from SCons.Action import Action
|
||||||
from SCons.Script import Delete, Mkdir, GetBuildFailures
|
from SCons.Script import Delete, Mkdir, GetBuildFailures, Flatten
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import atexit
|
import atexit
|
||||||
@ -30,13 +30,14 @@ def atexist_handler():
|
|||||||
return
|
return
|
||||||
|
|
||||||
for bf in GetBuildFailures():
|
for bf in GetBuildFailures():
|
||||||
if bf.node.exists and bf.node.name.endswith(".html"):
|
for node in Flatten(bf.node):
|
||||||
# macOS
|
if node.exists and node.name.endswith(".html"):
|
||||||
if sys.platform == "darwin":
|
# macOS
|
||||||
subprocess.run(["open", bf.node.abspath])
|
if sys.platform == "darwin":
|
||||||
else:
|
subprocess.run(["open", node.abspath])
|
||||||
webbrowser.open(bf.node.abspath)
|
else:
|
||||||
break
|
webbrowser.open(node.abspath)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
|||||||
@ -17,7 +17,7 @@ def parse_args():
|
|||||||
|
|
||||||
|
|
||||||
def checkCommitMessage(msg):
|
def checkCommitMessage(msg):
|
||||||
regex = re.compile(r"^'?\[FL-\d+\]")
|
regex = re.compile(r"^'?\[(FL-\d+,?\s?)+\]")
|
||||||
if regex.match(msg):
|
if regex.match(msg):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user