From 356db794b5f219d8fa1b1f58a6ae261676c42d49 Mon Sep 17 00:00:00 2001 From: clipboard1 Date: Tue, 2 May 2023 22:25:05 +0500 Subject: [PATCH 01/28] Added numpad keyboard --- applications/external/hid_app/hid.c | 15 + applications/external/hid_app/hid.h | 2 + applications/external/hid_app/views.h | 1 + .../external/hid_app/views/hid_numpad.c | 302 ++++++++++++++++++ .../external/hid_app/views/hid_numpad.h | 14 + 5 files changed, 334 insertions(+) create mode 100644 applications/external/hid_app/views/hid_numpad.c create mode 100644 applications/external/hid_app/views/hid_numpad.h diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c index f29a3b22a..791f6b2e4 100644 --- a/applications/external/hid_app/hid.c +++ b/applications/external/hid_app/hid.c @@ -9,6 +9,7 @@ enum HidDebugSubmenuIndex { HidSubmenuIndexKeynote, HidSubmenuIndexKeynoteVertical, HidSubmenuIndexKeyboard, + HidSubmenuIndexNumpad, HidSubmenuIndexMedia, HidSubmenuIndexTikTok, HidSubmenuIndexYTShorts, @@ -28,6 +29,9 @@ static void hid_submenu_callback(void* context, uint32_t index) { } else if(index == HidSubmenuIndexKeyboard) { app->view_id = HidViewKeyboard; view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeyboard); + } else if(index == HidSubmenuIndexNumpad) { + app->view_id = HidViewNumpad; + view_dispatcher_switch_to_view(app->view_dispatcher, HidViewNumpad); } else if(index == HidSubmenuIndexMedia) { app->view_id = HidViewMedia; view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMedia); @@ -60,6 +64,7 @@ static void bt_hid_connection_status_changed_callback(BtStatus status, void* con hid_keynote_set_connected_status(hid->hid_keynote, connected); hid_keynote_vertical_set_connected_status(hid->hid_keynote_vertical, connected); hid_keyboard_set_connected_status(hid->hid_keyboard, connected); + hid_numpad_set_connected_status(hid->hid_numpad, connected); hid_media_set_connected_status(hid->hid_media, connected); hid_mouse_set_connected_status(hid->hid_mouse, connected); hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected); @@ -118,6 +123,8 @@ Hid* hid_alloc(HidTransport transport) { app); submenu_add_item( app->device_type_submenu, "Keyboard", HidSubmenuIndexKeyboard, hid_submenu_callback, app); + submenu_add_item( + app->device_type_submenu, "Numpad keyboard", HidSubmenuIndexNumpad, hid_submenu_callback, app); submenu_add_item( app->device_type_submenu, "Media", HidSubmenuIndexMedia, hid_submenu_callback, app); submenu_add_item( @@ -185,6 +192,12 @@ Hid* hid_app_alloc_view(void* context) { view_dispatcher_add_view( app->view_dispatcher, HidViewKeyboard, hid_keyboard_get_view(app->hid_keyboard)); + //Numpad keyboard view + app->hid_numpad = hid_numpad_alloc(app); + view_set_previous_callback(hid_numpad_get_view(app->hid_numpad), hid_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, HidViewNumpad, hid_numpad_get_view(app->hid_numpad)); + // Media view app->hid_media = hid_media_alloc(app); view_set_previous_callback(hid_media_get_view(app->hid_media), hid_exit_confirm_view); @@ -240,6 +253,8 @@ void hid_free(Hid* app) { hid_keynote_vertical_free(app->hid_keynote_vertical); view_dispatcher_remove_view(app->view_dispatcher, HidViewKeyboard); hid_keyboard_free(app->hid_keyboard); + view_dispatcher_remove_view(app->view_dispatcher, HidViewNumpad); + hid_numpad_free(app->hid_numpad); view_dispatcher_remove_view(app->view_dispatcher, HidViewMedia); hid_media_free(app->hid_media); view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse); diff --git a/applications/external/hid_app/hid.h b/applications/external/hid_app/hid.h index be9176a28..3478a5194 100644 --- a/applications/external/hid_app/hid.h +++ b/applications/external/hid_app/hid.h @@ -19,6 +19,7 @@ #include "views/hid_keynote.h" #include "views/hid_keynote_vertical.h" #include "views/hid_keyboard.h" +#include "views/hid_numpad.h" #include "views/hid_media.h" #include "views/hid_mouse.h" #include "views/hid_mouse_jiggler.h" @@ -44,6 +45,7 @@ struct Hid { HidKeynote* hid_keynote; HidKeynoteVertical* hid_keynote_vertical; HidKeyboard* hid_keyboard; + HidNumpad* hid_numpad; HidMedia* hid_media; HidMouse* hid_mouse; HidMouseJiggler* hid_mouse_jiggler; diff --git a/applications/external/hid_app/views.h b/applications/external/hid_app/views.h index 81e8d6dbe..ec4d23ad9 100644 --- a/applications/external/hid_app/views.h +++ b/applications/external/hid_app/views.h @@ -3,6 +3,7 @@ typedef enum { HidViewKeynote, HidViewKeynoteVertical, HidViewKeyboard, + HidViewNumpad, HidViewMedia, HidViewMouse, HidViewMouseJiggler, diff --git a/applications/external/hid_app/views/hid_numpad.c b/applications/external/hid_app/views/hid_numpad.c new file mode 100644 index 000000000..d3b488801 --- /dev/null +++ b/applications/external/hid_app/views/hid_numpad.c @@ -0,0 +1,302 @@ +#include "hid_numpad.h" +#include +#include +#include +#include "../hid.h" +#include "hid_icons.h" + +#define TAG "HidNumpad" + +struct HidNumpad { + View* view; + Hid* hid; +}; + +typedef struct { + uint8_t last_x; + uint8_t last_y; + uint8_t x; + uint8_t y; + uint8_t last_key_code; + uint16_t modifier_code; + bool ok_pressed; + bool back_pressed; + bool connected; + char key_string[5]; + HidTransport transport; +} HidNumpadModel; + +typedef struct { + uint8_t width; + char* key; + uint8_t height; + const Icon* icon; + uint8_t value; +} HidNumpadKey; + +typedef struct { + int8_t x; + int8_t y; +} HidNumpadPoint; + +#define MARGIN_TOP 0 +#define MARGIN_LEFT 24 +#define KEY_WIDTH 20 +#define KEY_HEIGHT 15 +#define KEY_PADDING 1 +#define ROW_COUNT 5 +#define COLUMN_COUNT 4 + +const HidNumpadKey hid_numpad_keyset[ROW_COUNT][COLUMN_COUNT] = { + { + {.width = 1, .height = 1, .icon = NULL, .key = "NL", .value = HID_KEYPAD_NUMLOCK}, + {.width = 1, .height = 1, .icon = NULL, .key = "/", .value = HID_KEYPAD_SLASH}, + {.width = 1, .height = 1, .icon = NULL, .key = "*", .value = HID_KEYPAD_ASTERISK}, + {.width = 1, .height = 1, .icon = NULL, .key = "-", .value = HID_KEYPAD_MINUS}, + }, + { + {.width = 1, .height = 1, .icon = NULL, .key = "7", .value = HID_KEYPAD_7}, + {.width = 1, .height = 1, .icon = NULL, .key = "8", .value = HID_KEYBOARD_8}, + {.width = 1, .height = 1, .icon = NULL, .key = "9", .value = HID_KEYBOARD_9}, + {.width = 1, .height = 2, .icon = NULL, .key = "+", .value = HID_KEYPAD_PLUS}, + }, + { + {.width = 1, .height = 1, .icon = NULL, .key = "4", .value = HID_KEYPAD_4}, + {.width = 1, .height = 1, .icon = NULL, .key = "5", .value = HID_KEYPAD_5}, + {.width = 1, .height = 1, .icon = NULL, .key = "6", .value = HID_KEYPAD_6}, + }, + { + {.width = 1, .height = 1, .icon = NULL, .key = "1", .value = HID_KEYPAD_1}, + {.width = 1, .height = 1, .icon = NULL, .key = "2", .value = HID_KEYPAD_2}, + {.width = 1, .height = 1, .icon = NULL, .key = "3", .value = HID_KEYPAD_3}, + {.width = 1, .height = 2, .icon = NULL, .key = "En", .value = HID_KEYPAD_ENTER}, + }, + { + {.width = 2, .height = 1, .icon = NULL, .key = "0", .value = HID_KEYBOARD_0}, + {.width = 0, .height = 0, .icon = NULL, .key = "0", .value = HID_KEYBOARD_0}, + {.width = 1, .height = 1, .icon = NULL, .key = ".", .value = HID_KEYPAD_DOT}, + }, +}; + +static void hid_numpad_draw_key( + Canvas* canvas, + HidNumpadModel* model, + uint8_t x, + uint8_t y, + HidNumpadKey key, + bool selected) { + if(!key.width || !key.height) return; + + canvas_set_color(canvas, ColorBlack); + uint8_t keyWidth = KEY_WIDTH * key.width + KEY_PADDING * (key.width - 1); + uint8_t keyHeight = KEY_HEIGHT * key.height + KEY_PADDING * (key.height - 1); + if(selected) { + elements_slightly_rounded_box( + canvas, + MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING), + MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING), + keyWidth, + keyHeight); + canvas_set_color(canvas, ColorWhite); + } else { + elements_slightly_rounded_frame( + canvas, + MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING), + MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING), + keyWidth, + keyHeight); + } + if(key.icon != NULL) { + canvas_draw_icon( + canvas, + MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key.icon->width / 2, + MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + keyHeight / 2 - key.icon->height / 2, + key.icon); + } else { + strcpy(model->key_string, key.key); + canvas_draw_str_aligned( + canvas, + MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1, + MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + keyHeight / 2 + 1, + AlignCenter, + AlignCenter, + model->key_string); + } +} + +static void hid_numpad_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + HidNumpadModel* model = context; + + if((!model->connected) && (model->transport == HidTransportBle)) { + canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Numpad"); + + canvas_draw_icon(canvas, 68, 3, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 127, 4, AlignRight, AlignTop, "Hold to exit"); + + elements_multiline_text_aligned( + canvas, 4, 60, AlignLeft, AlignBottom, "Waiting for Connection..."); + return; + } + + canvas_set_font(canvas, FontKeyboard); + uint8_t initY = model->y == 0 ? 0 : 1; + + if(model->y > 5) { + initY = model->y - 4; + } + + for(uint8_t y = initY; y < ROW_COUNT; y++) { + const HidNumpadKey* numpadKeyRow = hid_numpad_keyset[y]; + uint8_t x = 0; + for(uint8_t i = 0; i < COLUMN_COUNT; i++) { + HidNumpadKey key = numpadKeyRow[i]; + bool keySelected = (x <= model->x && model->x < (x + key.width)) && y == model->y; + bool backSelected = model->back_pressed && key.value == HID_KEYBOARD_DELETE; + hid_numpad_draw_key( + canvas, + model, + x, + y - initY, + key, + (!model->ok_pressed && keySelected) || backSelected); + x += key.width; + } + } +} + +static uint8_t hid_numpad_get_selected_key(HidNumpadModel* model) { + HidNumpadKey key = hid_numpad_keyset[model->y][model->x]; + return key.value; +} + +static void hid_numpad_get_select_key(HidNumpadModel* model, HidNumpadPoint delta) { + do { + const int delta_sum = model->y + delta.y; + model->y = delta_sum < 0 ? ROW_COUNT - 1 : delta_sum % ROW_COUNT; + } while(delta.y != 0 && hid_numpad_keyset[model->y][model->x].value == 0); + + do { + const int delta_sum = model->x + delta.x; + model->x = delta_sum < 0 ? COLUMN_COUNT - 1 : delta_sum % COLUMN_COUNT; + } while(delta.x != 0 && hid_numpad_keyset[model->y][model->x].width == 0); +} + +static void hid_numpad_process(HidNumpad* hid_numpad, InputEvent* event) { + with_view_model( + hid_numpad->view, + HidNumpadModel * model, + { + if(event->key == InputKeyOk) { + if(event->type == InputTypePress) { + model->ok_pressed = true; + } else if(event->type == InputTypeLong || event->type == InputTypeShort) { + model->last_key_code = hid_numpad_get_selected_key(model); + hid_hal_keyboard_press( + hid_numpad->hid, model->modifier_code | model->last_key_code); + } else if(event->type == InputTypeRelease) { + hid_hal_keyboard_release( + hid_numpad->hid, model->modifier_code | model->last_key_code); + model->ok_pressed = false; + } + } else if(event->key == InputKeyBack) { + if(event->type == InputTypePress) { + model->back_pressed = true; + } else if(event->type == InputTypeShort) { + hid_hal_keyboard_press(hid_numpad->hid, HID_KEYBOARD_DELETE); + hid_hal_keyboard_release(hid_numpad->hid, HID_KEYBOARD_DELETE); + } else if(event->type == InputTypeRelease) { + model->back_pressed = false; + } + } else if(event->type == InputTypePress || event->type == InputTypeRepeat) { + if(event->key == InputKeyUp) { + hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 0, .y = -1}); + } else if(event->key == InputKeyDown) { + hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 0, .y = 1}); + } else if(event->key == InputKeyLeft) { + if(model->last_x == 2 && model->last_y == 2 && model->y == 1 && + model->x == 3) { + model->x = model->last_x; + model->y = model->last_y; + } else if( + model->last_x == 2 && model->last_y == 4 && model->y == 3 && + model->x == 3) { + model->x = model->last_x; + model->y = model->last_y; + } else + hid_numpad_get_select_key(model, (HidNumpadPoint){.x = -1, .y = 0}); + model->last_x = 0; + model->last_y = 0; + } else if(event->key == InputKeyRight) { + if(model->x == 2 && model->y == 2) { + model->last_x = model->x; + model->last_y = model->y; + hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 1, .y = -1}); + } else if(model->x == 2 && model->y == 4) { + model->last_x = model->x; + model->last_y = model->y; + hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 1, .y = -1}); + } else { + hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 1, .y = 0}); + } + } + } + }, + true); +} + +static bool hid_numpad_input_callback(InputEvent* event, void* context) { + furi_assert(context); + HidNumpad* hid_numpad = context; + bool consumed = false; + + if(event->type == InputTypeLong && event->key == InputKeyBack) { + hid_hal_keyboard_release_all(hid_numpad->hid); + } else { + hid_numpad_process(hid_numpad, event); + consumed = true; + } + + return consumed; +} + +HidNumpad* hid_numpad_alloc(Hid* bt_hid) { + HidNumpad* hid_numpad = malloc(sizeof(HidNumpad)); + hid_numpad->view = view_alloc(); + hid_numpad->hid = bt_hid; + view_set_context(hid_numpad->view, hid_numpad); + view_allocate_model(hid_numpad->view, ViewModelTypeLocking, sizeof(HidNumpadModel)); + view_set_draw_callback(hid_numpad->view, hid_numpad_draw_callback); + view_set_input_callback(hid_numpad->view, hid_numpad_input_callback); + + with_view_model( + hid_numpad->view, + HidNumpadModel * model, + { + model->transport = bt_hid->transport; + model->y = 0; + }, + true); + + return hid_numpad; +} + +void hid_numpad_free(HidNumpad* hid_numpad) { + furi_assert(hid_numpad); + view_free(hid_numpad->view); + free(hid_numpad); +} + +View* hid_numpad_get_view(HidNumpad* hid_numpad) { + furi_assert(hid_numpad); + return hid_numpad->view; +} + +void hid_numpad_set_connected_status(HidNumpad* hid_numpad, bool connected) { + furi_assert(hid_numpad); + with_view_model( + hid_numpad->view, HidNumpadModel * model, { model->connected = connected; }, true); +} diff --git a/applications/external/hid_app/views/hid_numpad.h b/applications/external/hid_app/views/hid_numpad.h new file mode 100644 index 000000000..d9bf54df9 --- /dev/null +++ b/applications/external/hid_app/views/hid_numpad.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +typedef struct Hid Hid; +typedef struct HidNumpad HidNumpad; + +HidNumpad* hid_numpad_alloc(Hid* bt_hid); + +void hid_numpad_free(HidNumpad* hid_numpad); + +View* hid_numpad_get_view(HidNumpad* hid_numpad); + +void hid_numpad_set_connected_status(HidNumpad* hid_numpad, bool connected); From 259855e7885ce9d7866fbe0b907313edba260cee Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Tue, 2 May 2023 20:52:41 +0100 Subject: [PATCH 02/28] Updated ac.ir New additions --- assets/resources/infrared/assets/ac.ir | 34 ++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 49a4acd20..777d5399c 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 14th Apr, 2023 -# Last Checked 25th Apr, 2023 +# Last Updated 2nd May, 2023 +# Last Checked 2nd May, 2023 # name: POWER type: raw @@ -1740,3 +1740,33 @@ type: parsed protocol: NEC address: 04 00 00 00 command: 00 00 00 00 +# +name: TEMP+ +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 443 457 418 451 424 445 420 449 416 453 422 25403 3487 1758 421 1325 416 445 420 452 423 446 419 1319 422 447 418 450 415 456 419 449 416 1323 418 454 421 1316 414 1326 415 462 424 1307 423 1315 415 1323 418 1322 419 1321 420 449 416 452 423 1316 414 455 420 448 417 453 422 447 418 452 423 448 417 451 424 443 422 450 415 452 423 445 420 450 415 456 419 450 415 452 423 447 418 450 415 456 419 1318 423 447 418 454 421 445 420 450 415 453 422 446 419 451 424 1315 415 1324 417 454 421 446 419 1321 420 1319 422 448 417 452 423 445 420 449 416 453 422 448 417 452 423 445 420 449 416 455 420 1319 422 1314 416 1325 416 1322 419 1322 419 1318 423 1317 424 447 418 1320 421 1317 424 1317 424 1315 415 455 420 449 416 452 423 447 418 451 414 454 421 448 417 453 422 448 417 452 423 444 421 449 416 452 423 447 418 453 422 445 420 450 415 456 419 448 417 453 422 446 419 450 415 455 420 450 415 453 422 448 417 452 423 444 421 448 417 454 421 446 419 452 423 445 420 450 415 453 422 447 418 451 424 446 419 449 416 454 421 447 418 452 423 446 419 452 423 1315 415 451 424 1316 414 456 419 451 414 453 422 1317 424 1316 425 444 421 447 418 452 423 448 417 450 415 455 420 456 419 449 416 446 419 451 414 455 420 1320 421 447 418 452 423 453 422 439 415 1324 417 459 416 446 419 451 424 446 419 1320 421 446 419 1319 422 +# +name: TEMP- +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 444 455 420 449 416 454 421 448 417 451 424 25402 3487 1758 421 1317 424 445 420 452 423 443 422 1317 424 447 418 451 424 447 418 449 416 1324 417 452 423 1315 415 1324 417 452 423 1316 425 1315 415 1325 416 1323 418 1319 422 449 416 452 423 1318 423 445 420 448 417 453 422 447 418 452 423 446 419 449 416 455 420 447 418 453 422 446 419 452 423 446 419 451 424 444 421 447 418 451 424 445 420 1320 421 448 417 454 421 445 420 452 423 445 420 450 415 454 421 1316 414 1324 417 454 421 448 417 1321 420 1320 421 448 417 453 422 446 419 452 423 446 419 449 416 455 420 448 417 451 424 445 420 1321 420 1319 422 1316 414 1324 417 1324 417 1321 420 1320 421 449 416 1323 418 1323 418 1319 422 1317 424 446 419 453 422 445 420 450 415 453 422 448 417 452 423 447 418 450 415 455 420 448 417 454 421 445 420 451 414 455 420 449 416 454 421 448 417 452 423 446 419 449 416 454 421 447 418 452 423 445 420 450 415 454 421 450 415 454 421 447 418 452 423 444 421 451 424 442 423 449 416 451 424 445 420 450 415 455 420 448 417 454 421 447 418 450 415 457 418 1317 424 448 417 1320 421 448 417 453 422 449 416 1321 420 1320 421 448 417 452 423 449 416 451 424 446 419 448 417 454 421 449 416 452 423 447 418 452 423 1315 415 452 423 447 418 451 424 446 419 1319 422 448 417 451 424 446 419 449 416 1324 417 453 422 1316 414 +# SWING_HORIZONTAL +name: SWING +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 446 455 420 449 416 461 393 467 419 454 421 25402 3484 1759 419 1319 422 449 416 454 421 447 418 1322 419 449 416 454 421 449 416 452 423 1317 424 444 421 1321 420 1316 425 446 419 1329 422 1308 422 1318 422 1317 424 1314 416 453 422 447 418 1323 418 451 424 444 421 448 417 454 421 449 416 458 417 444 421 449 416 454 421 447 418 453 422 446 419 456 419 445 420 448 417 452 423 446 419 451 424 1316 414 453 422 447 418 453 422 446 419 451 414 455 420 449 416 1324 417 1321 420 452 423 444 421 1318 423 1317 423 445 420 450 415 455 420 447 418 455 420 447 418 451 424 445 420 456 419 444 421 1317 424 1316 424 1315 415 1323 417 452 423 1316 414 456 419 1318 423 448 417 452 423 444 421 450 415 456 419 448 417 453 422 447 418 450 415 454 421 448 417 454 421 446 419 452 423 446 419 449 416 455 420 448 417 452 423 448 417 451 424 451 424 445 420 444 421 447 418 460 415 446 419 451 424 446 419 450 415 454 421 449 416 1321 420 451 424 444 421 449 416 453 422 447 418 454 421 445 420 449 416 456 419 449 416 452 423 447 418 451 424 444 421 451 424 1314 416 453 422 1324 417 445 420 449 416 453 422 1319 422 1315 415 455 420 448 417 452 423 453 422 442 423 451 424 439 415 454 421 447 418 451 424 447 418 1322 418 451 424 442 423 448 417 451 424 1317 423 1315 415 454 421 449 416 460 415 446 419 1320 421 1319 422 +# OFF +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 445 455 421 449 416 453 422 447 418 451 424 25400 3494 1753 416 1322 419 450 415 456 420 449 416 1325 416 451 425 444 421 448 417 453 423 1318 423 444 421 1320 421 1316 414 457 419 1320 421 1318 423 1314 417 1322 419 1320 421 449 416 453 422 1317 424 445 420 450 415 456 419 447 418 451 414 456 420 449 416 452 424 448 417 453 422 445 420 450 415 456 419 448 417 452 423 447 418 449 416 453 423 448 417 453 423 446 419 449 416 453 423 447 418 1321 420 451 414 454 422 449 416 1322 419 1319 422 449 416 1322 419 451 424 445 420 449 416 455 421 445 420 449 416 455 420 448 417 452 424 446 419 1321 420 1317 424 1315 416 1324 417 1322 419 1320 421 1320 421 446 419 1319 422 1319 422 1318 423 1313 417 453 423 445 420 450 415 454 421 449 416 454 422 446 419 449 416 456 420 448 417 453 423 444 421 450 415 454 422 447 418 451 424 445 420 450 415 455 420 447 418 452 424 447 418 451 424 445 420 448 417 453 423 446 419 451 424 444 421 448 417 452 423 446 419 451 424 445 420 448 417 451 414 456 420 452 424 443 422 449 416 451 424 448 417 449 416 455 420 1318 423 446 419 1319 422 448 417 451 424 447 418 1320 421 1316 415 455 421 451 414 455 421 449 416 451 424 446 419 1319 422 448 417 454 422 446 419 451 414 1325 416 452 423 447 418 451 424 447 418 1318 423 446 419 449 416 1327 424 1312 419 449 416 455 421 449 416 +# OFF +name: POWER +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 645 17766 3059 8884 533 461 557 1427 560 435 584 433 534 458 534 458 534 458 588 404 587 405 586 1399 586 407 584 408 558 1429 555 1457 502 491 525 1460 528 1458 554 1431 554 1431 555 1431 554 438 555 438 554 439 553 440 553 464 528 464 528 464 529 465 528 465 526 467 526 467 527 465 553 439 554 439 554 438 554 439 554 439 553 439 554 439 553 439 553 439 554 440 552 464 528 464 528 465 528 466 527 466 501 492 525 468 526 466 527 466 553 439 554 439 553 440 552 1433 553 1433 553 2936 3024 8893 552 1458 527 465 528 465 527 467 526 467 500 493 524 468 526 467 526 467 552 1434 552 441 552 441 552 1435 550 465 528 1458 527 1458 528 1459 527 1485 501 1485 500 1486 501 491 527 466 528 465 528 465 527 465 528 465 527 465 528 465 528 465 527 465 528 465 527 466 527 466 527 492 500 492 501 492 500 493 500 493 500 492 526 466 527 465 527 465 527 465 527 466 527 466 527 466 527 465 527 466 526 466 527 466 526 467 526 493 499 493 474 518 499 494 500 493 526 2936 3025 8918 526 1459 527 466 527 466 527 466 526 466 527 466 526 467 526 467 525 467 526 1460 525 493 499 493 498 495 498 495 499 493 500 493 525 1460 527 1460 525 1460 526 1460 525 1460 526 1460 526 468 525 1487 499 1487 497 495 498 495 499 493 500 1486 525 1460 525 1460 525 467 525 467 526 467 525 467 526 468 524 1462 524 468 524 494 498 1488 497 1488 499 494 499 493 525 468 525 1461 524 468 525 468 524 468 525 468 525 468 524 468 525 469 524 494 498 494 499 1488 473 1514 524 From bf0e8534132794962a21e54b734567704166d175 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Tue, 2 May 2023 20:53:25 +0100 Subject: [PATCH 03/28] Updated audio.ir Updated last checked, no new additions --- assets/resources/infrared/assets/audio.ir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index f6183ed86..ce6d0a7aa 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 # Last Updated 14th Apr, 2023 -# Last Checked 25th Apr, 2023 +# Last Checked 2nd May, 2023 # name: POWER type: parsed From 7ba96ad653197f9f98c367f829b67f0471657d0e Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Tue, 2 May 2023 20:53:48 +0100 Subject: [PATCH 04/28] Updated fans.ir New additions --- assets/resources/infrared/assets/fans.ir | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/fans.ir b/assets/resources/infrared/assets/fans.ir index 6bef11b34..e422bdce4 100644 --- a/assets/resources/infrared/assets/fans.ir +++ b/assets/resources/infrared/assets/fans.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 14th Apr, 2023 -# Last Checked 25th Apr, 2023 +# Last Updated 2nd May, 2023 +# Last Checked 2nd May, 2023 # name: POWER type: raw @@ -1497,3 +1497,9 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 3534 3439 954 2505 985 2535 955 798 954 2535 899 2591 899 2599 899 853 925 2566 924 2567 922 2596 894 2596 894 867 894 859 894 860 893 2597 894 859 894 859 894 867 894 2597 893 859 894 859 894 860 893 859 894 2605 894 40336 3531 3469 894 2597 893 2597 893 859 894 2597 893 2597 893 2605 893 860 893 2597 893 2597 893 2597 894 2597 893 868 893 860 893 860 893 2597 893 860 893 860 893 868 893 2597 893 860 893 860 893 860 893 860 893 2605 893 +# +name: POWER +type: parsed +protocol: NEC +address: 80 00 00 00 +command: 1A 00 00 00 From 79566b7fa31a1cef5465b4f5ffc1369cb40dd36b Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Tue, 2 May 2023 20:54:15 +0100 Subject: [PATCH 05/28] Updated projectors.ir New additions --- .../resources/infrared/assets/projectors.ir | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/projectors.ir b/assets/resources/infrared/assets/projectors.ir index 00e331bd4..8e81a25bd 100644 --- a/assets/resources/infrared/assets/projectors.ir +++ b/assets/resources/infrared/assets/projectors.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 14th Apr, 2023 -# Last Checked 25th Apr, 2023 +# Last Updated 2nd May, 2023 +# Last Checked 2nd May, 2023 # # ON name: POWER @@ -886,3 +886,27 @@ type: parsed protocol: NECext address: 84 F4 00 00 command: 2F D0 00 00 +# +name: MUTE +type: parsed +protocol: NECext +address: 4F 50 00 00 +command: 0F F0 00 00 +# +name: POWER +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 12 00 00 00 +# +name: VOL- +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 06 00 00 00 +# +name: VOL+ +type: parsed +protocol: NEC +address: 02 00 00 00 +command: 00 00 00 00 From dd6c031a3186dda25f92c5ea27a8053bb5a36451 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Tue, 2 May 2023 21:00:24 +0100 Subject: [PATCH 06/28] Updated tv.ir New additions, Added full sharp tv support. Reverted Vizio raw data change, will add this if needed --- assets/resources/infrared/assets/tv.ir | 68 ++++++++++++++++++++------ 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/assets/resources/infrared/assets/tv.ir b/assets/resources/infrared/assets/tv.ir index bd246f3d6..8c781eea9 100755 --- a/assets/resources/infrared/assets/tv.ir +++ b/assets/resources/infrared/assets/tv.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 2, May, 2023 -# Last Checked 2, May, 2023 +# Last Updated 2nd May, 2023 +# Last Checked 2nd May, 2023 # name: POWER type: parsed @@ -1899,39 +1899,77 @@ type: parsed protocol: SIRC20 address: 10 01 00 00 command: 33 00 00 00 +# +# Sharp TV # name: POWER +type: parsed +protocol: NECext +address: 00 BD 00 00 +command: 01 FE 00 00 +# +name: VOL+ +type: parsed +protocol: NECext +address: 00 BD 00 00 +command: 0C F3 00 00 +# +name: VOL- +type: parsed +protocol: NECext +address: 00 BD 00 00 +command: 10 EF 00 00 +# +name: CH+ +type: parsed +protocol: NECext +address: 00 BD 00 00 +command: 18 E7 00 00 +# +name: CH- +type: parsed +protocol: NECext +address: 00 BD 00 00 +command: 1C E3 00 00 +# +name: MUTE +type: parsed +protocol: NECext +address: 00 BD 00 00 +command: 04 FB 00 00 +# +name: POWER type: raw frequency: 38000 duty_cycle: 0.330000 -data: 195 1833 300 766 280 760 275 790 276 737 309 731 304 1801 301 1804 309 731 304 1801 270 795 282 758 277 762 273 1832 270 769 246 45851 326 1780 302 739 307 785 282 732 303 736 310 1795 307 732 303 763 303 1775 307 733 334 1798 273 1832 270 1810 251 814 273 1780 281 43762 302 1804 309 758 277 737 330 762 284 730 305 734 301 1803 310 1796 306 733 302 1829 273 767 279 734 301 791 275 1804 278 762 253 45870 307 1798 304 763 272 767 279 787 279 760 275 1829 284 730 305 734 301 1804 309 757 278 1827 275 1804 278 1828 274 765 270 1835 278 43740 303 1776 306 787 279 760 275 765 281 759 307 758 277 1775 307 1799 303 736 299 1832 281 759 276 763 304 736 299 1832 281 733 302 45820 306 1800 302 764 282 758 277 788 278 762 284 1821 281 732 303 736 310 1796 307 733 302 1829 273 1806 276 1830 272 767 268 1837 245 43772 302 1778 304 789 277 762 284 756 279 786 249 765 301 1777 336 1770 301 764 282 1824 278 761 274 765 301 738 308 1824 278 761 274 +data: 278 1811 277 788 246 794 250 764 280 786 248 792 252 1813 275 1815 273 791 253 1812 276 789 255 785 249 791 253 1812 276 789 255 45322 280 1809 279 786 248 766 278 788 246 794 250 1815 273 792 252 788 246 1819 280 785 249 1817 271 1819 280 1810 278 787 247 1818 281 43217 274 1818 270 794 250 764 280 786 248 792 252 788 256 1809 279 1811 277 788 246 1819 280 785 249 766 278 762 272 1819 280 785 248 # name: MUTE type: raw frequency: 38000 duty_cycle: 0.330000 -data: 254 1721 360 681 354 738 308 706 329 711 355 1774 307 1772 361 1744 327 687 359 1772 299 742 335 705 330 736 279 1825 298 742 283 44773 384 1721 360 707 308 707 359 733 302 711 335 705 361 704 331 708 338 1766 336 704 331 1773 329 1776 306 1773 360 681 323 1782 331 44726 411 1722 328 686 360 733 302 711 335 705 361 1742 329 1803 330 1749 332 708 327 1777 335 705 330 710 325 741 274 1830 303 737 278 44778 359 1747 355 712 303 711 355 711 335 705 330 709 337 703 363 703 332 1770 332 709 337 1767 335 1771 300 1752 360 733 302 1776 326 44731 355 1751 330 711 355 737 309 705 330 710 336 1793 309 1771 331 1774 307 706 360 1771 300 740 326 714 332 735 280 1798 325 741 274 -# -name: POWER -type: raw -frequency: 38000 -duty_cycle: 0.330000 -data: 9219 4484 662 469 661 469 661 1627 660 471 658 474 656 499 631 499 631 499 631 1657 630 1657 631 500 630 1657 631 1657 631 1657 630 1657 631 1657 631 500 630 500 630 500 630 1657 630 500 631 500 630 500 631 500 630 1657 630 1658 630 1657 631 500 630 1657 631 1658 630 1658 630 1658 630 40107 9106 2202 631 +data: 278 1812 276 762 282 758 276 765 279 761 273 1818 281 1809 279 1811 277 762 282 1809 279 760 274 766 278 762 282 1809 279 760 274 44279 276 1813 275 763 281 759 275 766 278 762 272 768 276 764 280 760 274 1817 271 768 276 1815 273 1817 271 1819 280 759 275 1816 272 44276 279 1812 276 763 281 758 276 765 279 761 273 1818 281 1810 278 1811 277 762 272 1819 279 760 274 766 278 762 282 1809 279 760 274 # name: VOL+ type: raw frequency: 38000 duty_cycle: 0.330000 -data: 9218 4484 636 495 660 469 661 1627 660 471 658 472 658 474 656 475 655 474 656 1632 655 1632 656 474 657 1632 656 1631 657 1632 656 1631 656 1632 656 474 656 1632 655 475 656 474 657 474 656 474 656 474 656 474 656 1632 655 474 656 1632 656 1632 656 1632 656 1632 656 1632 656 1632 656 40103 9107 2177 655 -# +data: 272 1817 271 794 250 790 254 786 248 792 252 762 272 794 250 1815 273 792 252 1813 275 790 254 785 249 766 278 1813 275 789 255 46372 273 1817 271 794 250 763 281 785 248 792 252 1813 275 1814 274 791 253 1812 276 789 255 1810 278 1812 276 1813 275 790 254 1811 277 42170 277 1814 274 791 253 787 247 793 251 763 281 759 275 791 253 1812 276 789 255 1810 278 787 247 793 251 789 255 1810 278 787 247 +# name: VOL- type: raw frequency: 38000 duty_cycle: 0.330000 -data: 9245 4429 689 467 662 468 661 1626 660 471 658 473 657 474 656 474 656 474 656 1631 657 1631 657 474 656 1631 656 1632 656 1631 657 1631 657 1631 656 1632 656 1631 657 474 656 474 656 474 657 474 656 474 656 474 657 474 656 474 656 1631 656 1632 656 1632 656 1632 656 1632 656 1631 656 40082 9109 2175 656 +data: 275 1814 274 791 253 787 247 793 251 789 255 1810 278 787 247 1818 281 785 249 1816 272 793 251 789 255 785 249 1816 272 766 278 45325 274 1815 273 792 252 762 272 794 250 790 254 786 247 1818 270 794 250 1815 273 792 252 1813 275 1815 273 1816 272 793 251 1814 274 43224 277 1814 274 764 280 786 248 792 252 788 246 1820 279 786 247 1817 271 768 276 1815 273 792 252 761 273 794 250 1815 273 791 253 # -name: MUTE +name: CH+ type: raw frequency: 38000 duty_cycle: 0.330000 -data: 9219 4485 636 495 660 469 661 1626 661 471 658 473 657 474 656 499 631 500 630 1657 630 1657 631 500 630 1657 630 1657 631 1657 631 1657 630 1657 631 1657 631 500 630 500 630 1657 631 500 630 500 630 500 630 500 631 500 630 1657 631 1657 631 500 630 1657 631 1658 630 1657 631 1658 630 39868 9106 2178 655 +data: 272 1817 271 794 250 790 254 786 248 792 252 1813 275 790 254 759 275 792 252 1813 275 789 255 785 248 792 252 1813 275 789 255 46372 273 1817 271 793 251 763 281 759 275 791 253 787 247 1818 281 1810 278 1812 276 789 255 1809 279 1811 277 1813 275 790 254 1811 277 42169 277 1815 273 792 252 787 247 794 250 789 255 1810 278 787 247 794 250 789 255 1810 278 761 273 793 251 789 255 1810 278 787 247 +# +name: CH- +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 273 1816 272 767 277 789 255 785 249 791 253 787 246 1818 281 785 248 765 279 1812 276 789 255 759 275 791 253 1812 276 789 255 46372 281 1808 280 785 249 791 253 787 247 793 251 1814 274 791 253 1812 276 1814 274 791 253 1812 276 1814 274 1815 273 792 252 1813 275 42172 272 1819 280 785 249 765 279 761 273 768 276 764 280 1811 277 788 246 768 276 1815 273 792 252 788 246 794 250 1815 273 791 253 From 238005890ec6a619157ac75eb60bd02dfe6c736e Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Wed, 3 May 2023 00:56:25 +0300 Subject: [PATCH 07/28] [FL-3294] Fix TERMINFO on Linux systems (#2630) * Fix TERMINFO on Linux systems * Set TERMINFO_DIRS only on Linux * Unset TERMINFO_DIRS if it was not set before --- scripts/toolchain/fbtenv.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index 57a50281e..143dce74b 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -56,6 +56,16 @@ fbtenv_restore_env() unset SSL_CERT_FILE; unset REQUESTS_CA_BUNDLE; fi + + if [ "$SYS_TYPE" = "Linux" ]; then + if [ -n "$SAVED_TERMINFO_DIRS" ]; then + export TERMINFO_DIRS="$SAVED_TERMINFO_DIRS"; + else + unset TERMINFO_DIRS; + fi + unset SAVED_TERMINFO_DIRS; + fi + export PYTHONNOUSERSITE="$SAVED_PYTHONNOUSERSITE"; export PYTHONPATH="$SAVED_PYTHONPATH"; export PYTHONHOME="$SAVED_PYTHONHOME"; @@ -325,6 +335,11 @@ fbtenv_main() export PYTHONNOUSERSITE=1; export PYTHONPATH=; export PYTHONHOME=; + + if [ "$SYS_TYPE" = "Linux" ]; then + export SAVED_TERMINFO_DIRS="${TERMINFO_DIRS:-""}"; + export TERMINFO_DIRS="$TOOLCHAIN_ARCH_DIR/ncurses/share/terminfo"; + fi } fbtenv_main "${1:-""}"; From 23c946ef50e07950199637776d2f520351ee7ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 3 May 2023 11:08:41 +0900 Subject: [PATCH 08/28] Move gauge calibration to separate header, add f18 calibration (#2622) --- firmware/targets/f18/api_symbols.csv | 1 + .../f18/furi_hal/furi_hal_power_calibration.h | 37 ++++++++++++++++++ firmware/targets/f7/api_symbols.csv | 1 + firmware/targets/f7/furi_hal/furi_hal_power.c | 38 +------------------ .../f7/furi_hal/furi_hal_power_calibration.h | 37 ++++++++++++++++++ 5 files changed, 77 insertions(+), 37 deletions(-) create mode 100644 firmware/targets/f18/furi_hal/furi_hal_power_calibration.h create mode 100644 firmware/targets/f7/furi_hal/furi_hal_power_calibration.h diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index eb2d6f43f..25f36ca02 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -36,6 +36,7 @@ Header,+,applications/services/notification/notification_messages.h,, Header,+,applications/services/power/power_service/power.h,, Header,+,applications/services/rpc/rpc_app.h,, Header,+,applications/services/storage/storage.h,, +Header,-,firmware/targets/f18/furi_hal/furi_hal_power_calibration.h,, Header,+,firmware/targets/f18/furi_hal/furi_hal_resources.h,, Header,+,firmware/targets/f18/furi_hal/furi_hal_spi_config.h,, Header,+,firmware/targets/f18/furi_hal/furi_hal_target_hw.h,, diff --git a/firmware/targets/f18/furi_hal/furi_hal_power_calibration.h b/firmware/targets/f18/furi_hal/furi_hal_power_calibration.h new file mode 100644 index 000000000..e97e1657d --- /dev/null +++ b/firmware/targets/f18/furi_hal/furi_hal_power_calibration.h @@ -0,0 +1,37 @@ +const ParamCEDV cedv = { + .cedv_conf.gauge_conf = + { + .CCT = 1, + .CSYNC = 0, + .EDV_CMP = 0, + .SC = 1, + .FIXED_EDV0 = 1, + .FCC_LIM = 1, + .FC_FOR_VDQ = 1, + .IGNORE_SD = 1, + .SME0 = 0, + }, + .full_charge_cap = 1300, + .design_cap = 1300, + .EDV0 = 3300, + .EDV1 = 3321, + .EDV2 = 3355, + .EMF = 3679, + .C0 = 430, + .C1 = 0, + .R1 = 408, + .R0 = 334, + .T0 = 4626, + .TC = 11, + .DOD0 = 4044, + .DOD10 = 3905, + .DOD20 = 3807, + .DOD30 = 3718, + .DOD40 = 3642, + .DOD50 = 3585, + .DOD60 = 3546, + .DOD70 = 3514, + .DOD80 = 3477, + .DOD90 = 3411, + .DOD100 = 3299, +}; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index d0c6b36ad..951e92aae 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -47,6 +47,7 @@ Header,+,firmware/targets/f7/furi_hal/furi_hal_idle_timer.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_interrupt.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_nfc.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_os.h,, +Header,-,firmware/targets/f7/furi_hal/furi_hal_power_calibration.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_pwm.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_resources.h,, Header,+,firmware/targets/f7/furi_hal/furi_hal_rfid.h,, diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index e380de7fa..ec405f108 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -46,43 +46,7 @@ static volatile FuriHalPower furi_hal_power = { .suppress_charge = 0, }; -const ParamCEDV cedv = { - .cedv_conf.gauge_conf = - { - .CCT = 1, - .CSYNC = 0, - .EDV_CMP = 0, - .SC = 1, - .FIXED_EDV0 = 1, - .FCC_LIM = 1, - .FC_FOR_VDQ = 1, - .IGNORE_SD = 1, - .SME0 = 0, - }, - .full_charge_cap = 2101, - .design_cap = 2101, - .EDV0 = 3300, - .EDV1 = 3321, - .EDV2 = 3355, - .EMF = 3679, - .C0 = 430, - .C1 = 0, - .R1 = 408, - .R0 = 334, - .T0 = 4626, - .TC = 11, - .DOD0 = 4044, - .DOD10 = 3905, - .DOD20 = 3807, - .DOD30 = 3718, - .DOD40 = 3642, - .DOD50 = 3585, - .DOD60 = 3546, - .DOD70 = 3514, - .DOD80 = 3477, - .DOD90 = 3411, - .DOD100 = 3299, -}; +#include void furi_hal_power_init() { #ifdef FURI_HAL_POWER_DEBUG diff --git a/firmware/targets/f7/furi_hal/furi_hal_power_calibration.h b/firmware/targets/f7/furi_hal/furi_hal_power_calibration.h new file mode 100644 index 000000000..5eb0f938b --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_power_calibration.h @@ -0,0 +1,37 @@ +const ParamCEDV cedv = { + .cedv_conf.gauge_conf = + { + .CCT = 1, + .CSYNC = 0, + .EDV_CMP = 0, + .SC = 1, + .FIXED_EDV0 = 1, + .FCC_LIM = 1, + .FC_FOR_VDQ = 1, + .IGNORE_SD = 1, + .SME0 = 0, + }, + .full_charge_cap = 2101, + .design_cap = 2101, + .EDV0 = 3300, + .EDV1 = 3321, + .EDV2 = 3355, + .EMF = 3679, + .C0 = 430, + .C1 = 0, + .R1 = 408, + .R0 = 334, + .T0 = 4626, + .TC = 11, + .DOD0 = 4044, + .DOD10 = 3905, + .DOD20 = 3807, + .DOD30 = 3718, + .DOD40 = 3642, + .DOD50 = 3585, + .DOD60 = 3546, + .DOD70 = 3514, + .DOD80 = 3477, + .DOD90 = 3411, + .DOD100 = 3299, +}; From 8b8f65c5ae0de6c100a2567264130e855b2c5561 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 3 May 2023 03:11:26 +0100 Subject: [PATCH 09/28] BadKB fix BT_ID command --- applications/main/bad_kb/helpers/ducky_script_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/applications/main/bad_kb/helpers/ducky_script_commands.c b/applications/main/bad_kb/helpers/ducky_script_commands.c index f23ab2f8a..42ed1b9e8 100644 --- a/applications/main/bad_kb/helpers/ducky_script_commands.c +++ b/applications/main/bad_kb/helpers/ducky_script_commands.c @@ -171,6 +171,7 @@ static int32_t ducky_fnc_waitforbutton(BadKbScript* bad_kb, const char* line, in static const DuckyCmd ducky_commands[] = { {"REM", NULL, -1}, {"ID", NULL, -1}, + {"BT_ID", NULL, -1}, {"DELAY", ducky_fnc_delay, -1}, {"STRING", ducky_fnc_string, 0}, {"STRINGLN", ducky_fnc_string, 1}, From 5c09bc5b2d25da5fa6fc71e82eb316ed9db87c1f Mon Sep 17 00:00:00 2001 From: Lewis Westbury Date: Wed, 3 May 2023 04:33:30 +0100 Subject: [PATCH 10/28] Gui: relax some asserts in view (#2623) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove assertion preventing replacement of view input callback * Gui: relax some asserts in view Co-authored-by: あく --- applications/services/gui/view.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/applications/services/gui/view.c b/applications/services/gui/view.c index 4d84cac50..07ae072a1 100644 --- a/applications/services/gui/view.c +++ b/applications/services/gui/view.c @@ -19,19 +19,16 @@ void view_tie_icon_animation(View* view, IconAnimation* icon_animation) { void view_set_draw_callback(View* view, ViewDrawCallback callback) { furi_assert(view); - furi_assert(view->draw_callback == NULL); view->draw_callback = callback; } void view_set_input_callback(View* view, ViewInputCallback callback) { furi_assert(view); - furi_assert(view->input_callback == NULL); view->input_callback = callback; } void view_set_custom_callback(View* view, ViewCustomCallback callback) { furi_assert(view); - furi_assert(callback); view->custom_callback = callback; } @@ -62,7 +59,6 @@ void view_set_update_callback_context(View* view, void* context) { void view_set_context(View* view, void* context) { furi_assert(view); - furi_assert(context); view->context = context; } From c5b460b416e24fa887ec93672e56b71109c91a79 Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 3 May 2023 06:58:59 +0300 Subject: [PATCH 11/28] [FL-3260] Added API version to device info (#2611) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * hal: device_info: added API version to "firmware.api.major" & "firmware.api.minor" * FuriHal: bump device info version Co-authored-by: あく --- .../loader/firmware_api/firmware_api.cpp | 7 +++++++ firmware/targets/f18/api_symbols.csv | 3 ++- firmware/targets/f7/api_symbols.csv | 3 ++- firmware/targets/f7/furi_hal/furi_hal_info.c | 16 ++++++++++++++-- .../targets/furi_hal_include/furi_hal_info.h | 2 ++ furi/core/common_defines.h | 4 ++++ 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/applications/services/loader/firmware_api/firmware_api.cpp b/applications/services/loader/firmware_api/firmware_api.cpp index 52e86efc2..6651bf112 100644 --- a/applications/services/loader/firmware_api/firmware_api.cpp +++ b/applications/services/loader/firmware_api/firmware_api.cpp @@ -6,6 +6,8 @@ /* Generated table */ #include +#include + static_assert(!has_hash_collisions(elf_api_table), "Detected API method hash collision!"); constexpr HashtableApiInterface elf_api_interface{ @@ -19,3 +21,8 @@ constexpr HashtableApiInterface elf_api_interface{ }; const ElfApiInterface* const firmware_api_interface = &elf_api_interface; + +extern "C" void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) { + *major = elf_api_interface.api_version_major; + *minor = elf_api_interface.api_version_minor; +} \ No newline at end of file diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 25f36ca02..bdd5d6b61 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,23.0,, +Version,+,23.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -960,6 +960,7 @@ Function,+,furi_hal_i2c_write_mem,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, Function,+,furi_hal_i2c_write_reg_16,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint16_t, uint32_t" Function,+,furi_hal_i2c_write_reg_8,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t, uint32_t" Function,+,furi_hal_info_get,void,"PropertyValueCallback, char, void*" +Function,+,furi_hal_info_get_api_version,void,"uint16_t*, uint16_t*" Function,-,furi_hal_init,void, Function,-,furi_hal_init_early,void, Function,-,furi_hal_interrupt_init,void, diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 951e92aae..9f4ec4261 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,23.0,, +Version,+,23.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1148,6 +1148,7 @@ Function,+,furi_hal_ibutton_pin_configure,void, Function,+,furi_hal_ibutton_pin_reset,void, Function,+,furi_hal_ibutton_pin_write,void,const _Bool Function,+,furi_hal_info_get,void,"PropertyValueCallback, char, void*" +Function,+,furi_hal_info_get_api_version,void,"uint16_t*, uint16_t*" Function,+,furi_hal_infrared_async_rx_set_capture_isr_callback,void,"FuriHalInfraredRxCaptureCallback, void*" Function,+,furi_hal_infrared_async_rx_set_timeout,void,uint32_t Function,+,furi_hal_infrared_async_rx_set_timeout_isr_callback,void,"FuriHalInfraredRxTimeoutCallback, void*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index c984ef4d5..4c034ff35 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -8,6 +8,11 @@ #include #include +FURI_WEAK void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) { + *major = 0; + *minor = 0; +} + void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { FuriString* key = furi_string_alloc(); FuriString* value = furi_string_alloc(); @@ -18,10 +23,10 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { // Device Info version if(sep == '.') { property_value_out(&property_context, NULL, 2, "format", "major", "3"); - property_value_out(&property_context, NULL, 2, "format", "minor", "0"); + property_value_out(&property_context, NULL, 2, "format", "minor", "1"); } else { property_value_out(&property_context, NULL, 3, "device", "info", "major", "2"); - property_value_out(&property_context, NULL, 3, "device", "info", "minor", "0"); + property_value_out(&property_context, NULL, 3, "device", "info", "minor", "1"); } // Model name @@ -161,6 +166,13 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { version_get_builddate(firmware_version)); property_value_out( &property_context, "%d", 2, "firmware", "target", version_get_target(firmware_version)); + + uint16_t api_version_major, api_version_minor; + furi_hal_info_get_api_version(&api_version_major, &api_version_minor); + property_value_out( + &property_context, "%d", 3, "firmware", "api", "major", api_version_major); + property_value_out( + &property_context, "%d", 3, "firmware", "api", "minor", api_version_minor); } if(furi_hal_bt_is_alive()) { diff --git a/firmware/targets/furi_hal_include/furi_hal_info.h b/firmware/targets/furi_hal_include/furi_hal_info.h index fa3267f5d..7e8b0e1fb 100644 --- a/firmware/targets/furi_hal_include/furi_hal_info.h +++ b/firmware/targets/furi_hal_include/furi_hal_info.h @@ -14,6 +14,8 @@ extern "C" { #endif +void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor); + /** Get device information * * @param[in] callback callback to provide with new data diff --git a/furi/core/common_defines.h b/furi/core/common_defines.h index 1ec847d45..d7bfaf207 100644 --- a/furi/core/common_defines.h +++ b/furi/core/common_defines.h @@ -15,6 +15,10 @@ extern "C" { #define FURI_WARN_UNUSED __attribute__((warn_unused_result)) #endif +#ifndef FURI_WEAK +#define FURI_WEAK __attribute__((weak)) +#endif + #ifndef FURI_IS_IRQ_MASKED #define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U) #endif From dfbacd1a4753d64d76b1ac85da8f5bc9a46ecbd5 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Tue, 2 May 2023 21:05:24 -0700 Subject: [PATCH 12/28] [#2612] Remove spaces in CSN(#2616) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../external/picopass/scenes/picopass_scene_read_card_success.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/picopass/scenes/picopass_scene_read_card_success.c b/applications/external/picopass/scenes/picopass_scene_read_card_success.c index 198b21d98..cc18ac066 100644 --- a/applications/external/picopass/scenes/picopass_scene_read_card_success.c +++ b/applications/external/picopass/scenes/picopass_scene_read_card_success.c @@ -34,7 +34,7 @@ void picopass_scene_read_card_success_on_enter(void* context) { uint8_t csn[PICOPASS_BLOCK_LEN] = {0}; memcpy(csn, AA1[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN); for(uint8_t i = 0; i < PICOPASS_BLOCK_LEN; i++) { - furi_string_cat_printf(csn_str, "%02X ", csn[i]); + furi_string_cat_printf(csn_str, "%02X", csn[i]); } bool no_key = picopass_is_memset(pacs->key, 0x00, PICOPASS_BLOCK_LEN); From 59386f9fa9e8b3f9b03823c99405484dddaec071 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 3 May 2023 08:15:47 +0400 Subject: [PATCH 13/28] WS: add protocol "Wendox W6726" (#2604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WS: add protocol "Wendox" * WS: add bat status * WS: add CRC, refactoring * WS: description added * WS: fix name file * WeatherStation: cleanup alien symbols Co-authored-by: あく --- .../protocols/protocol_items.c | 1 + .../protocols/protocol_items.h | 1 + .../weather_station/protocols/wendox_w6726.c | 299 ++++++++++++++++++ .../weather_station/protocols/wendox_w6726.h | 80 +++++ 4 files changed, 381 insertions(+) create mode 100644 applications/external/weather_station/protocols/wendox_w6726.c create mode 100644 applications/external/weather_station/protocols/wendox_w6726.h diff --git a/applications/external/weather_station/protocols/protocol_items.c b/applications/external/weather_station/protocols/protocol_items.c index 2c9d751c7..cd4bae76d 100644 --- a/applications/external/weather_station/protocols/protocol_items.c +++ b/applications/external/weather_station/protocols/protocol_items.c @@ -16,6 +16,7 @@ const SubGhzProtocol* weather_station_protocol_registry_items[] = { &ws_protocol_auriol_th, &ws_protocol_oregon_v1, &ws_protocol_tx_8300, + &ws_protocol_wendox_w6726, }; const SubGhzProtocolRegistry weather_station_protocol_registry = { diff --git a/applications/external/weather_station/protocols/protocol_items.h b/applications/external/weather_station/protocols/protocol_items.h index f9e443abc..0398c11f2 100644 --- a/applications/external/weather_station/protocols/protocol_items.h +++ b/applications/external/weather_station/protocols/protocol_items.h @@ -16,5 +16,6 @@ #include "auriol_hg0601a.h" #include "oregon_v1.h" #include "tx_8300.h" +#include "wendox_w6726.h" extern const SubGhzProtocolRegistry weather_station_protocol_registry; diff --git a/applications/external/weather_station/protocols/wendox_w6726.c b/applications/external/weather_station/protocols/wendox_w6726.c new file mode 100644 index 000000000..2fbe961f7 --- /dev/null +++ b/applications/external/weather_station/protocols/wendox_w6726.c @@ -0,0 +1,299 @@ +#include "wendox_w6726.h" + +#define TAG "WSProtocolWendoxW6726" + +/* + * Wendox W6726 + * + * Temperature -50C to +70C + * _ _ _ __ _ + * _| |___| |___| |___ ... | |_| |__...._______________ + * preamble data guard time + * + * 3 reps every 3 minutes + * in the first message 11 bytes of the preamble in the rest by 7 + * + * bit 0: 1955-hi, 5865-lo + * bit 1: 5865-hi, 1955-lo + * guard time: 12*1955+(lo last bit) + * data: 29 bit + * + * IIIII | ZTTTTTTTTT | uuuuuuuBuu | CCCC + * + * I: identification; + * Z: temperature sign; + * T: temperature sign dependent +12C; + * B: battery low; flag to indicate low battery voltage; + * C: CRC4 (polynomial = 0x9, start_data = 0xD); + * u: unknown; + */ + +static const SubGhzBlockConst ws_protocol_wendox_w6726_const = { + .te_short = 1955, + .te_long = 5865, + .te_delta = 300, + .min_count_bit_for_found = 29, +}; + +struct WSProtocolDecoderWendoxW6726 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + WSBlockGeneric generic; + + uint16_t header_count; +}; + +struct WSProtocolEncoderWendoxW6726 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + WSBlockGeneric generic; +}; + +typedef enum { + WendoxW6726DecoderStepReset = 0, + WendoxW6726DecoderStepCheckPreambule, + WendoxW6726DecoderStepSaveDuration, + WendoxW6726DecoderStepCheckDuration, +} WendoxW6726DecoderStep; + +const SubGhzProtocolDecoder ws_protocol_wendox_w6726_decoder = { + .alloc = ws_protocol_decoder_wendox_w6726_alloc, + .free = ws_protocol_decoder_wendox_w6726_free, + + .feed = ws_protocol_decoder_wendox_w6726_feed, + .reset = ws_protocol_decoder_wendox_w6726_reset, + + .get_hash_data = ws_protocol_decoder_wendox_w6726_get_hash_data, + .serialize = ws_protocol_decoder_wendox_w6726_serialize, + .deserialize = ws_protocol_decoder_wendox_w6726_deserialize, + .get_string = ws_protocol_decoder_wendox_w6726_get_string, +}; + +const SubGhzProtocolEncoder ws_protocol_wendox_w6726_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol ws_protocol_wendox_w6726 = { + .name = WS_PROTOCOL_WENDOX_W6726_NAME, + .type = SubGhzProtocolWeatherStation, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &ws_protocol_wendox_w6726_decoder, + .encoder = &ws_protocol_wendox_w6726_encoder, +}; + +void* ws_protocol_decoder_wendox_w6726_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + WSProtocolDecoderWendoxW6726* instance = malloc(sizeof(WSProtocolDecoderWendoxW6726)); + instance->base.protocol = &ws_protocol_wendox_w6726; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void ws_protocol_decoder_wendox_w6726_free(void* context) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + free(instance); +} + +void ws_protocol_decoder_wendox_w6726_reset(void* context) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + instance->decoder.parser_step = WendoxW6726DecoderStepReset; +} + +static bool ws_protocol_wendox_w6726_check(WSProtocolDecoderWendoxW6726* instance) { + if(!instance->decoder.decode_data) return false; + uint8_t msg[] = { + instance->decoder.decode_data >> 28, + instance->decoder.decode_data >> 20, + instance->decoder.decode_data >> 12, + instance->decoder.decode_data >> 4}; + + uint8_t crc = subghz_protocol_blocks_crc4(msg, 4, 0x9, 0xD); + return (crc == (instance->decoder.decode_data & 0x0F)); +} + +/** + * Analysis of received data + * @param instance Pointer to a WSBlockGeneric* instance + */ +static void ws_protocol_wendox_w6726_remote_controller(WSBlockGeneric* instance) { + instance->id = (instance->data >> 24) & 0xFF; + instance->battery_low = (instance->data >> 6) & 1; + instance->channel = WS_NO_CHANNEL; + + if(((instance->data >> 23) & 1)) { + instance->temp = (float)(((instance->data >> 14) & 0x1FF) + 12) / 10.0f; + } else { + instance->temp = (float)((~(instance->data >> 14) & 0x1FF) + 1 - 12) / -10.0f; + } + + if(instance->temp < -50.0f) { + instance->temp = -50.0f; + } else if(instance->temp > 70.0f) { + instance->temp = 70.0f; + } + + instance->btn = WS_NO_BTN; + instance->humidity = WS_NO_HUMIDITY; +} + +void ws_protocol_decoder_wendox_w6726_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + + switch(instance->decoder.parser_step) { + case WendoxW6726DecoderStepReset: + if((level) && (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta)) { + instance->decoder.parser_step = WendoxW6726DecoderStepCheckPreambule; + instance->decoder.te_last = duration; + instance->header_count = 0; + } + break; + + case WendoxW6726DecoderStepCheckPreambule: + if(level) { + instance->decoder.te_last = duration; + } else { + if((DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta * 1) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2)) { + instance->header_count++; + } else if((instance->header_count > 4) && (instance->header_count < 12)) { + if((DURATION_DIFF( + instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta)) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + } + break; + + case WendoxW6726DecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = WendoxW6726DecoderStepCheckDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + break; + + case WendoxW6726DecoderStepCheckDuration: + if(!level) { + if(duration > + ws_protocol_wendox_w6726_const.te_short + ws_protocol_wendox_w6726_const.te_long) { + if(DURATION_DIFF( + instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else if( + DURATION_DIFF( + instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + if((instance->decoder.decode_count_bit == + ws_protocol_wendox_w6726_const.min_count_bit_for_found) && + ws_protocol_wendox_w6726_check(instance)) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + ws_protocol_wendox_w6726_remote_controller(&instance->generic); + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } else if( + (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 3)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else if( + (DURATION_DIFF(instance->decoder.te_last, ws_protocol_wendox_w6726_const.te_long) < + ws_protocol_wendox_w6726_const.te_delta * 2) && + (DURATION_DIFF(duration, ws_protocol_wendox_w6726_const.te_short) < + ws_protocol_wendox_w6726_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = WendoxW6726DecoderStepSaveDuration; + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + } else { + instance->decoder.parser_step = WendoxW6726DecoderStepReset; + } + break; + } +} + +uint8_t ws_protocol_decoder_wendox_w6726_get_hash_data(void* context) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus ws_protocol_decoder_wendox_w6726_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + return ws_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + ws_protocol_decoder_wendox_w6726_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + return ws_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + ws_protocol_wendox_w6726_const.min_count_bit_for_found); +} + +void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output) { + furi_assert(context); + WSProtocolDecoderWendoxW6726* instance = context; + furi_string_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Sn:0x%lX Ch:%d Bat:%d\r\n" + "Temp:%3.1f C Hum:%d%%", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data), + instance->generic.id, + instance->generic.channel, + instance->generic.battery_low, + (double)instance->generic.temp, + instance->generic.humidity); +} diff --git a/applications/external/weather_station/protocols/wendox_w6726.h b/applications/external/weather_station/protocols/wendox_w6726.h new file mode 100644 index 000000000..236777a1c --- /dev/null +++ b/applications/external/weather_station/protocols/wendox_w6726.h @@ -0,0 +1,80 @@ +#pragma once + +#include + +#include +#include +#include +#include "ws_generic.h" +#include + +#define WS_PROTOCOL_WENDOX_W6726_NAME "Wendox W6726" + +typedef struct WSProtocolDecoderWendoxW6726 WSProtocolDecoderWendoxW6726; +typedef struct WSProtocolEncoderWendoxW6726 WSProtocolEncoderWendoxW6726; + +extern const SubGhzProtocolDecoder ws_protocol_wendox_w6726_decoder; +extern const SubGhzProtocolEncoder ws_protocol_wendox_w6726_encoder; +extern const SubGhzProtocol ws_protocol_wendox_w6726; + +/** + * Allocate WSProtocolDecoderWendoxW6726. + * @param environment Pointer to a SubGhzEnvironment instance + * @return WSProtocolDecoderWendoxW6726* pointer to a WSProtocolDecoderWendoxW6726 instance + */ +void* ws_protocol_decoder_wendox_w6726_alloc(SubGhzEnvironment* environment); + +/** + * Free WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + */ +void ws_protocol_decoder_wendox_w6726_free(void* context); + +/** + * Reset decoder WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + */ +void ws_protocol_decoder_wendox_w6726_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void ws_protocol_decoder_wendox_w6726_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @return hash Hash sum + */ +uint8_t ws_protocol_decoder_wendox_w6726_get_hash_data(void* context); + +/** + * Serialize data WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return status + */ +SubGhzProtocolStatus ws_protocol_decoder_wendox_w6726_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data WSProtocolDecoderWendoxW6726. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + ws_protocol_decoder_wendox_w6726_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a WSProtocolDecoderWendoxW6726 instance + * @param output Resulting text + */ +void ws_protocol_decoder_wendox_w6726_get_string(void* context, FuriString* output); From 015ab4a0242c9c9c7ff182afd42b81cbecee758c Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Wed, 3 May 2023 07:39:14 +0300 Subject: [PATCH 14/28] [#2591] BadUSB: command parser fix (#2607) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../bad_usb/helpers/ducky_script_commands.c | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/applications/main/bad_usb/helpers/ducky_script_commands.c b/applications/main/bad_usb/helpers/ducky_script_commands.c index 1498c9a73..d073b4c8d 100644 --- a/applications/main/bad_usb/helpers/ducky_script_commands.c +++ b/applications/main/bad_usb/helpers/ducky_script_commands.c @@ -152,22 +152,22 @@ static int32_t ducky_fnc_waitforbutton(BadUsbScript* bad_usb, const char* line, } static const DuckyCmd ducky_commands[] = { - {"REM ", NULL, -1}, - {"ID ", NULL, -1}, - {"DELAY ", ducky_fnc_delay, -1}, - {"STRING ", ducky_fnc_string, 0}, - {"STRINGLN ", ducky_fnc_string, 1}, - {"DEFAULT_DELAY ", ducky_fnc_defdelay, -1}, - {"DEFAULTDELAY ", ducky_fnc_defdelay, -1}, - {"STRINGDELAY ", ducky_fnc_strdelay, -1}, - {"STRING_DELAY ", ducky_fnc_strdelay, -1}, - {"REPEAT ", ducky_fnc_repeat, -1}, - {"SYSRQ ", ducky_fnc_sysrq, -1}, - {"ALTCHAR ", ducky_fnc_altchar, -1}, - {"ALTSTRING ", ducky_fnc_altstring, -1}, - {"ALTCODE ", ducky_fnc_altstring, -1}, - {"HOLD ", ducky_fnc_hold, -1}, - {"RELEASE ", ducky_fnc_release, -1}, + {"REM", NULL, -1}, + {"ID", NULL, -1}, + {"DELAY", ducky_fnc_delay, -1}, + {"STRING", ducky_fnc_string, 0}, + {"STRINGLN", ducky_fnc_string, 1}, + {"DEFAULT_DELAY", ducky_fnc_defdelay, -1}, + {"DEFAULTDELAY", ducky_fnc_defdelay, -1}, + {"STRINGDELAY", ducky_fnc_strdelay, -1}, + {"STRING_DELAY", ducky_fnc_strdelay, -1}, + {"REPEAT", ducky_fnc_repeat, -1}, + {"SYSRQ", ducky_fnc_sysrq, -1}, + {"ALTCHAR", ducky_fnc_altchar, -1}, + {"ALTSTRING", ducky_fnc_altstring, -1}, + {"ALTCODE", ducky_fnc_altstring, -1}, + {"HOLD", ducky_fnc_hold, -1}, + {"RELEASE", ducky_fnc_release, -1}, {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, }; @@ -175,8 +175,15 @@ static const DuckyCmd ducky_commands[] = { #define WORKER_TAG TAG "Worker" int32_t ducky_execute_cmd(BadUsbScript* bad_usb, const char* line) { + size_t cmd_word_len = strcspn(line, " "); for(size_t i = 0; i < COUNT_OF(ducky_commands); i++) { - if(strncmp(line, ducky_commands[i].name, strlen(ducky_commands[i].name)) == 0) { + size_t cmd_compare_len = strlen(ducky_commands[i].name); + + if(cmd_compare_len != cmd_word_len) { + continue; + } + + if(strncmp(line, ducky_commands[i].name, cmd_compare_len) == 0) { if(ducky_commands[i].callback == NULL) { return 0; } else { From c3ececcf969576f2099fd45be80d5e4f213dc9b5 Mon Sep 17 00:00:00 2001 From: hedger Date: Wed, 3 May 2023 08:48:49 +0300 Subject: [PATCH 15/28] [FL-3174] Dolphin builder in ufbt; minor ufbt/fbt improvements (#2601) * ufbt: added "dolphin_ext" target (expects "external" subfolder in cwd with dolphin assets); cleaned up unused code * ufbt: codestyle fixes * scripts: fixed style according to ruff linter * scripts: additional cleanup & codestyle fixes * github: pass target hw code when installing local SDK with ufbt * ufbt: added error message for missing folder in dolphin builder * scripts: more linter fixes * sdk: added flipper_format_stream; ufbt: support for --extra-define * fbt: reduced amount of global defines * scripts, fbt: rearranged imports Co-authored-by: Aleksandr Kutuzov --- .github/workflows/build.yml | 2 + assets/SConscript | 4 +- firmware.scons | 4 +- firmware/targets/f18/api_symbols.csv | 8 +++- firmware/targets/f7/api_symbols.csv | 8 +++- lib/flipper_format/SConscript | 1 + lib/freertos.scons | 3 -- lib/libusb_stm32.scons | 8 ++-- lib/littlefs.scons | 8 ++-- lib/misc.scons | 4 +- lib/toolbox/SConscript | 4 +- scripts/assets.py | 32 ++++++------- scripts/distfap.py | 6 +-- scripts/fbt/appmanifest.py | 12 ++--- scripts/fbt/elfmanifest.py | 4 +- scripts/fbt/fapassets.py | 2 +- scripts/fbt/sdk/cache.py | 17 +++---- scripts/fbt/util.py | 9 ++-- scripts/fbt/version.py | 2 +- scripts/fbt_tools/ccache.py | 2 +- scripts/fbt_tools/crosscc.py | 14 +++--- scripts/fbt_tools/fbt_apps.py | 13 +++--- scripts/fbt_tools/fbt_assets.py | 14 +++--- scripts/fbt_tools/fbt_debugopts.py | 2 - scripts/fbt_tools/fbt_dist.py | 3 +- scripts/fbt_tools/fbt_extapps.py | 18 +++----- scripts/fbt_tools/fbt_hwtarget.py | 2 - scripts/fbt_tools/fbt_sdk.py | 19 ++++---- scripts/fbt_tools/fbt_tweaks.py | 12 +++-- scripts/fbt_tools/fbt_version.py | 2 +- scripts/fbt_tools/fwbin.py | 4 +- scripts/fbt_tools/gdb.py | 4 -- scripts/fbt_tools/objdump.py | 2 +- scripts/fbt_tools/openocd.py | 6 +-- scripts/fbt_tools/pvsstudio.py | 13 +++--- scripts/fbt_tools/sconsmodular.py | 3 +- scripts/fbt_tools/sconsrecursiveglob.py | 2 +- scripts/fbt_tools/strip.py | 2 +- scripts/flash.py | 50 ++++++++++----------- scripts/flipper/app.py | 2 +- scripts/flipper/assets/copro.py | 8 ++-- scripts/flipper/assets/coprobin.py | 3 +- scripts/flipper/assets/dolphin.py | 12 +++-- scripts/flipper/assets/icon.py | 12 ++--- scripts/flipper/assets/manifest.py | 5 +-- scripts/flipper/assets/obdata.py | 4 +- scripts/flipper/cube.py | 8 ++-- scripts/flipper/storage.py | 4 +- scripts/flipper/utils/__init__.py | 1 - scripts/flipper/utils/programmer_openocd.py | 10 ++--- scripts/flipper/utils/stm32wb55.py | 6 +-- scripts/flipper/utils/templite.py | 4 +- scripts/fwsize.py | 7 +-- scripts/get_env.py | 14 +++--- scripts/lint.py | 11 +++-- scripts/merge_report_qa.py | 3 +- scripts/meta.py | 3 +- scripts/ob.py | 4 +- scripts/otp.py | 37 +++++++-------- scripts/program.py | 14 +++--- scripts/runfap.py | 12 +++-- scripts/sconsdist.py | 2 +- scripts/selfupdate.py | 12 +++-- scripts/serial_cli.py | 5 ++- scripts/storage.py | 12 ++--- scripts/ufbt/SConstruct | 37 ++++++++++----- scripts/ufbt/commandline.scons | 34 +++++--------- scripts/ufbt/site_init.py | 6 +-- scripts/ufbt/site_tools/ufbt_state.py | 7 ++- scripts/ufbt/update.scons | 37 --------------- scripts/update.py | 20 ++++----- scripts/version.py | 8 ++-- site_scons/extapps.scons | 4 +- 73 files changed, 311 insertions(+), 382 deletions(-) delete mode 100644 scripts/ufbt/update.scons diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0934eec76..d69318530 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -193,12 +193,14 @@ jobs: TARGET="$(echo '${{ matrix.target }}' | sed 's/f//')"; \ ./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package echo "sdk-file=$(ls dist/${{ matrix.target }}-*/flipper-z-${{ matrix.target }}-sdk-*.zip)" >> $GITHUB_OUTPUT + echo "hw-target-code=$TARGET" >> $GITHUB_OUTPUT - name: Deploy uFBT with SDK uses: flipperdevices/flipperzero-ufbt-action@v0.1.0 with: task: setup sdk-file: ${{ steps.build-fw.outputs.sdk-file }} + sdk-hw-target: ${{ steps.build-fw.outputs.hw-target-code }} - name: Build test app with SDK run: | diff --git a/assets/SConscript b/assets/SConscript index 21437aa30..9bd273626 100644 --- a/assets/SConscript +++ b/assets/SConscript @@ -1,7 +1,7 @@ -Import("env") - from fbt.version import get_git_commit_unix_timestamp +Import("env") + assetsenv = env.Clone( tools=["fbt_assets"], FW_LIB_NAME="assets", diff --git a/firmware.scons b/firmware.scons index c7fdc6392..c46996899 100644 --- a/firmware.scons +++ b/firmware.scons @@ -1,5 +1,3 @@ -Import("ENV", "fw_build_meta") - from SCons.Errors import UserError from SCons.Node import FS @@ -10,6 +8,8 @@ from fbt_extra.util import ( link_elf_dir_as_latest, ) +Import("ENV", "fw_build_meta") + # Building initial C environment for libs env = ENV.Clone( tools=[ diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index bdd5d6b61..f84bf074e 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,23.1,, +Version,+,23.3,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -112,6 +112,7 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,, Header,+,lib/flipper_application/plugins/plugin_manager.h,, Header,+,lib/flipper_format/flipper_format.h,, Header,+,lib/flipper_format/flipper_format_i.h,, +Header,+,lib/flipper_format/flipper_format_stream.h,, Header,+,lib/libusb_stm32/inc/hid_usage_button.h,, Header,+,lib/libusb_stm32/inc/hid_usage_consumer.h,, Header,+,lib/libusb_stm32/inc/hid_usage_desktop.h,, @@ -755,6 +756,11 @@ Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32 Function,+,flipper_format_rewind,_Bool,FlipperFormat* Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat* Function,+,flipper_format_set_strict_mode,void,"FlipperFormat*, _Bool" +Function,+,flipper_format_stream_delete_key_and_write,_Bool,"Stream*, FlipperStreamWriteData*, _Bool" +Function,+,flipper_format_stream_get_value_count,_Bool,"Stream*, const char*, uint32_t*, _Bool" +Function,+,flipper_format_stream_read_value_line,_Bool,"Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool" +Function,+,flipper_format_stream_write_comment_cstr,_Bool,"Stream*, const char*" +Function,+,flipper_format_stream_write_value_line,_Bool,"Stream*, FlipperStreamWriteData*" Function,+,flipper_format_string_alloc,FlipperFormat*, Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t" Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 9f4ec4261..c176b2d7e 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,23.1,, +Version,+,23.3,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -118,6 +118,7 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,, Header,+,lib/flipper_application/plugins/plugin_manager.h,, Header,+,lib/flipper_format/flipper_format.h,, Header,+,lib/flipper_format/flipper_format_i.h,, +Header,+,lib/flipper_format/flipper_format_stream.h,, Header,+,lib/ibutton/ibutton_key.h,, Header,+,lib/ibutton/ibutton_protocols.h,, Header,+,lib/ibutton/ibutton_worker.h,, @@ -918,6 +919,11 @@ Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32 Function,+,flipper_format_rewind,_Bool,FlipperFormat* Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat* Function,+,flipper_format_set_strict_mode,void,"FlipperFormat*, _Bool" +Function,+,flipper_format_stream_delete_key_and_write,_Bool,"Stream*, FlipperStreamWriteData*, _Bool" +Function,+,flipper_format_stream_get_value_count,_Bool,"Stream*, const char*, uint32_t*, _Bool" +Function,+,flipper_format_stream_read_value_line,_Bool,"Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool" +Function,+,flipper_format_stream_write_comment_cstr,_Bool,"Stream*, const char*" +Function,+,flipper_format_stream_write_value_line,_Bool,"Stream*, FlipperStreamWriteData*" Function,+,flipper_format_string_alloc,FlipperFormat*, Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t" Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t" diff --git a/lib/flipper_format/SConscript b/lib/flipper_format/SConscript index 353da8035..9c9e8b6f3 100644 --- a/lib/flipper_format/SConscript +++ b/lib/flipper_format/SConscript @@ -7,6 +7,7 @@ env.Append( SDK_HEADERS=[ File("flipper_format.h"), File("flipper_format_i.h"), + File("flipper_format_stream.h"), ], ) diff --git a/lib/freertos.scons b/lib/freertos.scons index 1c5a5bf54..cb0006e56 100644 --- a/lib/freertos.scons +++ b/lib/freertos.scons @@ -7,9 +7,6 @@ env.Append( "#/lib/FreeRTOS-Kernel/portable/GCC/ARM_CM4F", "#/lib/FreeRTOS-glue", ], - CPPDEFINES=[ - "HAVE_FREERTOS", - ], ) diff --git a/lib/libusb_stm32.scons b/lib/libusb_stm32.scons index 4838b7c50..ccc5de24f 100644 --- a/lib/libusb_stm32.scons +++ b/lib/libusb_stm32.scons @@ -4,9 +4,6 @@ env.Append( CPPPATH=[ "#/lib/libusb_stm32/inc", ], - CPPDEFINES=[ - ("USB_PMASIZE", "0x400"), - ], SDK_HEADERS=env.GlobRecursive( "*.h", Dir("libusb_stm32/inc"), @@ -16,6 +13,11 @@ env.Append( libenv = env.Clone(FW_LIB_NAME="usb_stm32") libenv.ApplyLibFlags() +libenv.Append( + CPPDEFINES=[ + ("USB_PMASIZE", "0x400"), + ], +) sources = [ diff --git a/lib/littlefs.scons b/lib/littlefs.scons index 792142c32..3d68e07ba 100644 --- a/lib/littlefs.scons +++ b/lib/littlefs.scons @@ -4,14 +4,16 @@ env.Append( CPPPATH=[ "#/lib/littlefs", ], - CPPDEFINES=[ - ("LFS_CONFIG", "lfs_config.h"), - ], ) libenv = env.Clone(FW_LIB_NAME="littlefs") libenv.ApplyLibFlags() +libenv.Append( + CPPDEFINES=[ + ("LFS_CONFIG", "lfs_config.h"), + ], +) sources = Glob("littlefs/*.c", source=True) diff --git a/lib/misc.scons b/lib/misc.scons index b479851b1..1ff6e2fb0 100644 --- a/lib/misc.scons +++ b/lib/misc.scons @@ -1,7 +1,7 @@ -Import("env") - from fbt.util import GLOB_FILE_EXCLUSION +Import("env") + env.Append( CPPPATH=[ "#/lib/digital_signal", diff --git a/lib/toolbox/SConscript b/lib/toolbox/SConscript index bb06c2db4..4e158e30e 100644 --- a/lib/toolbox/SConscript +++ b/lib/toolbox/SConscript @@ -1,8 +1,8 @@ -Import("env") - from fbt.version import get_fast_git_version_id +Import("env") + env.Append( CPPPATH=[ "#/lib/toolbox", diff --git a/scripts/assets.py b/scripts/assets.py index 75bebcfb4..c0fa9100b 100755 --- a/scripts/assets.py +++ b/scripts/assets.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 +import os + from flipper.app import App from flipper.assets.icon import file2image -import os - ICONS_SUPPORTED_FORMATS = ["png"] ICONS_TEMPLATE_H_HEADER = """#pragma once @@ -127,7 +127,7 @@ class Main(App): if not filenames: continue if "frame_rate" in filenames: - self.logger.debug(f"Folder contains animation") + self.logger.debug("Folder contains animation") icon_name = "A_" + os.path.split(dirpath)[1].replace("-", "_") width = height = None frame_count = 0 @@ -186,7 +186,7 @@ class Main(App): icons_c.write("\n") icons.append((icon_name, width, height, 0, 1)) # Create array of images: - self.logger.debug(f"Finalizing source file") + self.logger.debug("Finalizing source file") for name, width, height, frame_rate, frame_count in icons: icons_c.write( ICONS_TEMPLATE_C_ICONS.format( @@ -201,7 +201,7 @@ class Main(App): icons_c.close() # Create Public Header - self.logger.debug(f"Creating header") + self.logger.debug("Creating header") icons_h = open( os.path.join(self.args.output_directory, f"{self.args.filename}.h"), "w", @@ -211,7 +211,7 @@ class Main(App): for name, width, height, frame_rate, frame_count in icons: icons_h.write(ICONS_TEMPLATE_H_ICON_NAME.format(name=name)) icons_h.close() - self.logger.debug(f"Done") + self.logger.debug("Done") return 0 def manifest(self): @@ -232,7 +232,7 @@ class Main(App): new_manifest = Manifest(self.args.timestamp) new_manifest.create(directory_path) - self.logger.info(f"Comparing new manifest with existing") + self.logger.info("Comparing new manifest with existing") only_in_old, changed, only_in_new = Manifest.compare(old_manifest, new_manifest) for record in only_in_old: self.logger.info(f"Only in old: {record}") @@ -246,38 +246,38 @@ class Main(App): else: self.logger.info("Manifest is up-to-date!") - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 def copro(self): from flipper.assets.copro import Copro - self.logger.info(f"Bundling coprocessor binaries") + self.logger.info("Bundling coprocessor binaries") copro = Copro(self.args.mcu) - self.logger.info(f"Loading CUBE info") + self.logger.info("Loading CUBE info") copro.loadCubeInfo(self.args.cube_dir, self.args.cube_ver) - self.logger.info(f"Bundling") + self.logger.info("Bundling") copro.bundle( self.args.output_dir, self.args.stack_file, self.args.stack_type, self.args.stack_addr, ) - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 def dolphin(self): from flipper.assets.dolphin import Dolphin - self.logger.info(f"Processing Dolphin sources") + self.logger.info("Processing Dolphin sources") dolphin = Dolphin() - self.logger.info(f"Loading data") + self.logger.info("Loading data") dolphin.load(self.args.input_directory) - self.logger.info(f"Packing") + self.logger.info("Packing") dolphin.pack(self.args.output_directory, self.args.symbol_name) - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 diff --git a/scripts/distfap.py b/scripts/distfap.py index 060fe26ff..d330988b5 100644 --- a/scripts/distfap.py +++ b/scripts/distfap.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 +import os +import posixpath + from flipper.app import App from flipper.storage import FlipperStorage, FlipperStorageOperations from flipper.utils.cdc import resolve_port -import os -import posixpath - class Main(App): def init(self): diff --git a/scripts/fbt/appmanifest.py b/scripts/fbt/appmanifest.py index 37ddc4348..5e41f4c0e 100644 --- a/scripts/fbt/appmanifest.py +++ b/scripts/fbt/appmanifest.py @@ -1,7 +1,7 @@ -from dataclasses import dataclass, field -from typing import List, Optional, Tuple, Callable -from enum import Enum import os +from dataclasses import dataclass, field +from enum import Enum +from typing import Callable, List, Optional, Tuple class FlipperManifestException(Exception): @@ -93,7 +93,7 @@ class AppManager: def get(self, appname: str): try: return self.known_apps[appname] - except KeyError as _: + except KeyError: raise FlipperManifestException( f"Missing application manifest for '{appname}'" ) @@ -223,6 +223,7 @@ class AppBuildset: return self.appmgr.get(app_name).supports_hardware_target(self.hw_target) def _get_app_depends(self, app_name: str) -> List[str]: + app_def = self.appmgr.get(app_name) # Skip app if its target is not supported by the target we are building for if not self._check_if_app_target_supported(app_name): self._writer( @@ -230,7 +231,6 @@ class AppBuildset: ) return [] - app_def = self.appmgr.get(app_name) return list( filter( self._check_if_app_target_supported, @@ -296,7 +296,7 @@ class AppBuildset: try: parent_app = self.appmgr.get(parent_app_id) parent_app._plugins.append(extension_app) - except FlipperManifestException as e: + except FlipperManifestException: self._writer( f"Module {extension_app.appid} has unknown parent {parent_app_id}" ) diff --git a/scripts/fbt/elfmanifest.py b/scripts/fbt/elfmanifest.py index 17bceddf4..333888e14 100644 --- a/scripts/fbt/elfmanifest.py +++ b/scripts/fbt/elfmanifest.py @@ -1,12 +1,10 @@ -from dataclasses import dataclass import os - import struct from dataclasses import dataclass, field -from .appmanifest import FlipperApplication from flipper.assets.icon import file2image +from .appmanifest import FlipperApplication _MANIFEST_MAGIC = 0x52474448 diff --git a/scripts/fbt/fapassets.py b/scripts/fbt/fapassets.py index 0649f03ef..9902fd79a 100644 --- a/scripts/fbt/fapassets.py +++ b/scripts/fbt/fapassets.py @@ -1,5 +1,5 @@ -import os import hashlib +import os import struct from typing import TypedDict diff --git a/scripts/fbt/sdk/cache.py b/scripts/fbt/sdk/cache.py index 756c37827..b6f6edbe5 100644 --- a/scripts/fbt/sdk/cache.py +++ b/scripts/fbt/sdk/cache.py @@ -1,20 +1,13 @@ -import operator -import os import csv import operator - -from enum import Enum, auto -from typing import Set, ClassVar, Any +import os from dataclasses import dataclass +from enum import Enum, auto +from typing import Any, ClassVar, Set from ansi.color import fg -from . import ( - ApiEntries, - ApiEntryFunction, - ApiEntryVariable, - ApiHeader, -) +from . import ApiEntries, ApiEntryFunction, ApiEntryVariable, ApiHeader @dataclass(frozen=True) @@ -137,7 +130,7 @@ class SdkCache: f"API version is still WIP: {self.version}. Review the changes and re-run command." ) ) - print(f"CSV file entries to mark up:") + print("CSV file entries to mark up:") print( fg.yellow( "\n".join( diff --git a/scripts/fbt/util.py b/scripts/fbt/util.py index 7bdaea031..ae850a8c3 100644 --- a/scripts/fbt/util.py +++ b/scripts/fbt/util.py @@ -1,10 +1,9 @@ -import SCons -from SCons.Subst import quote_spaces -from SCons.Errors import StopError - -import re import os +import re +import SCons +from SCons.Errors import StopError +from SCons.Subst import quote_spaces WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)") diff --git a/scripts/fbt/version.py b/scripts/fbt/version.py index e7fe2edaf..09f48c8eb 100644 --- a/scripts/fbt/version.py +++ b/scripts/fbt/version.py @@ -1,5 +1,5 @@ -import subprocess import datetime +import subprocess from functools import cache diff --git a/scripts/fbt_tools/ccache.py b/scripts/fbt_tools/ccache.py index e88886ade..63577ab78 100644 --- a/scripts/fbt_tools/ccache.py +++ b/scripts/fbt_tools/ccache.py @@ -3,7 +3,7 @@ def exists(): def generate(env): - if ccache := env.WhereIs("ccache"): + if env.WhereIs("ccache"): env["CCACHE"] = "ccache" env["CC_NOCACHE"] = env["CC"] env["CC"] = "$CCACHE $CC_NOCACHE" diff --git a/scripts/fbt_tools/crosscc.py b/scripts/fbt_tools/crosscc.py index dd5cd5319..d0631ca33 100644 --- a/scripts/fbt_tools/crosscc.py +++ b/scripts/fbt_tools/crosscc.py @@ -1,15 +1,11 @@ -from SCons.Errors import StopError -from SCons.Tool import asm -from SCons.Tool import gcc -from SCons.Tool import gxx -from SCons.Tool import ar -from SCons.Tool import gnulink -import strip +import subprocess + import gdb import objdump - +import strip from SCons.Action import _subproc -import subprocess +from SCons.Errors import StopError +from SCons.Tool import ar, asm, gcc, gnulink, gxx def prefix_commands(env, command_prefix, cmd_list): diff --git a/scripts/fbt_tools/fbt_apps.py b/scripts/fbt_tools/fbt_apps.py index 9dbe30720..053a69503 100644 --- a/scripts/fbt_tools/fbt_apps.py +++ b/scripts/fbt_tools/fbt_apps.py @@ -1,15 +1,14 @@ -from SCons.Builder import Builder -from SCons.Action import Action -from SCons.Errors import StopError -from SCons.Warnings import warn, WarningOnByDefault from ansi.color import fg - from fbt.appmanifest import ( - FlipperAppType, - AppManager, ApplicationsCGenerator, + AppManager, + FlipperAppType, FlipperManifestException, ) +from SCons.Action import Action +from SCons.Builder import Builder +from SCons.Errors import StopError +from SCons.Warnings import WarningOnByDefault, warn # Adding objects for application management to env # AppManager env["APPMGR"] - loads all manifests; manages list of known apps diff --git a/scripts/fbt_tools/fbt_assets.py b/scripts/fbt_tools/fbt_assets.py index e4c567993..68617c254 100644 --- a/scripts/fbt_tools/fbt_assets.py +++ b/scripts/fbt_tools/fbt_assets.py @@ -1,10 +1,10 @@ -from SCons.Builder import Builder -from SCons.Action import Action -from SCons.Errors import StopError - import os import subprocess + from ansi.color import fg +from SCons.Action import Action +from SCons.Builder import Builder +from SCons.Errors import StopError def icons_emitter(target, source, env): @@ -76,11 +76,11 @@ def proto_ver_generator(target, source, env): target_file = target[0] src_dir = source[0].dir.abspath try: - git_fetch = _invoke_git( + _invoke_git( ["fetch", "--tags"], source_dir=src_dir, ) - except (subprocess.CalledProcessError, EnvironmentError) as e: + except (subprocess.CalledProcessError, EnvironmentError): # Not great, not terrible print(fg.boldred("Git: fetch failed")) @@ -89,7 +89,7 @@ def proto_ver_generator(target, source, env): ["describe", "--tags", "--abbrev=0"], source_dir=src_dir, ) - except (subprocess.CalledProcessError, EnvironmentError) as e: + except (subprocess.CalledProcessError, EnvironmentError): raise StopError("Git: describe failed") git_major, git_minor = git_describe.split(".") diff --git a/scripts/fbt_tools/fbt_debugopts.py b/scripts/fbt_tools/fbt_debugopts.py index 9abe59893..33cc0c076 100644 --- a/scripts/fbt_tools/fbt_debugopts.py +++ b/scripts/fbt_tools/fbt_debugopts.py @@ -1,5 +1,3 @@ -from re import search - from SCons.Errors import UserError diff --git a/scripts/fbt_tools/fbt_dist.py b/scripts/fbt_tools/fbt_dist.py index d2808419c..a43d62e9d 100644 --- a/scripts/fbt_tools/fbt_dist.py +++ b/scripts/fbt_tools/fbt_dist.py @@ -1,6 +1,5 @@ -from SCons.Builder import Builder from SCons.Action import Action -from SCons.Script import Mkdir +from SCons.Builder import Builder from SCons.Defaults import Touch diff --git a/scripts/fbt_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py index 4ac1c6873..1a1bad29e 100644 --- a/scripts/fbt_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -3,23 +3,19 @@ import os import pathlib import shutil from dataclasses import dataclass, field -from typing import Optional, TypedDict - -from ansi.color import fg +from typing import Optional import SCons.Warnings -from SCons.Action import Action -from SCons.Builder import Builder -from SCons.Errors import UserError -from SCons.Node import NodeList -from SCons.Node.FS import File, Entry - +from ansi.color import fg from fbt.appmanifest import FlipperApplication, FlipperAppType, FlipperManifestException from fbt.elfmanifest import assemble_manifest_data from fbt.fapassets import FileBundler from fbt.sdk.cache import SdkCache from fbt.util import extract_abs_dir_path - +from SCons.Action import Action +from SCons.Builder import Builder +from SCons.Errors import UserError +from SCons.Node.FS import Entry, File _FAP_META_SECTION = ".fapmeta" _FAP_FILEASSETS_SECTION = ".fapassets" @@ -289,7 +285,7 @@ def GetExtAppByIdOrPath(env, app_dir): try: # Maybe user passed an appid? app = appmgr.get(app_dir) - except FlipperManifestException as _: + except FlipperManifestException: # Look up path components in known app dirs for dir_part in reversed(pathlib.Path(app_dir).parts): if app := appmgr.find_by_appdir(dir_part): diff --git a/scripts/fbt_tools/fbt_hwtarget.py b/scripts/fbt_tools/fbt_hwtarget.py index b4e1e58ac..1831a6984 100644 --- a/scripts/fbt_tools/fbt_hwtarget.py +++ b/scripts/fbt_tools/fbt_hwtarget.py @@ -1,5 +1,3 @@ -from SCons.Builder import Builder -from SCons.Action import Action import json diff --git a/scripts/fbt_tools/fbt_sdk.py b/scripts/fbt_tools/fbt_sdk.py index 90d0831eb..2f7d62388 100644 --- a/scripts/fbt_tools/fbt_sdk.py +++ b/scripts/fbt_tools/fbt_sdk.py @@ -1,21 +1,20 @@ +import json +import os.path +import pathlib +import posixpath import shutil -from SCons.Builder import Builder + +from fbt.sdk.cache import SdkCache +from fbt.sdk.collector import SdkCollector +from fbt.util import path_as_posix from SCons.Action import Action +from SCons.Builder import Builder from SCons.Errors import UserError # from SCons.Scanner import C from SCons.Script import Entry from SCons.Util import LogicalLines -import os.path -import posixpath -import pathlib -import json - -from fbt.sdk.collector import SdkCollector -from fbt.sdk.cache import SdkCache -from fbt.util import path_as_posix - def ProcessSdkDepends(env, filename): try: diff --git a/scripts/fbt_tools/fbt_tweaks.py b/scripts/fbt_tools/fbt_tweaks.py index 700f66d23..68ac9d7d1 100644 --- a/scripts/fbt_tools/fbt_tweaks.py +++ b/scripts/fbt_tools/fbt_tweaks.py @@ -1,15 +1,13 @@ +import os +import sys +import traceback + import SCons.Warnings as Warnings +from ansi.color import fg from SCons.Errors import UserError - # from SCons.Script.Main import find_deepest_user_frame -from ansi.color import fg, bg, fx - -import traceback -import sys -import os - def find_deepest_user_frame(tb): tb.reverse() diff --git a/scripts/fbt_tools/fbt_version.py b/scripts/fbt_tools/fbt_version.py index 87497ca5f..8469e181a 100644 --- a/scripts/fbt_tools/fbt_version.py +++ b/scripts/fbt_tools/fbt_version.py @@ -1,5 +1,5 @@ -from SCons.Builder import Builder from SCons.Action import Action +from SCons.Builder import Builder def version_emitter(target, source, env): diff --git a/scripts/fbt_tools/fwbin.py b/scripts/fbt_tools/fwbin.py index f510c2a60..06a435b6d 100644 --- a/scripts/fbt_tools/fwbin.py +++ b/scripts/fbt_tools/fwbin.py @@ -1,6 +1,6 @@ -from SCons.Builder import Builder -from SCons.Action import Action import SCons +from SCons.Action import Action +from SCons.Builder import Builder __OBJCOPY_ARM_BIN = "arm-none-eabi-objcopy" __NM_ARM_BIN = "arm-none-eabi-nm" diff --git a/scripts/fbt_tools/gdb.py b/scripts/fbt_tools/gdb.py index 38256a0f8..ea29e9c92 100644 --- a/scripts/fbt_tools/gdb.py +++ b/scripts/fbt_tools/gdb.py @@ -1,7 +1,3 @@ -from SCons.Builder import Builder -from SCons.Action import Action - - def generate(env): env.SetDefault( GDB="gdb", diff --git a/scripts/fbt_tools/objdump.py b/scripts/fbt_tools/objdump.py index f5fa938a7..31f817648 100644 --- a/scripts/fbt_tools/objdump.py +++ b/scripts/fbt_tools/objdump.py @@ -1,5 +1,5 @@ -from SCons.Builder import Builder from SCons.Action import Action +from SCons.Builder import Builder def generate(env): diff --git a/scripts/fbt_tools/openocd.py b/scripts/fbt_tools/openocd.py index dcf0bf925..157d798f4 100644 --- a/scripts/fbt_tools/openocd.py +++ b/scripts/fbt_tools/openocd.py @@ -1,7 +1,7 @@ -from SCons.Builder import Builder -from SCons.Action import Action -from SCons.Defaults import Touch import SCons +from SCons.Action import Action +from SCons.Builder import Builder +from SCons.Defaults import Touch __OPENOCD_BIN = "openocd" diff --git a/scripts/fbt_tools/pvsstudio.py b/scripts/fbt_tools/pvsstudio.py index 593559a33..211f46aee 100644 --- a/scripts/fbt_tools/pvsstudio.py +++ b/scripts/fbt_tools/pvsstudio.py @@ -1,11 +1,12 @@ -from SCons.Builder import Builder -from SCons.Action import Action -from SCons.Script import Delete, Mkdir, GetBuildFailures, Flatten -import multiprocessing -import webbrowser import atexit -import sys +import multiprocessing import subprocess +import sys +import webbrowser + +from SCons.Action import Action +from SCons.Builder import Builder +from SCons.Script import Delete, Flatten, GetBuildFailures, Mkdir __no_browser = False diff --git a/scripts/fbt_tools/sconsmodular.py b/scripts/fbt_tools/sconsmodular.py index 57ae8f055..4dc2079a6 100644 --- a/scripts/fbt_tools/sconsmodular.py +++ b/scripts/fbt_tools/sconsmodular.py @@ -1,5 +1,6 @@ -import posixpath import os +import posixpath + from SCons.Errors import UserError diff --git a/scripts/fbt_tools/sconsrecursiveglob.py b/scripts/fbt_tools/sconsrecursiveglob.py index fbcee965b..7dbde531b 100644 --- a/scripts/fbt_tools/sconsrecursiveglob.py +++ b/scripts/fbt_tools/sconsrecursiveglob.py @@ -1,6 +1,6 @@ import SCons -from SCons.Script import Flatten from fbt.util import GLOB_FILE_EXCLUSION +from SCons.Script import Flatten def GlobRecursive(env, pattern, node=".", exclude=[]): diff --git a/scripts/fbt_tools/strip.py b/scripts/fbt_tools/strip.py index 053956f22..ee14fc185 100644 --- a/scripts/fbt_tools/strip.py +++ b/scripts/fbt_tools/strip.py @@ -1,5 +1,5 @@ -from SCons.Builder import Builder from SCons.Action import Action +from SCons.Builder import Builder def generate(env): diff --git a/scripts/flash.py b/scripts/flash.py index fb05b8b0b..6189dc1a2 100755 --- a/scripts/flash.py +++ b/scripts/flash.py @@ -1,13 +1,9 @@ #!/usr/bin/env python3 -import logging -import argparse -import sys -import os from flipper.app import App -from flipper.cube import CubeProgrammer from flipper.assets.coprobin import CoproBinary +from flipper.cube import CubeProgrammer STATEMENT = "AGREE_TO_LOSE_FLIPPER_FEATURES_THAT_USE_CRYPTO_ENCLAVE" @@ -94,59 +90,59 @@ class Main(App): } def wipe(self): - self.logger.info(f"Wiping flash") + self.logger.info("Wiping flash") cp = CubeProgrammer(self._getCubeParams()) - self.logger.info(f"Setting RDP to 0xBB") + self.logger.info("Setting RDP to 0xBB") cp.setOptionBytes({"RDP": ("0xBB", "rw")}) - self.logger.info(f"Verifying RDP") + self.logger.info("Verifying RDP") r = cp.checkOptionBytes({"RDP": ("0xBB", "rw")}) - assert r == True + assert r is True self.logger.info(f"Result: {r}") - self.logger.info(f"Setting RDP to 0xAA") + self.logger.info("Setting RDP to 0xAA") cp.setOptionBytes({"RDP": ("0xAA", "rw")}) - self.logger.info(f"Verifying RDP") + self.logger.info("Verifying RDP") r = cp.checkOptionBytes({"RDP": ("0xAA", "rw")}) - assert r == True + assert r is True self.logger.info(f"Result: {r}") - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 def core1bootloader(self): - self.logger.info(f"Flashing bootloader") + self.logger.info("Flashing bootloader") cp = CubeProgrammer(self._getCubeParams()) cp.flashBin("0x08000000", self.args.bootloader) - self.logger.info(f"Complete") + self.logger.info("Complete") cp.resetTarget() return 0 def core1firmware(self): - self.logger.info(f"Flashing firmware") + self.logger.info("Flashing firmware") cp = CubeProgrammer(self._getCubeParams()) cp.flashBin("0x08008000", self.args.firmware) - self.logger.info(f"Complete") + self.logger.info("Complete") cp.resetTarget() return 0 def core1(self): - self.logger.info(f"Flashing bootloader") + self.logger.info("Flashing bootloader") cp = CubeProgrammer(self._getCubeParams()) cp.flashBin("0x08000000", self.args.bootloader) - self.logger.info(f"Flashing firmware") + self.logger.info("Flashing firmware") cp.flashBin("0x08008000", self.args.firmware) cp.resetTarget() - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 def core2fus(self): if self.args.statement != STATEMENT: self.logger.error( - f"PLEASE DON'T. THIS FEATURE INTENDED ONLY FOR FACTORY FLASHING" + "PLEASE DON'T. THIS FEATURE INTENDED ONLY FOR FACTORY FLASHING" ) return 1 - self.logger.info(f"Flashing Firmware Update Service") + self.logger.info("Flashing Firmware Update Service") cp = CubeProgrammer(self._getCubeParams()) cp.flashCore2(self.args.fus_address, self.args.fus) - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 def core2radio(self): @@ -163,15 +159,15 @@ class Main(App): f"Radio address not provided, guessed as 0x{radio_address:X}" ) if radio_address > 0x080E0000: - self.logger.error(f"I KNOW WHAT YOU DID LAST SUMMER") + self.logger.error("I KNOW WHAT YOU DID LAST SUMMER") return 1 cp = CubeProgrammer(self._getCubeParams()) - self.logger.info(f"Removing Current Radio Stack") + self.logger.info("Removing Current Radio Stack") cp.deleteCore2RadioStack() - self.logger.info(f"Flashing Radio Stack") + self.logger.info("Flashing Radio Stack") cp.flashCore2(radio_address, self.args.radio) - self.logger.info(f"Complete") + self.logger.info("Complete") return 0 diff --git a/scripts/flipper/app.py b/scripts/flipper/app.py index 30630a5f9..405c4c399 100644 --- a/scripts/flipper/app.py +++ b/scripts/flipper/app.py @@ -44,7 +44,7 @@ class App: if isinstance(return_code, int): return self._exit(return_code) else: - self.logger.error(f"Missing return code") + self.logger.error("Missing return code") return self._exit(255) def _exit(self, code): diff --git a/scripts/flipper/assets/copro.py b/scripts/flipper/assets/copro.py index e0375b51f..ee13a9b5e 100644 --- a/scripts/flipper/assets/copro.py +++ b/scripts/flipper/assets/copro.py @@ -6,7 +6,7 @@ import xml.etree.ElementTree as ET import posixpath import os -from flipper.utils import * +from flipper.utils import file_sha256, timestamp from flipper.assets.coprobin import CoproBinary, get_stack_type @@ -45,13 +45,13 @@ class Copro: cube_manifest = ET.parse(cube_manifest_file) cube_package = cube_manifest.find("PackDescription") if not cube_package: - raise Exception(f"Unknown Cube manifest format") + raise Exception("Unknown Cube manifest format") cube_version = cube_package.get("Patch") or cube_package.get("Release") if not cube_version or not cube_version.startswith("FW.WB"): - raise Exception(f"Incorrect Cube package or version info") + raise Exception("Incorrect Cube package or version info") cube_version = cube_version.replace("FW.WB.", "", 1) if cube_version != reference_cube_version: - raise Exception(f"Unsupported cube version") + raise Exception("Unsupported cube version") self.version = cube_version def _getFileName(self, name): diff --git a/scripts/flipper/assets/coprobin.py b/scripts/flipper/assets/coprobin.py index 64f0b8c87..7c5bdb3dc 100644 --- a/scripts/flipper/assets/coprobin.py +++ b/scripts/flipper/assets/coprobin.py @@ -1,6 +1,7 @@ import struct import math -import os, os.path +import os +import os.path import sys diff --git a/scripts/flipper/assets/dolphin.py b/scripts/flipper/assets/dolphin.py index cbd1320b6..ebe9fd889 100644 --- a/scripts/flipper/assets/dolphin.py +++ b/scripts/flipper/assets/dolphin.py @@ -1,13 +1,11 @@ import multiprocessing import logging import os -import sys -import shutil from collections import Counter -from flipper.utils.fff import * -from flipper.utils.templite import * -from .icon import * +from flipper.utils.fff import FlipperFormatFile +from flipper.utils.templite import Templite +from .icon import ImageTools, file2image def _convert_image_to_bm(pair: set): @@ -121,7 +119,7 @@ class DolphinBubbleAnimation: self.meta["Passive frames"] + self.meta["Active frames"] == ordered_frames_count ) - except EOFError as e: + except EOFError: raise Exception("Invalid meta file: too short") except AssertionError as e: self.logger.exception(e) @@ -158,7 +156,7 @@ class DolphinBubbleAnimation: except AssertionError as e: self.logger.exception(e) self.logger.error( - f"Animation {self.name} bubble slot {bubble_slot} got incorrect data: {bubble}" + f"Animation {self.name} bubble slot {bubble['Slot']} got incorrect data: {bubble}" ) raise Exception("Meta file is invalid: incorrect bubble data") except EOFError: diff --git a/scripts/flipper/assets/icon.py b/scripts/flipper/assets/icon.py index f0dae25be..d5d2a585e 100644 --- a/scripts/flipper/assets/icon.py +++ b/scripts/flipper/assets/icon.py @@ -1,9 +1,6 @@ import logging -import argparse import subprocess import io -import os -import sys ICONS_SUPPORTED_FORMATS = ["png"] @@ -36,11 +33,8 @@ class ImageTools: @staticmethod def is_processing_slow(): try: - from PIL import Image, ImageOps - import heatshrink2 - return False - except ImportError as e: + except ImportError: return True def __init__(self): @@ -52,7 +46,7 @@ class ImageTools: try: from PIL import Image, ImageOps - except ImportError as e: + except ImportError: self.__pil_unavailable = True self.logger.info("pillow module is missing, using convert cli util") return self.png2xbm(file) @@ -72,7 +66,7 @@ class ImageTools: try: import heatshrink2 - except ImportError as e: + except ImportError: self.__hs2_unavailable = True self.logger.info("heatshrink2 module is missing, using heatshrink cli util") return self.xbm2hs(data) diff --git a/scripts/flipper/assets/manifest.py b/scripts/flipper/assets/manifest.py index a8f6855a4..a9bbb8dac 100644 --- a/scripts/flipper/assets/manifest.py +++ b/scripts/flipper/assets/manifest.py @@ -1,11 +1,10 @@ -import datetime import logging import os import posixpath from pathlib import Path -from flipper.utils import * -from flipper.utils.fstree import * +from flipper.utils import timestamp, file_md5 +from flipper.utils.fstree import FsNode, compare_fs_trees MANIFEST_VERSION = 0 diff --git a/scripts/flipper/assets/obdata.py b/scripts/flipper/assets/obdata.py index 0f7f5c192..eb35d0e17 100644 --- a/scripts/flipper/assets/obdata.py +++ b/scripts/flipper/assets/obdata.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -import logging -import struct from enum import Enum from dataclasses import dataclass @@ -181,7 +179,7 @@ class OptionBytesData: def gen_values(self): obref = ObReferenceValuesGenerator() - converted_refs = list(obref.apply(ob) for ob in self.obs) + list(obref.apply(ob) for ob in self.obs) return obref diff --git a/scripts/flipper/cube.py b/scripts/flipper/cube.py index 38aa54a85..e4f9876df 100644 --- a/scripts/flipper/cube.py +++ b/scripts/flipper/cube.py @@ -14,7 +14,7 @@ class CubeProgrammer: if "port" in config and config["port"]: connect.append(f"port={config['port']}") else: - connect.append(f"port=swd") + connect.append("port=swd") if "serial" in config and config["serial"]: connect.append(f"sn={config['serial']}") self.params.append("-c " + " ".join(connect)) @@ -43,20 +43,20 @@ class CubeProgrammer: return output.decode() def getVersion(self): - output = self._execute(["--version"]) + self._execute(["--version"]) def checkOptionBytes(self, option_bytes): output = self._execute(["-ob displ"]) ob_correct = True for line in output.split("\n"): line = line.strip() - if not ":" in line: + if ":" not in line: self.logger.debug(f"Skipping line: {line}") continue key, data = line.split(":", 1) key = key.strip() data = data.strip() - if not key in option_bytes.keys(): + if key not in option_bytes.keys(): self.logger.debug(f"Skipping key: {key}") continue self.logger.debug(f"Processing key: {key} {data}") diff --git a/scripts/flipper/storage.py b/scripts/flipper/storage.py index cff32ceb1..9f6f52156 100644 --- a/scripts/flipper/storage.py +++ b/scripts/flipper/storage.py @@ -151,7 +151,7 @@ class FlipperStorage: try: # TODO: better decoding, considering non-ascii characters line = line.decode("ascii") - except: + except Exception: continue line = line.strip() @@ -194,7 +194,7 @@ class FlipperStorage: try: # TODO: better decoding, considering non-ascii characters line = line.decode("ascii") - except: + except Exception: continue line = line.strip() diff --git a/scripts/flipper/utils/__init__.py b/scripts/flipper/utils/__init__.py index 62bf98a25..6b4ebbd52 100644 --- a/scripts/flipper/utils/__init__.py +++ b/scripts/flipper/utils/__init__.py @@ -1,6 +1,5 @@ import datetime import hashlib -import os def timestamp(): diff --git a/scripts/flipper/utils/programmer_openocd.py b/scripts/flipper/utils/programmer_openocd.py index 3d2171854..5a8029f37 100644 --- a/scripts/flipper/utils/programmer_openocd.py +++ b/scripts/flipper/utils/programmer_openocd.py @@ -31,13 +31,13 @@ class OpenOCDProgrammer(Programmer): config["interface"] = interface config["target"] = "target/stm32wbx.cfg" - if not serial is None: + if serial is not None: if interface == "interface/cmsis-dap.cfg": config["serial"] = f"cmsis_dap_serial {serial}" elif "stlink" in interface: config["serial"] = f"stlink_serial {serial}" - if not port_base is None: + if port_base is not None: config["port_base"] = port_base self.openocd = OpenOCD(config) @@ -59,7 +59,7 @@ class OpenOCDProgrammer(Programmer): raise Exception(f"File {file_path} not found") self.openocd.start() - self.openocd.send_tcl(f"init") + self.openocd.send_tcl("init") self.openocd.send_tcl( f"program {file_path} 0x{address:08x}{' verify' if verify else ''} reset exit" ) @@ -196,7 +196,7 @@ class OpenOCDProgrammer(Programmer): if ob_need_to_apply: stm32.option_bytes_apply(self.openocd) else: - self.logger.info(f"Option Bytes are already correct") + self.logger.info("Option Bytes are already correct") # Load Option Bytes # That will reset and also lock the Option Bytes and the Flash @@ -256,7 +256,7 @@ class OpenOCDProgrammer(Programmer): already_written = False if already_written: - self.logger.info(f"OTP memory is already written with the given data") + self.logger.info("OTP memory is already written with the given data") return OpenOCDProgrammerResult.Success self.reset(self.RunMode.Stop) diff --git a/scripts/flipper/utils/stm32wb55.py b/scripts/flipper/utils/stm32wb55.py index 910b0d7d6..52a5ec4e3 100644 --- a/scripts/flipper/utils/stm32wb55.py +++ b/scripts/flipper/utils/stm32wb55.py @@ -123,7 +123,7 @@ class STM32WB55: def clear_flash_errors(self, oocd: OpenOCD): # Errata 2.2.9: Flash OPTVERR flag is always set after system reset # And also clear all other flash error flags - self.logger.debug(f"Resetting flash errors") + self.logger.debug("Resetting flash errors") self.FLASH_SR.load(oocd) self.FLASH_SR.OP_ERR = 1 self.FLASH_SR.PROG_ERR = 1 @@ -218,7 +218,7 @@ class STM32WB55: raise Exception("Flash lock failed") def option_bytes_apply(self, oocd: OpenOCD): - self.logger.debug(f"Applying Option Bytes") + self.logger.debug("Applying Option Bytes") self.FLASH_CR.load(oocd) self.FLASH_CR.OPT_STRT = 1 @@ -228,7 +228,7 @@ class STM32WB55: self.flash_wait_for_operation(oocd) def option_bytes_load(self, oocd: OpenOCD): - self.logger.debug(f"Loading Option Bytes") + self.logger.debug("Loading Option Bytes") self.FLASH_CR.load(oocd) self.FLASH_CR.OBL_LAUNCH = 1 self.FLASH_CR.store(oocd) diff --git a/scripts/flipper/utils/templite.py b/scripts/flipper/utils/templite.py index 2d958bd77..1d19585cd 100644 --- a/scripts/flipper/utils/templite.py +++ b/scripts/flipper/utils/templite.py @@ -77,8 +77,8 @@ class TempliteCompiler: return lines = self.block.splitlines() - margin = min(len(l) - len(l.lstrip()) for l in lines if l.strip()) - self.block = "\n".join("\t" * self.offset + l[margin:] for l in lines) + margin = min(len(line) - len(line.lstrip()) for line in lines if line.strip()) + self.block = "\n".join("\t" * self.offset + line[margin:] for line in lines) self.blocks.append(self.block) if self.block.endswith(":"): self.offset += 1 diff --git a/scripts/fwsize.py b/scripts/fwsize.py index 445c29049..75a825692 100644 --- a/scripts/fwsize.py +++ b/scripts/fwsize.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 -from flipper.app import App -import subprocess -import os import math +import os +import subprocess + from ansi.color import fg +from flipper.app import App class Main(App): diff --git a/scripts/get_env.py b/scripts/get_env.py index 92f9243c2..5403bafeb 100644 --- a/scripts/get_env.py +++ b/scripts/get_env.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 -import ssl -import json -import os -import shlex -import re -import string -import random import argparse import datetime +import json +import os +import random +import re +import shlex +import ssl +import string import urllib.request diff --git a/scripts/lint.py b/scripts/lint.py index 58f2d69f5..8530209be 100755 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 +import multiprocessing import os import re import shutil import subprocess -import multiprocessing from flipper.app import App - SOURCE_CODE_FILE_EXTENSIONS = [".h", ".c", ".cpp", ".cxx", ".hpp"] SOURCE_CODE_FILE_PATTERN = r"^[0-9A-Za-z_]+\.[a-z]+$" SOURCE_CODE_DIR_PATTERN = r"^[0-9A-Za-z_]+$" @@ -59,7 +58,7 @@ class Main(App): show_message = True if show_message: self.logger.warning( - f"Folders are not renamed automatically, please fix it by yourself" + "Folders are not renamed automatically, please fix it by yourself" ) def _find_sources(self, folders: list): @@ -70,7 +69,7 @@ class Main(App): for filename in filenames: ext = os.path.splitext(filename.lower())[1] - if not ext in SOURCE_CODE_FILE_EXTENSIONS: + if ext not in SOURCE_CODE_FILE_EXTENSIONS: continue output.append(os.path.join(dirpath, filename)) return output @@ -80,7 +79,7 @@ class Main(App): try: subprocess.check_call(task) return True - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError: return False def _format_sources(self, sources: list, dry_run: bool = False): @@ -144,7 +143,7 @@ class Main(App): def _apply_file_permissions(self, sources: list, dry_run: bool = False): execute_permissions = 0o111 - pattern = re.compile(SOURCE_CODE_FILE_PATTERN) + re.compile(SOURCE_CODE_FILE_PATTERN) good = [] bad = [] # Check sources for unexpected execute permissions diff --git a/scripts/merge_report_qa.py b/scripts/merge_report_qa.py index caa742408..a33327e6b 100755 --- a/scripts/merge_report_qa.py +++ b/scripts/merge_report_qa.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 +import argparse import os import re import sys -import argparse + from slack_sdk import WebClient from slack_sdk.errors import SlackApiError diff --git a/scripts/meta.py b/scripts/meta.py index ae2f213b7..f47ef65fb 100755 --- a/scripts/meta.py +++ b/scripts/meta.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 -from flipper.app import App import json +from flipper.app import App + class Main(App): def init(self): diff --git a/scripts/ob.py b/scripts/ob.py index 178fe16a7..7010bdec5 100755 --- a/scripts/ob.py +++ b/scripts/ob.py @@ -44,7 +44,7 @@ class Main(App): ) def check(self): - self.logger.info(f"Checking Option Bytes") + self.logger.info("Checking Option Bytes") # OpenOCD openocd = OpenOCDProgrammer( @@ -60,7 +60,7 @@ class Main(App): return return_code def set(self): - self.logger.info(f"Setting Option Bytes") + self.logger.info("Setting Option Bytes") # OpenOCD openocd = OpenOCDProgrammer( diff --git a/scripts/otp.py b/scripts/otp.py index cb76bdc86..19b8c4df4 100755 --- a/scripts/otp.py +++ b/scripts/otp.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 +import datetime import logging -import argparse -import subprocess import os -import sys import re import struct -import datetime + +from flipper.app import App +from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult OTP_MAGIC = 0xBABE OTP_VERSION = 0x02 @@ -33,9 +33,6 @@ OTP_DISPLAYS = { "mgg": 0x02, } -from flipper.app import App -from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult - class OTPException(Exception): def __init__(self, message: str, result: OpenOCDProgrammerResult): @@ -158,7 +155,7 @@ class Main(App): ) def generate_all(self): - self.logger.info(f"Generating OTP") + self.logger.info("Generating OTP") self._processFirstArgs() self._processSecondArgs() with open(f"{self.args.file}_first.bin", "wb") as file: @@ -172,18 +169,18 @@ class Main(App): return 0 def flash_first(self): - self.logger.info(f"Flashing first block of OTP") + self.logger.info("Flashing first block of OTP") self._processFirstArgs() filename = f"otp_unknown_first_{self.timestamp}.bin" try: - self.logger.info(f"Packing binary data") + self.logger.info("Packing binary data") with open(filename, "wb") as file: file.write(self._packFirst()) - self.logger.info(f"Flashing OTP") + self.logger.info("Flashing OTP") openocd = OpenOCDProgrammer( self.args.interface, @@ -195,7 +192,7 @@ class Main(App): if programmer_result != OpenOCDProgrammerResult.Success: raise OTPException("Failed to flash OTP", programmer_result) - self.logger.info(f"Flashed Successfully") + self.logger.info("Flashed Successfully") except OTPException as e: self.logger.exception(e) return e.get_exit_code() @@ -205,18 +202,18 @@ class Main(App): return 0 def flash_second(self): - self.logger.info(f"Flashing second block of OTP") + self.logger.info("Flashing second block of OTP") self._processSecondArgs() filename = f"otp_{self.args.name}_second_{self.timestamp}.bin" try: - self.logger.info(f"Packing binary data") + self.logger.info("Packing binary data") with open(filename, "wb") as file: file.write(self._packSecond()) - self.logger.info(f"Flashing OTP") + self.logger.info("Flashing OTP") openocd = OpenOCDProgrammer( self.args.interface, @@ -228,7 +225,7 @@ class Main(App): if programmer_result != OpenOCDProgrammerResult.Success: raise OTPException("Failed to flash OTP", programmer_result) - self.logger.info(f"Flashed Successfully") + self.logger.info("Flashed Successfully") except OTPException as e: self.logger.exception(e) return e.get_exit_code() @@ -238,7 +235,7 @@ class Main(App): return 0 def flash_all(self): - self.logger.info(f"Flashing OTP") + self.logger.info("Flashing OTP") self._processFirstArgs() self._processSecondArgs() @@ -246,12 +243,12 @@ class Main(App): filename = f"otp_{self.args.name}_whole_{self.timestamp}.bin" try: - self.logger.info(f"Packing binary data") + self.logger.info("Packing binary data") with open(filename, "wb") as file: file.write(self._packFirst()) file.write(self._packSecond()) - self.logger.info(f"Flashing OTP") + self.logger.info("Flashing OTP") openocd = OpenOCDProgrammer( self.args.interface, @@ -263,7 +260,7 @@ class Main(App): if programmer_result != OpenOCDProgrammerResult.Success: raise OTPException("Failed to flash OTP", programmer_result) - self.logger.info(f"Flashed Successfully") + self.logger.info("Flashed Successfully") except OTPException as e: self.logger.exception(e) return e.get_exit_code() diff --git a/scripts/program.py b/scripts/program.py index c140a9024..f3e7e3e2d 100755 --- a/scripts/program.py +++ b/scripts/program.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 -import typing -import subprocess import logging -import time import os import socket - +import subprocess +import time +import typing from abc import ABC, abstractmethod from dataclasses import dataclass + from flipper.app import App @@ -223,7 +223,7 @@ class BlackmagicProgrammer(Programmer): try: socket.inet_aton(address) return True - except: + except Exception: return False def set_serial(self, serial: str): @@ -415,12 +415,12 @@ class Main(App): if len(interfaces) == 0: interfaces = [p for p in network_programmers if p.get_name() == i_name] else: - self.logger.info(f"Probing for interfaces...") + self.logger.info("Probing for interfaces...") interfaces = self._search_interface(self.args.serial) if len(interfaces) == 0: # Probe network blackmagic - self.logger.info(f"Probing for network interfaces...") + self.logger.info("Probing for network interfaces...") interfaces = self._search_network_interface(self.args.serial) if len(interfaces) == 0: diff --git a/scripts/runfap.py b/scripts/runfap.py index f8ff607c1..a240acf12 100644 --- a/scripts/runfap.py +++ b/scripts/runfap.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 +import operator +from functools import reduce + from flipper.app import App from flipper.storage import FlipperStorage, FlipperStorageOperations from flipper.utils.cdc import resolve_port -import os -import posixpath -from functools import reduce -import operator - class Main(App): def init(self): @@ -38,8 +36,8 @@ class Main(App): self.parser.set_defaults(func=self.install) @staticmethod - def flatten(l): - return reduce(operator.concat, l, []) + def flatten(item_list): + return reduce(operator.concat, item_list, []) def install(self): self.args.sources = self.flatten(self.args.sources) diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index af2554d0a..1657feab9 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -5,7 +5,7 @@ import shutil import tarfile import zipfile from os import makedirs, walk -from os.path import exists, join, relpath, basename, split +from os.path import basename, exists, join, relpath from ansi.color import fg from flipper.app import App diff --git a/scripts/selfupdate.py b/scripts/selfupdate.py index 9bfbfefa3..1ce0b8376 100644 --- a/scripts/selfupdate.py +++ b/scripts/selfupdate.py @@ -1,14 +1,12 @@ #!/usr/bin/env python3 -from typing import final -from flipper.app import App -from flipper.storage import FlipperStorage, FlipperStorageOperations -from flipper.utils.cdc import resolve_port - import logging import os import pathlib -import serial.tools.list_ports as list_ports + +from flipper.app import App +from flipper.storage import FlipperStorage, FlipperStorageOperations +from flipper.utils.cdc import resolve_port class Main(App): @@ -54,7 +52,7 @@ class Main(App): f"update install {flipper_update_path}/{manifest_name}\r" ) result = storage.read.until(storage.CLI_EOL) - if not b"Verifying" in result: + if b"Verifying" not in result: self.logger.error(f"Unexpected response: {result.decode('ascii')}") return 3 result = storage.read.until(storage.CLI_EOL) diff --git a/scripts/serial_cli.py b/scripts/serial_cli.py index 390b1f263..2fa37d751 100644 --- a/scripts/serial_cli.py +++ b/scripts/serial_cli.py @@ -1,9 +1,10 @@ import logging -import subprocess -from flipper.utils.cdc import resolve_port import os +import subprocess import sys +from flipper.utils.cdc import resolve_port + def main(): logger = logging.getLogger() diff --git a/scripts/storage.py b/scripts/storage.py index 84c01021a..e04eaa7e1 100755 --- a/scripts/storage.py +++ b/scripts/storage.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 +import binascii +import filecmp +import os +import tempfile + from flipper.app import App from flipper.storage import FlipperStorage, FlipperStorageOperations from flipper.utils.cdc import resolve_port -import os -import binascii -import filecmp -import tempfile - def WrapStorageOp(func): def wrapper(*args, **kwargs): @@ -122,7 +122,7 @@ class Main(App): try: print("Text data:") print(data.decode()) - except: + except Exception: print("Binary hexadecimal data:") print(binascii.hexlify(data).decode()) diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index ce7c8b978..fdb51981b 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -1,7 +1,6 @@ from SCons.Platform import TempFileMunge from SCons.Node import FS from SCons.Errors import UserError -from SCons.Warnings import warn, WarningOnByDefault import os @@ -14,6 +13,7 @@ SetOption("max_drift", 1) ufbt_state_dir = Dir(os.environ.get("UFBT_STATE_DIR", "#.ufbt")) ufbt_script_dir = Dir(os.environ.get("UFBT_SCRIPT_DIR")) +ufbt_build_dir = ufbt_state_dir.Dir("build") ufbt_current_sdk_dir = ufbt_state_dir.Dir("current") @@ -63,16 +63,7 @@ core_env = Environment( ], ) -if "update" in BUILD_TARGETS: - SConscript( - "update.scons", - exports={"core_env": core_env}, - ) - -if "purge" in BUILD_TARGETS: - core_env.Execute(Delete(ufbt_state_dir)) - print("uFBT state purged") - Exit(0) +core_env.Append(CPPDEFINES=GetOption("extra_defines")) # Now we can import stuff bundled with SDK - it was added to sys.path by ufbt_state @@ -109,7 +100,7 @@ env = core_env.Clone( "fbt_assets", ("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}), ], - FBT_FAP_DEBUG_ELF_ROOT=ufbt_state_dir.Dir("build"), + FBT_FAP_DEBUG_ELF_ROOT=ufbt_build_dir, TEMPFILE=TempFileMunge, MAXLINELENGTH=2048, PROGSUFFIX=".elf", @@ -427,3 +418,25 @@ dist_env.PhonyTarget( "get_apiversion", "@echo $( ${UFBT_API_VERSION} $)", ) + +# Dolphin animation builder. Expects "external" directory in current dir +# with animation sources & manifests. Builds & uploads them to connected Flipper +dolphin_src_dir = original_app_dir.Dir("external") +if dolphin_src_dir.exists(): + dolphin_dir = ufbt_build_dir.Dir("dolphin") + dolphin_external = dist_env.DolphinExtBuilder( + ufbt_build_dir.Dir("dolphin"), + original_app_dir, + DOLPHIN_RES_TYPE="external", + ) + dist_env.PhonyTarget( + "dolphin_ext", + '${PYTHON3} ${FBT_SCRIPT_DIR}/storage.py send "${SOURCE}" /ext/dolphin', + source=ufbt_build_dir.Dir("dolphin"), + ) +else: + + def missing_dolphin_folder(**kw): + raise UserError(f"Dolphin folder not found: {dolphin_src_dir}") + + dist_env.PhonyTarget("dolphin_ext", Action(missing_dolphin_folder, None)) diff --git a/scripts/ufbt/commandline.scons b/scripts/ufbt/commandline.scons index 9af5e9bce..a9b91bbca 100644 --- a/scripts/ufbt/commandline.scons +++ b/scripts/ufbt/commandline.scons @@ -1,32 +1,18 @@ +AddOption( + "--extra-define", + action="append", + dest="extra_defines", + default=[], + help="Extra global define that will be passed to C/C++ compiler, can be specified multiple times", +) + AddOption( "--proxy-env", action="store", dest="proxy_env", default="", - help="Comma-separated list of additional environment variables to pass to child SCons processes", -) - -AddOption( - "--channel", - action="store", - dest="sdk_channel", - choices=["dev", "rc", "release"], - default="", - help="Release channel to use for SDK", -) - -AddOption( - "--branch", - action="store", - dest="sdk_branch", - help="Custom main repo branch to use for SDK", -) - -AddOption( - "--hw-target", - action="store", - dest="sdk_target", - help="SDK Hardware target", + help="Comma-separated list of additional environment variables to pass to " + "child SCons processes", ) vars = Variables("ufbt_options.py", ARGUMENTS) diff --git a/scripts/ufbt/site_init.py b/scripts/ufbt/site_init.py index 557085ede..8e38a36e9 100644 --- a/scripts/ufbt/site_init.py +++ b/scripts/ufbt/site_init.py @@ -1,8 +1,8 @@ -from SCons.Script import GetBuildFailures -import SCons.Errors - import atexit + +import SCons.Errors from ansi.color import fg, fx +from SCons.Script import GetBuildFailures def bf_to_str(bf): diff --git a/scripts/ufbt/site_tools/ufbt_state.py b/scripts/ufbt/site_tools/ufbt_state.py index 76c6e9acf..47f4afec4 100644 --- a/scripts/ufbt/site_tools/ufbt_state.py +++ b/scripts/ufbt/site_tools/ufbt_state.py @@ -1,12 +1,11 @@ -from SCons.Errors import StopError -from SCons.Warnings import warn, WarningOnByDefault - import json import os -import sys import pathlib +import sys from functools import reduce +from SCons.Errors import StopError + def _load_sdk_data(sdk_root): split_vars = { diff --git a/scripts/ufbt/update.scons b/scripts/ufbt/update.scons deleted file mode 100644 index 9658e0bb2..000000000 --- a/scripts/ufbt/update.scons +++ /dev/null @@ -1,37 +0,0 @@ -from SCons.Errors import StopError - -Import("core_env") - -update_env = core_env.Clone( - toolpath=[core_env["FBT_SCRIPT_DIR"].Dir("fbt_tools")], - tools=["python3"], -) -print("Updating SDK...") -ufbt_state = update_env["UFBT_STATE"] - -update_args = [ - "--ufbt-dir", - f'"{update_env["UFBT_STATE_DIR"]}"', -] - -if branch_name := GetOption("sdk_branch"): - update_args.extend(["--branch", branch_name]) -elif channel_name := GetOption("sdk_channel"): - update_args.extend(["--channel", channel_name]) -elif branch_name := ufbt_state.get("branch", None): - update_args.extend(["--branch", branch_name]) -elif channel_name := ufbt_state.get("channel", None): - update_args.extend(["--channel", channel_name]) -else: - raise StopError("No branch or channel specified for SDK update") - -if hw_target := GetOption("sdk_target"): - update_args.extend(["--hw-target", hw_target]) -else: - update_args.extend(["--hw-target", ufbt_state["hw_target"]]) - -update_env.Replace(UPDATE_ARGS=update_args) -result = update_env.Execute( - update_env.subst('$PYTHON3 "$UFBT_BOOTSTRAP_SCRIPT" $UPDATE_ARGS'), -) -Exit(result) diff --git a/scripts/update.py b/scripts/update.py index 2b0157260..0f3ee6ea8 100755 --- a/scripts/update.py +++ b/scripts/update.py @@ -1,16 +1,16 @@ #!/usr/bin/env python3 -from flipper.app import App -from flipper.utils.fff import FlipperFormatFile -from flipper.assets.coprobin import CoproBinary, get_stack_type -from flipper.assets.obdata import OptionBytesData, ObReferenceValues -from os.path import basename, join, exists +import math import os import shutil -import zlib import tarfile -import math +import zlib +from os.path import exists, join +from flipper.app import App +from flipper.assets.coprobin import CoproBinary, get_stack_type +from flipper.assets.obdata import ObReferenceValues, OptionBytesData +from flipper.utils.fff import FlipperFormatFile from slideshow import Main as SlideshowMain @@ -267,9 +267,9 @@ class Main(App): @staticmethod def batch(iterable, n=1): - l = len(iterable) - for ndx in range(0, l, n): - yield iterable[ndx : min(ndx + n, l)] + iterable_len = len(iterable) + for ndx in range(0, iterable_len, n): + yield iterable[ndx : min(ndx + n, iterable_len)] if __name__ == "__main__": diff --git a/scripts/version.py b/scripts/version.py index 880a97281..71d201abb 100644 --- a/scripts/version.py +++ b/scripts/version.py @@ -1,12 +1,12 @@ #!/usb/bin/env python3 -from flipper.app import App - -import subprocess -import os import json +import os +import subprocess from datetime import date, datetime +from flipper.app import App + class GitVersion: REVISION_SUFFIX_LENGTH = 8 diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 89ee49242..6db0e538d 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -1,12 +1,12 @@ from dataclasses import dataclass, field +from fbt.appmanifest import FlipperAppType from SCons.Node import NodeList from SCons.Warnings import warn, WarningOnByDefault -from SCons.Errors import UserError + Import("ENV") -from fbt.appmanifest import FlipperAppType appenv = ENV["APPENV"] = ENV.Clone( tools=[ From 71e85ac36723663f1d153d46f682245d8ed4a58d Mon Sep 17 00:00:00 2001 From: Raymond Lucke Date: Wed, 3 May 2023 02:38:09 -0400 Subject: [PATCH 16/28] Add HID mouse auto-clicker. (#2627) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add HID mouse auto-clicker. * Add click rate adjustment to HID auto-clicker. * Fix formatting. * HidRemote: modify jiggler/clicker event filter and allow repeat to change click rate --------- Co-authored-by: あく --- applications/external/hid_app/hid.c | 22 ++ applications/external/hid_app/hid.h | 2 + applications/external/hid_app/views.h | 1 + .../hid_app/views/hid_mouse_clicker.c | 214 ++++++++++++++++++ .../hid_app/views/hid_mouse_clicker.h | 14 ++ .../hid_app/views/hid_mouse_jiggler.c | 2 +- 6 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 applications/external/hid_app/views/hid_mouse_clicker.c create mode 100644 applications/external/hid_app/views/hid_mouse_clicker.h diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c index 949ff63b3..a4f64589d 100644 --- a/applications/external/hid_app/hid.c +++ b/applications/external/hid_app/hid.c @@ -11,6 +11,7 @@ enum HidDebugSubmenuIndex { HidSubmenuIndexMedia, HidSubmenuIndexTikTok, HidSubmenuIndexMouse, + HidSubmenuIndexMouseClicker, HidSubmenuIndexMouseJiggler, }; @@ -32,6 +33,9 @@ static void hid_submenu_callback(void* context, uint32_t index) { } else if(index == HidSubmenuIndexTikTok) { app->view_id = BtHidViewTikTok; view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewTikTok); + } else if(index == HidSubmenuIndexMouseClicker) { + app->view_id = HidViewMouseClicker; + view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseClicker); } else if(index == HidSubmenuIndexMouseJiggler) { app->view_id = HidViewMouseJiggler; view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseJiggler); @@ -53,6 +57,7 @@ static void bt_hid_connection_status_changed_callback(BtStatus status, void* con hid_keyboard_set_connected_status(hid->hid_keyboard, connected); hid_media_set_connected_status(hid->hid_media, connected); hid_mouse_set_connected_status(hid->hid_mouse, connected); + hid_mouse_clicker_set_connected_status(hid->hid_mouse_clicker, connected); hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected); hid_tiktok_set_connected_status(hid->hid_tiktok, connected); } @@ -114,6 +119,12 @@ Hid* hid_alloc(HidTransport transport) { hid_submenu_callback, app); } + submenu_add_item( + app->device_type_submenu, + "Mouse Clicker", + HidSubmenuIndexMouseClicker, + hid_submenu_callback, + app); submenu_add_item( app->device_type_submenu, "Mouse Jiggler", @@ -172,6 +183,15 @@ Hid* hid_app_alloc_view(void* context) { view_dispatcher_add_view( app->view_dispatcher, HidViewMouse, hid_mouse_get_view(app->hid_mouse)); + // Mouse clicker view + app->hid_mouse_clicker = hid_mouse_clicker_alloc(app); + view_set_previous_callback( + hid_mouse_clicker_get_view(app->hid_mouse_clicker), hid_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, + HidViewMouseClicker, + hid_mouse_clicker_get_view(app->hid_mouse_clicker)); + // Mouse jiggler view app->hid_mouse_jiggler = hid_mouse_jiggler_alloc(app); view_set_previous_callback( @@ -205,6 +225,8 @@ void hid_free(Hid* app) { hid_media_free(app->hid_media); view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse); hid_mouse_free(app->hid_mouse); + view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseClicker); + hid_mouse_clicker_free(app->hid_mouse_clicker); view_dispatcher_remove_view(app->view_dispatcher, HidViewMouseJiggler); hid_mouse_jiggler_free(app->hid_mouse_jiggler); view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok); diff --git a/applications/external/hid_app/hid.h b/applications/external/hid_app/hid.h index 8ed1664a3..49d8b4e04 100644 --- a/applications/external/hid_app/hid.h +++ b/applications/external/hid_app/hid.h @@ -20,6 +20,7 @@ #include "views/hid_keyboard.h" #include "views/hid_media.h" #include "views/hid_mouse.h" +#include "views/hid_mouse_clicker.h" #include "views/hid_mouse_jiggler.h" #include "views/hid_tiktok.h" @@ -43,6 +44,7 @@ struct Hid { HidKeyboard* hid_keyboard; HidMedia* hid_media; HidMouse* hid_mouse; + HidMouseClicker* hid_mouse_clicker; HidMouseJiggler* hid_mouse_jiggler; HidTikTok* hid_tiktok; diff --git a/applications/external/hid_app/views.h b/applications/external/hid_app/views.h index 2a44832e1..1bea3355e 100644 --- a/applications/external/hid_app/views.h +++ b/applications/external/hid_app/views.h @@ -4,6 +4,7 @@ typedef enum { HidViewKeyboard, HidViewMedia, HidViewMouse, + HidViewMouseClicker, HidViewMouseJiggler, BtHidViewTikTok, HidViewExitConfirm, diff --git a/applications/external/hid_app/views/hid_mouse_clicker.c b/applications/external/hid_app/views/hid_mouse_clicker.c new file mode 100644 index 000000000..d85affc43 --- /dev/null +++ b/applications/external/hid_app/views/hid_mouse_clicker.c @@ -0,0 +1,214 @@ +#include "hid_mouse_clicker.h" +#include +#include "../hid.h" + +#include "hid_icons.h" + +#define TAG "HidMouseClicker" +#define DEFAULT_CLICK_RATE 1 +#define MAXIMUM_CLICK_RATE 60 + +struct HidMouseClicker { + View* view; + Hid* hid; + FuriTimer* timer; +}; + +typedef struct { + bool connected; + bool running; + int rate; + HidTransport transport; +} HidMouseClickerModel; + +static void hid_mouse_clicker_start_or_restart_timer(void* context) { + furi_assert(context); + HidMouseClicker* hid_mouse_clicker = context; + + if(furi_timer_is_running(hid_mouse_clicker->timer)) { + furi_timer_stop(hid_mouse_clicker->timer); + } + + with_view_model( + hid_mouse_clicker->view, + HidMouseClickerModel * model, + { + furi_timer_start( + hid_mouse_clicker->timer, furi_kernel_get_tick_frequency() / model->rate); + }, + true); +} + +static void hid_mouse_clicker_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + HidMouseClickerModel* model = context; + + // Header + if(model->transport == HidTransportBle) { + if(model->connected) { + canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); + } else { + canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); + } + } + + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Mouse Clicker"); + + // Ok + canvas_draw_icon(canvas, 63, 25, &I_Space_65x18); + if(model->running) { + canvas_set_font(canvas, FontPrimary); + + FuriString* rate_label = furi_string_alloc(); + furi_string_printf(rate_label, "%d clicks/s\n\nUp / Down", model->rate); + elements_multiline_text(canvas, AlignLeft, 35, furi_string_get_cstr(rate_label)); + canvas_set_font(canvas, FontSecondary); + furi_string_free(rate_label); + + elements_slightly_rounded_box(canvas, 66, 27, 60, 13); + canvas_set_color(canvas, ColorWhite); + } else { + canvas_set_font(canvas, FontPrimary); + elements_multiline_text(canvas, AlignLeft, 35, "Press Start\nto start\nclicking"); + canvas_set_font(canvas, FontSecondary); + } + canvas_draw_icon(canvas, 74, 29, &I_Ok_btn_9x9); + if(model->running) { + elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Stop"); + } else { + elements_multiline_text_aligned(canvas, 91, 36, AlignLeft, AlignBottom, "Start"); + } + canvas_set_color(canvas, ColorBlack); + + // Back + canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8); + elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Quit"); +} + +static void hid_mouse_clicker_timer_callback(void* context) { + furi_assert(context); + HidMouseClicker* hid_mouse_clicker = context; + with_view_model( + hid_mouse_clicker->view, + HidMouseClickerModel * model, + { + if(model->running) { + hid_hal_mouse_press(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT); + hid_hal_mouse_release(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT); + } + }, + false); +} + +static void hid_mouse_clicker_enter_callback(void* context) { + hid_mouse_clicker_start_or_restart_timer(context); +} + +static void hid_mouse_clicker_exit_callback(void* context) { + furi_assert(context); + HidMouseClicker* hid_mouse_clicker = context; + furi_timer_stop(hid_mouse_clicker->timer); +} + +static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) { + furi_assert(context); + HidMouseClicker* hid_mouse_clicker = context; + + bool consumed = false; + bool rate_changed = false; + + if(event->type != InputTypeShort && event->type != InputTypeRepeat) { + return false; + } + + with_view_model( + hid_mouse_clicker->view, + HidMouseClickerModel * model, + { + switch(event->key) { + case InputKeyOk: + model->running = !model->running; + consumed = true; + break; + case InputKeyUp: + if(model->rate < MAXIMUM_CLICK_RATE) { + model->rate++; + } + rate_changed = true; + consumed = true; + break; + case InputKeyDown: + if(model->rate > 1) { + model->rate--; + } + rate_changed = true; + consumed = true; + break; + default: + consumed = true; + break; + } + }, + true); + + if(rate_changed) { + hid_mouse_clicker_start_or_restart_timer(context); + } + + return consumed; +} + +HidMouseClicker* hid_mouse_clicker_alloc(Hid* hid) { + HidMouseClicker* hid_mouse_clicker = malloc(sizeof(HidMouseClicker)); + + hid_mouse_clicker->view = view_alloc(); + view_set_context(hid_mouse_clicker->view, hid_mouse_clicker); + view_allocate_model( + hid_mouse_clicker->view, ViewModelTypeLocking, sizeof(HidMouseClickerModel)); + view_set_draw_callback(hid_mouse_clicker->view, hid_mouse_clicker_draw_callback); + view_set_input_callback(hid_mouse_clicker->view, hid_mouse_clicker_input_callback); + view_set_enter_callback(hid_mouse_clicker->view, hid_mouse_clicker_enter_callback); + view_set_exit_callback(hid_mouse_clicker->view, hid_mouse_clicker_exit_callback); + + hid_mouse_clicker->hid = hid; + + hid_mouse_clicker->timer = furi_timer_alloc( + hid_mouse_clicker_timer_callback, FuriTimerTypePeriodic, hid_mouse_clicker); + + with_view_model( + hid_mouse_clicker->view, + HidMouseClickerModel * model, + { + model->transport = hid->transport; + model->rate = DEFAULT_CLICK_RATE; + }, + true); + + return hid_mouse_clicker; +} + +void hid_mouse_clicker_free(HidMouseClicker* hid_mouse_clicker) { + furi_assert(hid_mouse_clicker); + + furi_timer_stop(hid_mouse_clicker->timer); + furi_timer_free(hid_mouse_clicker->timer); + + view_free(hid_mouse_clicker->view); + + free(hid_mouse_clicker); +} + +View* hid_mouse_clicker_get_view(HidMouseClicker* hid_mouse_clicker) { + furi_assert(hid_mouse_clicker); + return hid_mouse_clicker->view; +} + +void hid_mouse_clicker_set_connected_status(HidMouseClicker* hid_mouse_clicker, bool connected) { + furi_assert(hid_mouse_clicker); + with_view_model( + hid_mouse_clicker->view, + HidMouseClickerModel * model, + { model->connected = connected; }, + true); +} diff --git a/applications/external/hid_app/views/hid_mouse_clicker.h b/applications/external/hid_app/views/hid_mouse_clicker.h new file mode 100644 index 000000000..d72847baa --- /dev/null +++ b/applications/external/hid_app/views/hid_mouse_clicker.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +typedef struct Hid Hid; +typedef struct HidMouseClicker HidMouseClicker; + +HidMouseClicker* hid_mouse_clicker_alloc(Hid* bt_hid); + +void hid_mouse_clicker_free(HidMouseClicker* hid_mouse_clicker); + +View* hid_mouse_clicker_get_view(HidMouseClicker* hid_mouse_clicker); + +void hid_mouse_clicker_set_connected_status(HidMouseClicker* hid_mouse_clicker, bool connected); diff --git a/applications/external/hid_app/views/hid_mouse_jiggler.c b/applications/external/hid_app/views/hid_mouse_jiggler.c index d8f1f8928..15547eb26 100644 --- a/applications/external/hid_app/views/hid_mouse_jiggler.c +++ b/applications/external/hid_app/views/hid_mouse_jiggler.c @@ -95,7 +95,7 @@ static bool hid_mouse_jiggler_input_callback(InputEvent* event, void* context) { bool consumed = false; - if(event->key == InputKeyOk) { + if(event->type == InputTypeShort && event->key == InputKeyOk) { with_view_model( hid_mouse_jiggler->view, HidMouseJigglerModel * model, From d110a3ef262e69c7c31755f21048aa7ac4a02469 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 3 May 2023 18:48:13 +0300 Subject: [PATCH 17/28] Update wifi marauder version --- .../external/wifi_marauder_companion/wifi_marauder_app.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/wifi_marauder_companion/wifi_marauder_app.h b/applications/external/wifi_marauder_companion/wifi_marauder_app.h index 89a06f904..2f8b2f9a6 100644 --- a/applications/external/wifi_marauder_companion/wifi_marauder_app.h +++ b/applications/external/wifi_marauder_companion/wifi_marauder_app.h @@ -4,7 +4,7 @@ extern "C" { #endif -#define WIFI_MARAUDER_APP_VERSION "v0.3.3" +#define WIFI_MARAUDER_APP_VERSION "v0.3.4" typedef struct WifiMarauderApp WifiMarauderApp; From 30f79f838ecf5472be407aefaab27bef67f6f861 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 3 May 2023 20:16:20 +0300 Subject: [PATCH 18/28] rename --- applications/external/hid_app/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c index 52f4708fb..f4f59b435 100644 --- a/applications/external/hid_app/hid.c +++ b/applications/external/hid_app/hid.c @@ -129,7 +129,7 @@ Hid* hid_alloc(HidTransport transport) { submenu_add_item( app->device_type_submenu, "Keyboard", HidSubmenuIndexKeyboard, hid_submenu_callback, app); submenu_add_item( - app->device_type_submenu, "Numpad keyboard", HidSubmenuIndexNumpad, hid_submenu_callback, app); + app->device_type_submenu, "Numpad", HidSubmenuIndexNumpad, hid_submenu_callback, app); submenu_add_item( app->device_type_submenu, "Media", HidSubmenuIndexMedia, hid_submenu_callback, app); submenu_add_item( From 6874b3b4295b68c1035845cdc7a2c4912ea5cde3 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 3 May 2023 21:53:44 +0300 Subject: [PATCH 19/28] We don't use region provision so remove 00 from about screens --- applications/services/desktop/views/desktop_view_debug.c | 3 +-- applications/settings/about/about.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/applications/services/desktop/views/desktop_view_debug.c b/applications/services/desktop/views/desktop_view_debug.c index 8c72001b4..1fe957712 100644 --- a/applications/services/desktop/views/desktop_view_debug.c +++ b/applications/services/desktop/views/desktop_view_debug.c @@ -37,13 +37,12 @@ void desktop_debug_render(Canvas* canvas, void* model) { snprintf( buffer, sizeof(buffer), - "%d.F%dB%dC%d %s:%s %s", + "%d.F%dB%dC%d %s %s", furi_hal_version_get_hw_version(), furi_hal_version_get_hw_target(), furi_hal_version_get_hw_body(), furi_hal_version_get_hw_connect(), furi_hal_version_get_hw_region_name_otp(), - furi_hal_region_get_name(), my_name ? my_name : "Unknown"); canvas_draw_str(canvas, 0, 19 + STATUS_BAR_Y_SHIFT, buffer); diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c index 7d6724dc2..49f30ef9c 100644 --- a/applications/settings/about/about.c +++ b/applications/settings/about/about.c @@ -127,13 +127,12 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* furi_string_cat_printf( buffer, - "%d.F%dB%dC%d %s:%s %s\n", + "%d.F%dB%dC%d %s %s\n", furi_hal_version_get_hw_version(), furi_hal_version_get_hw_target(), furi_hal_version_get_hw_body(), furi_hal_version_get_hw_connect(), furi_hal_version_get_hw_region_name_otp(), - furi_hal_region_get_name(), my_name ? my_name : "Unknown"); furi_string_cat_printf(buffer, "Serial Number:\n"); From 3a51b3f70c110350f5366a2755af6abb394054ef Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 3 May 2023 21:58:07 +0300 Subject: [PATCH 20/28] Update changelog --- CHANGELOG.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a861b0a0..37c6260e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,12 @@ ### New changes -* NFC: Temp fix for Detect reader not collecting nonces -* Desktop: Temp fix for old backlight bug when locking by holding up arrow -* IR: Add Sharp and Vizio to Universal TV remote -* BLE Info: Show version instead of branch -* Plugins: Add new game - Bomberduck (by @leo-need-more-coffee | PR #450) -* Plugins: Fix `SWD Probe` plugin GPIO pins state reset on exit -* Plugins: Bluetooth Remote - new UI (by @krolchonok | PR #447) -* Plugins: Update **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) -* Docs: Update HowToInstall (by @krolchonok | PR #443) -* OFW PR 2627: Add HID mouse auto-clicker (by @rwl4) +* Plugins: Added Numpad keyboard to HID app (by @clipboard1 | PR #452) +* Infrared: Updated universal remote assets (by @amec0e | PR #454) +* Update slideshow: Replace QR code with good old link +* OFW: Dolphin builder in ufbt; minor ufbt/fbt improvements +* OFW: Added API version to device info +* OFW: Gui: relax some asserts in view +* OFW: Move gauge calibration to separate header, add f18 calibration +* OFW: Fix TERMINFO on Linux systems #### [🎲 Download latest extra apps pack](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip) From 348088e979f828c4ce1c2d43063d0f1a562e6bdd Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 3 May 2023 21:31:01 +0100 Subject: [PATCH 21/28] Fix BadKB USB mode and BT reset --- applications/main/bad_kb/bad_kb_app.c | 6 --- .../main/bad_kb/helpers/ducky_script.c | 49 +++++++++++++++---- .../main/bad_kb/helpers/ducky_script.h | 4 ++ 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/applications/main/bad_kb/bad_kb_app.c b/applications/main/bad_kb/bad_kb_app.c index e8b29b837..205a14022 100644 --- a/applications/main/bad_kb/bad_kb_app.c +++ b/applications/main/bad_kb/bad_kb_app.c @@ -13,12 +13,6 @@ #define BAD_KB_SETTINGS_PATH BAD_KB_APP_BASE_FOLDER "/" BAD_KB_SETTINGS_FILE_NAME -// this is the MAC address used when we do not forget paired device (BOUND STATE) -const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] = - {0x41, 0x4a, 0xef, 0xb6, 0xa9, 0xd4}; -const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] = - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - static bool bad_kb_app_custom_event_callback(void* context, uint32_t event) { furi_assert(context); BadKbApp* app = context; diff --git a/applications/main/bad_kb/helpers/ducky_script.c b/applications/main/bad_kb/helpers/ducky_script.c index 71c307cdf..d41f4ea41 100644 --- a/applications/main/bad_kb/helpers/ducky_script.c +++ b/applications/main/bad_kb/helpers/ducky_script.c @@ -12,6 +12,11 @@ #include #include +const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] = + {0x41, 0x4a, 0xef, 0xb6, 0xa9, 0xd4}; +const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + #define TAG "BadKB" #define WORKER_TAG TAG "Worker" @@ -383,7 +388,8 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) { bad_kb->app->switch_mode_thread = NULL; } // Looking for ID or BT_ID command at first line - bool reset_bt_id = !!bad_kb->bt; + bool usb_id = false; + bool bt_id = false; if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) { if(bad_kb->bt) { bad_kb->app->is_bt = false; @@ -395,11 +401,7 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) { furi_thread_start(bad_kb->app->switch_mode_thread); return false; } - if(ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1])) { - furi_check(furi_hal_usb_set_config(&usb_hid, &bad_kb->hid_cfg)); - } else { - furi_check(furi_hal_usb_set_config(&usb_hid, NULL)); - } + usb_id = ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1]); } else if(strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0) { if(!bad_kb->bt) { bad_kb->app->is_bt = true; @@ -412,12 +414,39 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) { return false; } if(!bad_kb->app->bt_remember) { - reset_bt_id = !ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]); + bt_id = ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]); } } - if(reset_bt_id) { - furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, bad_kb->app->config.bt_name); - bt_set_profile_mac_address(bad_kb->bt, bad_kb->app->config.bt_mac); + + if(bad_kb->bt) { + if(!bt_id) { + const char* bt_name = bad_kb->app->config.bt_name; + const uint8_t* bt_mac = bad_kb->app->bt_remember ? + (uint8_t*)&BAD_KB_BOUND_MAC_ADDRESS : + bad_kb->app->config.bt_mac; + bool reset_name = strncmp( + bt_name, + furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard), + BAD_KB_ADV_NAME_MAX_LEN); + bool reset_mac = memcmp( + bt_mac, + furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard), + BAD_KB_MAC_ADDRESS_LEN); + if(reset_name && reset_mac) { + furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, bt_name); + } else if(reset_name) { + bt_set_profile_adv_name(bad_kb->bt, bt_name); + } + if(reset_mac) { + bt_set_profile_mac_address(bad_kb->bt, bt_mac); + } + } + } else { + if(usb_id) { + furi_check(furi_hal_usb_set_config(&usb_hid, &bad_kb->hid_cfg)); + } else { + furi_check(furi_hal_usb_set_config(&usb_hid, NULL)); + } } storage_file_seek(script_file, 0, true); diff --git a/applications/main/bad_kb/helpers/ducky_script.h b/applications/main/bad_kb/helpers/ducky_script.h index 6a0386cf1..015586b2e 100644 --- a/applications/main/bad_kb/helpers/ducky_script.h +++ b/applications/main/bad_kb/helpers/ducky_script.h @@ -103,6 +103,10 @@ BadKbState* bad_kb_script_get_state(BadKbScript* bad_kb); #define BAD_KB_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH #define BAD_KB_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE +// this is the MAC address used when we do not forget paired device (BOUND STATE) +extern const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN]; +extern const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN]; + typedef enum { BadKbAppErrorNoFiles, BadKbAppErrorCloseRpc, From 7d152d85ff53f0ae40528938f9c45c408d7b0fe6 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 3 May 2023 21:59:20 +0100 Subject: [PATCH 22/28] Fix webupdater nextcloud subfolder --- .github/workflow_data/webupdater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflow_data/webupdater.py b/.github/workflow_data/webupdater.py index eecbf2282..52005151a 100644 --- a/.github/workflow_data/webupdater.py +++ b/.github/workflow_data/webupdater.py @@ -5,7 +5,7 @@ if __name__ == "__main__": client = nextcloud_client.Client(os.environ["NC_HOST"]) client.login(os.environ["NC_USER"], os.environ["NC_PASS"]) file = os.environ["NC_FILE"] - path = os.environ["NC_PATH"] + file + path = os.environ["NC_PATH"] + "/" + file try: client.delete(path) except Exception: From 04324dc812f39455a91ac364f4857130cf436ef3 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 3 May 2023 22:10:34 +0100 Subject: [PATCH 23/28] Fix hotfix script url --- .github/workflow_data/hotfix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflow_data/hotfix.py b/.github/workflow_data/hotfix.py index fd04d7151..0cc88471e 100644 --- a/.github/workflow_data/hotfix.py +++ b/.github/workflow_data/hotfix.py @@ -12,7 +12,7 @@ if __name__ == "__main__": event = json.load(f) release = requests.get( - event["repository"]["releases_url"].rsplit("{/")[0] + "latest", + event["repository"]["releases_url"].rsplit("{/")[0] + "/latest", headers={ "Accept": "application/vnd.github.v3+json", "Authorization": f"token {os.environ['GITHUB_TOKEN']}" From eaae10441f0b87a30f07de2ad0929fb6f1e70639 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Wed, 3 May 2023 22:12:44 +0100 Subject: [PATCH 24/28] Fix favorite timeout bugs with subghz --- .../main/subghz/scenes/subghz_scene_read_raw.c | 4 ++-- .../main/subghz/scenes/subghz_scene_transmitter.c | 15 +++++---------- applications/main/subghz/subghz.c | 10 ++++++---- applications/main/subghz/subghz_i.h | 3 +++ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 5734a8e9f..db2cf4763 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -124,7 +124,7 @@ void subghz_scene_read_raw_on_enter(void* context) { view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW); // Start sending immediately with favorites - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW)) { + if(subghz->fav_timeout) { with_view_model( subghz->subghz_read_raw->view, SubGhzReadRAWModel * model, @@ -293,7 +293,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { subghz_read_raw_stop_send(subghz->subghz_read_raw); // Exit / stop with favorites - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW)) { + if(subghz->fav_timeout) { while(scene_manager_handle_back_event(subghz->scene_manager)) ; view_dispatcher_stop(subghz->view_dispatcher); diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 7877e3c14..78b26688f 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -51,8 +51,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) { return ret; } -FuriTimer* fav_timer = NULL; - void fav_timer_callback(void* context) { SubGhz* subghz = context; scene_manager_handle_custom_event( @@ -77,7 +75,7 @@ void subghz_scene_transmitter_on_enter(void* context) { view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTransmitter); // Auto send and exit with favorites - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTransmitter)) { + if(subghz->fav_timeout) { subghz_custom_btn_set(0); scene_manager_handle_custom_event( subghz->scene_manager, SubGhzCustomEventViewTransmitterSendStart); @@ -86,9 +84,10 @@ void subghz_scene_transmitter_on_enter(void* context) { SubGhzViewTransmitterModel * model, { model->show_button = false; }, true); - fav_timer = furi_timer_alloc(fav_timer_callback, FuriTimerTypeOnce, subghz); + subghz->fav_timer = furi_timer_alloc(fav_timer_callback, FuriTimerTypeOnce, subghz); furi_timer_start( - fav_timer, XTREME_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency()); + subghz->fav_timer, + XTREME_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency()); subghz->state_notifications = SubGhzNotificationStateTx; } } @@ -134,11 +133,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { subghz_sleep(subghz); furi_hal_subghz_set_rolling_counter_mult(tmp_counter); } - if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTransmitter)) { - if(fav_timer) { - furi_timer_stop(fav_timer); - furi_timer_free(fav_timer); - } + if(subghz->fav_timeout) { while(scene_manager_handle_back_event(subghz->scene_manager)) ; view_dispatcher_stop(subghz->view_dispatcher); diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 6752b4e55..fa6e10b7a 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -474,16 +474,13 @@ int32_t subghz_app(char* p) { if(subghz_key_load(subghz, p, true)) { furi_string_set(subghz->file_path, (const char*)p); + subghz->fav_timeout = is_favorite; if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { //Load Raw TX subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneReadRAW, is_favorite); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); } else { //Load transmitter TX - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneTransmitter, is_favorite); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); } } else { @@ -512,6 +509,11 @@ int32_t subghz_app(char* p) { view_dispatcher_run(subghz->view_dispatcher); + if(subghz->fav_timer) { + furi_timer_stop(subghz->fav_timer); + furi_timer_free(subghz->fav_timer); + } + furi_hal_power_suppress_charge_exit(); // Disable power for External CC1101 if it was enabled and module is connected furi_hal_subghz_disable_ext_power(); diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index faae35fa2..37318580f 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -131,6 +131,9 @@ struct SubGhz { SubGhzDecodeRawState decode_raw_state; SubGhzFileEncoderWorker* decode_raw_file_worker_encoder; + bool fav_timeout; + FuriTimer* fav_timer; + void* rpc_ctx; }; From ee94d48736a892b5168e5b16680dcc48296b1134 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 4 May 2023 01:17:58 +0100 Subject: [PATCH 25/28] Fix lockscreen backlight flicker --- applications/services/desktop/desktop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 45435411a..127afdcdb 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -133,7 +133,6 @@ void desktop_lock(Desktop* desktop) { scene_manager_set_scene_state( desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER); scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked); - notification_message(desktop->notification, &sequence_display_backlight_off_delay_1000); } void desktop_unlock(Desktop* desktop) { From 0e28cfc50bbbecc52d6c07c6f29828ecdf050863 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 4 May 2023 02:12:19 +0100 Subject: [PATCH 26/28] Fix hotfix script --- .github/workflows/hotfix.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/hotfix.yml b/.github/workflows/hotfix.yml index 505f9c676..85bf00171 100644 --- a/.github/workflows/hotfix.yml +++ b/.github/workflows/hotfix.yml @@ -55,6 +55,8 @@ jobs: - name: "Upload hotfix" run: python .github/workflow_data/hotfix.py + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - name: "Merge pull request" uses: "pascalgn/automerge-action@v0.15.6" From dbade67dc4663568c948c75b96e02ee05eaa043f Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 4 May 2023 03:17:44 +0100 Subject: [PATCH 27/28] Bump hotfix version --- fbt_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fbt_options.py b/fbt_options.py index 5c874357a..3fdcc6e30 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -14,7 +14,7 @@ DEBUG = 0 # Suffix to add to files when building distribution # If OS environment has DIST_SUFFIX set, it will be used instead -DIST_SUFFIX = "XFW-0045_02052023" +DIST_SUFFIX = "XFW-0045_04052023" # Coprocessor firmware COPRO_OB_DATA = "scripts/ob.data" From 103abfef86a90fd9ea9709b28aa4a9bfb3f48f65 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 4 May 2023 03:18:52 +0100 Subject: [PATCH 28/28] Fix hotfix script again --- .github/workflow_data/hotfix.py | 43 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/.github/workflow_data/hotfix.py b/.github/workflow_data/hotfix.py index 0cc88471e..cb454ae56 100644 --- a/.github/workflow_data/hotfix.py +++ b/.github/workflow_data/hotfix.py @@ -19,30 +19,30 @@ if __name__ == "__main__": } ).json() - artifacts = ( - os.environ['ARTIFACT_TGZ'], - os.environ['ARTIFACT_ZIP'] - ) + artifacts = { + os.environ['ARTIFACT_TGZ']: "application/gzip", + os.environ['ARTIFACT_ZIP']: "application/zip" + } for asset in release["assets"]: - if asset["name"] in artifacts: - req = requests.delete( - asset["url"], - headers={ - "Accept": "application/vnd.github.v3+json", - "Authorization": f"token {os.environ['GITHUB_TOKEN']}" - } - ) - if not req.ok: - print(f"{req.url = }\n{req.status_code = }\n{req.content = }") - sys.exit(1) + req = requests.delete( + asset["url"], + headers={ + "Accept": "application/vnd.github.v3+json", + "Authorization": f"token {os.environ['GITHUB_TOKEN']}" + } + ) + if not req.ok: + print(f"{req.url = }\n{req.status_code = }\n{req.content = }") + sys.exit(1) - for artifact in artifacts: + for artifact, mediatype in artifacts.items(): req = requests.post( release["upload_url"].rsplit("{?", 1)[0], headers={ "Accept": "application/vnd.github.v3+json", - "Authorization": f"token {os.environ['GITHUB_TOKEN']}" + "Authorization": f"token {os.environ['GITHUB_TOKEN']}", + "Content-Type": mediatype }, params={ "name": artifact @@ -59,8 +59,13 @@ if __name__ == "__main__": body = release["body"] body = re.sub( - r"(https://lab\.flipper\.net/\?url=).*?(&channel=XFW-Updater&version=" + os.environ['VERSION_TAG'] + r")", - r"\1" + os.environ['ARTIFACT_WEB'] + r"\2", + r"(https://lab\.flipper\.net/\?url=).*?(&channel=XFW-Updater&version=)[A-Za-z0-9_-]+", + r"\1" + os.environ['ARTIFACT_WEB'] + r"\2" + os.environ['VERSION_TAG'], + body + ) + body = re.sub( + r"(https://github\.com/ClaraCrazy/Flipper-Xtreme/releases/download/[A-Za-z0-9_-]+?/)[A-Za-z0-9_-]+", + r"\1" + os.environ['VERSION_TAG'], body ) body = body.replace("