From 0d8518d31ded15a2f1ae6ef559f39c8a8abf286e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 6 Apr 2023 17:06:19 +0800 Subject: [PATCH 01/22] [FL-3232] FuriHal: fix gpio naming and add explicit pulls for vibro, speaker and ir_tx (#2565) * FuriHal: fix gpio naming and add explicit pulls for vibro, speaker and ir_tx * Github: workflow event debug print * Github: proper PR head commit SHA extraction in get_env.py --- .github/workflows/build.yml | 4 ++-- .github/workflows/merge_report.yml | 2 +- .github/workflows/pvs_studio.yml | 2 +- applications/debug/accessor/accessor_app.cpp | 2 +- .../examples/example_thermo/README.md | 4 ++-- .../examples/example_thermo/example_thermo.c | 4 ++-- applications/main/onewire/onewire_cli.c | 2 +- firmware/targets/f18/api_symbols.csv | 8 +++---- .../targets/f18/furi_hal/furi_hal_resources.c | 20 ++++++++++-------- .../targets/f18/furi_hal/furi_hal_resources.h | 6 +++--- firmware/targets/f7/api_symbols.csv | 8 +++---- .../targets/f7/furi_hal/furi_hal_ibutton.c | 10 ++++----- .../targets/f7/furi_hal/furi_hal_infrared.c | 4 ++-- firmware/targets/f7/furi_hal/furi_hal_power.c | 4 ++-- .../targets/f7/furi_hal/furi_hal_resources.c | 21 +++++++++++-------- .../targets/f7/furi_hal/furi_hal_resources.h | 6 +++--- .../targets/f7/furi_hal/furi_hal_speaker.c | 2 +- firmware/targets/f7/furi_hal/furi_hal_vibro.c | 6 +++--- .../protocols/dallas/protocol_group_dallas.c | 4 ++-- scripts/get_env.py | 2 +- 20 files changed, 63 insertions(+), 58 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 56e50d5f4..5f6f50a9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: else TYPE="other" fi - python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" + python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" echo random_hash=$(openssl rand -base64 40 | shasum -a 256 | awk '{print $1}') >> $GITHUB_OUTPUT echo "event_type=$TYPE" >> $GITHUB_OUTPUT @@ -182,7 +182,7 @@ jobs: else TYPE="other" fi - python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" + python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" - name: 'Build the firmware' run: | diff --git a/.github/workflows/merge_report.yml b/.github/workflows/merge_report.yml index 71515e1c5..5b7d5fcbf 100644 --- a/.github/workflows/merge_report.yml +++ b/.github/workflows/merge_report.yml @@ -30,7 +30,7 @@ jobs: else TYPE="other" fi - python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" + python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" - name: 'Check ticket and report' run: | diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index 6dbf84edb..b8c4d7a36 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -38,7 +38,7 @@ jobs: else TYPE="other" fi - python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" + python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" - name: 'Supply PVS credentials' run: | diff --git a/applications/debug/accessor/accessor_app.cpp b/applications/debug/accessor/accessor_app.cpp index 337437d0e..2e40b3c35 100644 --- a/applications/debug/accessor/accessor_app.cpp +++ b/applications/debug/accessor/accessor_app.cpp @@ -34,7 +34,7 @@ void AccessorApp::run(void) { AccessorApp::AccessorApp() : text_store{0} { notification = static_cast(furi_record_open(RECORD_NOTIFICATION)); - onewire_host = onewire_host_alloc(&ibutton_gpio); + onewire_host = onewire_host_alloc(&gpio_ibutton); furi_hal_power_enable_otg(); } diff --git a/applications/examples/example_thermo/README.md b/applications/examples/example_thermo/README.md index fa00264dc..08240a1f8 100644 --- a/applications/examples/example_thermo/README.md +++ b/applications/examples/example_thermo/README.md @@ -33,10 +33,10 @@ It is possible to use other GPIO pin as a 1-Wire data pin. In order to change it - gpio_ext_pa4 - gpio_ext_pa6 - gpio_ext_pa7 - - ibutton_gpio + - gpio_ibutton */ -#define THERMO_GPIO_PIN (ibutton_gpio) +#define THERMO_GPIO_PIN (gpio_ibutton) ``` Do not forget about the external pull-up resistor as these pins do not have one built-in. diff --git a/applications/examples/example_thermo/example_thermo.c b/applications/examples/example_thermo/example_thermo.c index 4241cb59d..5cb8863a4 100644 --- a/applications/examples/example_thermo/example_thermo.c +++ b/applications/examples/example_thermo/example_thermo.c @@ -43,10 +43,10 @@ - gpio_ext_pa4 - gpio_ext_pa6 - gpio_ext_pa7 - - ibutton_gpio + - gpio_ibutton */ -#define THERMO_GPIO_PIN (ibutton_gpio) +#define THERMO_GPIO_PIN (gpio_ibutton) /* Flags which the reader thread responds to */ typedef enum { diff --git a/applications/main/onewire/onewire_cli.c b/applications/main/onewire/onewire_cli.c index 4c16fb389..5f6cdc670 100644 --- a/applications/main/onewire/onewire_cli.c +++ b/applications/main/onewire/onewire_cli.c @@ -25,7 +25,7 @@ static void onewire_cli_print_usage() { static void onewire_cli_search(Cli* cli) { UNUSED(cli); - OneWireHost* onewire = onewire_host_alloc(&ibutton_gpio); + OneWireHost* onewire = onewire_host_alloc(&gpio_ibutton); uint8_t address[8]; bool done = false; diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 3806ac47b..5d5b7bbcf 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,+,20.1,, +Version,+,21.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2161,7 +2161,7 @@ Variable,+,gpio_usart_rx,const GpioPin, Variable,+,gpio_usart_tx,const GpioPin, Variable,+,gpio_usb_dm,const GpioPin, Variable,+,gpio_usb_dp,const GpioPin, -Variable,+,ibutton_gpio,const GpioPin, +Variable,+,gpio_ibutton,const GpioPin, Variable,+,input_pins,const InputPin[], Variable,+,input_pins_count,const size_t, Variable,+,message_blink_set_color_blue,const NotificationMessage, @@ -2309,7 +2309,7 @@ Variable,+,message_red_255,const NotificationMessage, Variable,+,message_sound_off,const NotificationMessage, Variable,+,message_vibro_off,const NotificationMessage, Variable,+,message_vibro_on,const NotificationMessage, -Variable,+,periph_power,const GpioPin, +Variable,+,gpio_periph_power,const GpioPin, Variable,+,sequence_audiovisual_alert,const NotificationSequence, Variable,+,sequence_blink_blue_10,const NotificationSequence, Variable,+,sequence_blink_blue_100,const NotificationSequence, @@ -2364,4 +2364,4 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface, Variable,+,usb_hid,FuriHalUsbInterface, Variable,+,usb_hid_u2f,FuriHalUsbInterface, Variable,+,usbd_devfs,const usbd_driver, -Variable,+,vibro_gpio,const GpioPin, +Variable,+,gpio_vibro,const GpioPin, diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index abb258cb1..19bc9f998 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -6,8 +6,8 @@ #define TAG "FuriHalResources" -const GpioPin vibro_gpio = {.port = GPIOA, .pin = LL_GPIO_PIN_8}; -const GpioPin ibutton_gpio = {.port = GPIOB, .pin = LL_GPIO_PIN_14}; +const GpioPin gpio_vibro = {.port = GPIOA, .pin = LL_GPIO_PIN_8}; +const GpioPin gpio_ibutton = {.port = GPIOB, .pin = LL_GPIO_PIN_14}; const GpioPin gpio_display_cs = {.port = GPIOC, .pin = LL_GPIO_PIN_11}; const GpioPin gpio_display_rst_n = {.port = GPIOB, .pin = LL_GPIO_PIN_0}; @@ -57,7 +57,7 @@ const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8}; -const GpioPin periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3}; const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11}; const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12}; @@ -118,8 +118,8 @@ void furi_hal_resources_init_early() { furi_hal_resources_init_input_pins(GpioModeInput); // SD Card stepdown control - furi_hal_gpio_write(&periph_power, 1); - furi_hal_gpio_init(&periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_periph_power, 1); + furi_hal_gpio_init(&gpio_periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); // Display pins furi_hal_gpio_write(&gpio_display_rst_n, 1); @@ -165,6 +165,10 @@ void furi_hal_resources_init() { // Button pins furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); + // Explicit pulls pins + furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_display_rst_n, 0); @@ -176,9 +180,7 @@ void furi_hal_resources_init() { furi_hal_gpio_init(&gpio_sdcard_cd, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_sdcard_cd, 0); - furi_hal_gpio_init(&vibro_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ibutton, GpioModeAnalog, GpioPullNo, GpioSpeedLow); NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(EXTI0_IRQn); @@ -222,7 +224,7 @@ int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) { return 15; else if(gpio == &gpio_ext_pc0) return 16; - else if(gpio == &ibutton_gpio) + else if(gpio == &gpio_ibutton) return 17; else return -1; diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.h b/firmware/targets/f18/furi_hal/furi_hal_resources.h index a24afbf94..3c4708d15 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.h @@ -50,8 +50,8 @@ extern const size_t input_pins_count; extern const GpioPinRecord gpio_pins[]; extern const size_t gpio_pins_count; -extern const GpioPin vibro_gpio; -extern const GpioPin ibutton_gpio; +extern const GpioPin gpio_vibro; +extern const GpioPin gpio_ibutton; extern const GpioPin gpio_display_cs; extern const GpioPin gpio_display_rst_n; @@ -100,7 +100,7 @@ extern const GpioPin gpio_i2c_power_scl; extern const GpioPin gpio_speaker; -extern const GpioPin periph_power; +extern const GpioPin gpio_periph_power; extern const GpioPin gpio_usb_dm; extern const GpioPin gpio_usb_dp; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index efc20b4a7..89984352a 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,+,20.1,, +Version,+,21.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -3100,7 +3100,7 @@ Variable,+,gpio_usart_rx,const GpioPin, Variable,+,gpio_usart_tx,const GpioPin, Variable,+,gpio_usb_dm,const GpioPin, Variable,+,gpio_usb_dp,const GpioPin, -Variable,+,ibutton_gpio,const GpioPin, +Variable,+,gpio_ibutton,const GpioPin, Variable,+,input_pins,const InputPin[], Variable,+,input_pins_count,const size_t, Variable,+,lfrfid_protocols,const ProtocolBase*[], @@ -3249,7 +3249,7 @@ Variable,+,message_red_255,const NotificationMessage, Variable,+,message_sound_off,const NotificationMessage, Variable,+,message_vibro_off,const NotificationMessage, Variable,+,message_vibro_on,const NotificationMessage, -Variable,+,periph_power,const GpioPin, +Variable,+,gpio_periph_power,const GpioPin, Variable,+,sequence_audiovisual_alert,const NotificationSequence, Variable,+,sequence_blink_blue_10,const NotificationSequence, Variable,+,sequence_blink_blue_100,const NotificationSequence, @@ -3307,4 +3307,4 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface, Variable,+,usb_hid,FuriHalUsbInterface, Variable,+,usb_hid_u2f,FuriHalUsbInterface, Variable,+,usbd_devfs,const usbd_driver, -Variable,+,vibro_gpio,const GpioPin, +Variable,+,gpio_vibro,const GpioPin, diff --git a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c index f19fd0a0e..c8041c9f2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c +++ b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c @@ -93,15 +93,15 @@ void furi_hal_ibutton_emulate_stop() { } void furi_hal_ibutton_pin_configure() { - furi_hal_gpio_write(&ibutton_gpio, true); - furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_ibutton, true); + furi_hal_gpio_init(&gpio_ibutton, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); } void furi_hal_ibutton_pin_reset() { - furi_hal_gpio_write(&ibutton_gpio, true); - furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_ibutton, true); + furi_hal_gpio_init(&gpio_ibutton, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } void furi_hal_ibutton_pin_write(const bool state) { - furi_hal_gpio_write(&ibutton_gpio, state); + furi_hal_gpio_write(&gpio_ibutton, state); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index c1d24f803..2598e5fa3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -17,7 +17,7 @@ #if INFRARED_TX_DEBUG == 1 #define gpio_infrared_tx gpio_infrared_tx_debug -const GpioPin gpio_infrared_tx_debug = {.port = GPIOA, .pin = GPIO_PIN_7}; +const GpioPin gpio_infrared_tx_debug = {.port = GPIOA, .pin = GpioModeAnalog}; #endif #define INFRARED_TIM_TX_DMA_BUFFER_SIZE 200 @@ -567,7 +567,7 @@ static void furi_hal_infrared_async_tx_free_resources(void) { (furi_hal_infrared_state == InfraredStateIdle) || (furi_hal_infrared_state == InfraredStateAsyncTxStopped)); - furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL); furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL); LL_TIM_DeInit(TIM1); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index dd7c34ae7..fd601ec7e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -440,11 +440,11 @@ float furi_hal_power_get_usb_voltage() { } void furi_hal_power_enable_external_3_3v() { - furi_hal_gpio_write(&periph_power, 1); + furi_hal_gpio_write(&gpio_periph_power, 1); } void furi_hal_power_disable_external_3_3v() { - furi_hal_gpio_write(&periph_power, 0); + furi_hal_gpio_write(&gpio_periph_power, 0); } void furi_hal_power_suppress_charge_enter() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index d0d85cb2d..df9530079 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -6,8 +6,8 @@ #define TAG "FuriHalResources" -const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; -const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; +const GpioPin gpio_vibro = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; +const GpioPin gpio_ibutton = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; const GpioPin gpio_cc1101_g0 = {.port = CC1101_G0_GPIO_Port, .pin = CC1101_G0_Pin}; const GpioPin gpio_rf_sw_0 = {.port = RF_SW_0_GPIO_Port, .pin = RF_SW_0_Pin}; @@ -59,7 +59,7 @@ const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8}; -const GpioPin periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3}; const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11}; const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12}; @@ -106,8 +106,8 @@ void furi_hal_resources_init_early() { furi_hal_resources_init_input_pins(GpioModeInput); // SD Card stepdown control - furi_hal_gpio_write(&periph_power, 1); - furi_hal_gpio_init(&periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_periph_power, 1); + furi_hal_gpio_init(&gpio_periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); // Display pins furi_hal_gpio_write(&gpio_display_rst_n, 1); @@ -153,6 +153,11 @@ void furi_hal_resources_init() { // Button pins furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); + // Explicit pulls pins + furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_display_rst_n, 0); @@ -164,9 +169,7 @@ void furi_hal_resources_init() { furi_hal_gpio_init(&gpio_sdcard_cd, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_sdcard_cd, 0); - furi_hal_gpio_init(&vibro_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ibutton, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(&gpio_nfc_irq_rfid_pull, GpioModeInterruptRise, GpioPullNo, GpioSpeedLow); @@ -213,7 +216,7 @@ int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) { return 15; else if(gpio == &gpio_ext_pc0) return 16; - else if(gpio == &ibutton_gpio) + else if(gpio == &gpio_ibutton) return 17; else return -1; diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index 04b99a84e..f29917300 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -50,8 +50,8 @@ extern const size_t input_pins_count; extern const GpioPinRecord gpio_pins[]; extern const size_t gpio_pins_count; -extern const GpioPin vibro_gpio; -extern const GpioPin ibutton_gpio; +extern const GpioPin gpio_vibro; +extern const GpioPin gpio_ibutton; extern const GpioPin gpio_cc1101_g0; extern const GpioPin gpio_rf_sw_0; @@ -102,7 +102,7 @@ extern const GpioPin gpio_i2c_power_scl; extern const GpioPin gpio_speaker; -extern const GpioPin periph_power; +extern const GpioPin gpio_periph_power; extern const GpioPin gpio_usb_dm; extern const GpioPin gpio_usb_dp; diff --git a/firmware/targets/f7/furi_hal/furi_hal_speaker.c b/firmware/targets/f7/furi_hal/furi_hal_speaker.c index c4a0bdd1e..5421509cc 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_speaker.c +++ b/firmware/targets/f7/furi_hal/furi_hal_speaker.c @@ -52,7 +52,7 @@ void furi_hal_speaker_release() { furi_check(furi_hal_speaker_is_mine()); furi_hal_speaker_stop(); - furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); furi_hal_power_insomnia_exit(); furi_check(furi_mutex_release(furi_hal_speaker_mutex) == FuriStatusOk); diff --git a/firmware/targets/f7/furi_hal/furi_hal_vibro.c b/firmware/targets/f7/furi_hal/furi_hal_vibro.c index 4315ea637..f46784677 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_vibro.c +++ b/firmware/targets/f7/furi_hal/furi_hal_vibro.c @@ -4,11 +4,11 @@ #define TAG "FuriHalVibro" void furi_hal_vibro_init() { - furi_hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_write(&vibro_gpio, false); + furi_hal_gpio_init(&gpio_vibro, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_vibro, false); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_vibro_on(bool value) { - furi_hal_gpio_write(&vibro_gpio, value); + furi_hal_gpio_write(&gpio_vibro, value); } diff --git a/lib/ibutton/protocols/dallas/protocol_group_dallas.c b/lib/ibutton/protocols/dallas/protocol_group_dallas.c index d0ffa511b..63ec97855 100644 --- a/lib/ibutton/protocols/dallas/protocol_group_dallas.c +++ b/lib/ibutton/protocols/dallas/protocol_group_dallas.c @@ -14,8 +14,8 @@ typedef struct { static iButtonProtocolGroupDallas* ibutton_protocol_group_dallas_alloc() { iButtonProtocolGroupDallas* group = malloc(sizeof(iButtonProtocolGroupDallas)); - group->host = onewire_host_alloc(&ibutton_gpio); - group->bus = onewire_slave_alloc(&ibutton_gpio); + group->host = onewire_host_alloc(&gpio_ibutton); + group->bus = onewire_slave_alloc(&gpio_ibutton); return group; } diff --git a/scripts/get_env.py b/scripts/get_env.py index f661f38d6..92f9243c2 100644 --- a/scripts/get_env.py +++ b/scripts/get_env.py @@ -32,7 +32,7 @@ def parse_args(): def get_commit_json(event): context = ssl._create_unverified_context() commit_url = event["pull_request"]["base"]["repo"]["commits_url"].replace( - "{/sha}", f"/{event['after']}" + "{/sha}", f"/{event['pull_request']['head']['sha']}" ) with urllib.request.urlopen(commit_url, context=context) as commit_file: commit_json = json.loads(commit_file.read().decode("utf-8")) From 89161a7a1e14d6365626e76068035acc45954934 Mon Sep 17 00:00:00 2001 From: hedger Date: Thu, 6 Apr 2023 23:37:12 +0400 Subject: [PATCH 02/22] scripts: sconsdist: added stub file artifact for older ufbt (#2568) * scripts: sconsdist: added stub file artifact for older ufbt * scripts: sconsdist: not creating dummy SDK archive --- scripts/sconsdist.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index c2cfecd4e..2e28ebef4 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -84,21 +84,16 @@ class Main(App): if exists(sdk_folder := join(obj_directory, foldertype)): self.note_dist_component(foldertype, "dir", sdk_folder) - def package_zip(self, foldertype, sdk_folder): + # TODO: remove this after everyone migrates to new uFBT + self.create_zip_stub("lib") + + def create_zip_stub(self, foldertype): with zipfile.ZipFile( self.get_dist_path(self.get_dist_file_name(foldertype, "zip")), "w", zipfile.ZIP_DEFLATED, - ) as zf: - for root, _, files in walk(sdk_folder): - for file in files: - zf.write( - join(root, file), - relpath( - join(root, file), - sdk_folder, - ), - ) + ) as _: + pass def copy(self) -> int: self._dist_components: dict[str, str] = dict() From 6cc5f30c84e6991af1fa7318922a6aab02ce1a67 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Fri, 7 Apr 2023 07:02:29 +0400 Subject: [PATCH 03/22] Fix gpio state isp programmer (#2567) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ISP: fix state gpio ISP Programmer * WS: delete string debug Co-authored-by: あく --- applications/external/avr_isp_programmer/helpers/avr_isp.c | 1 + .../external/avr_isp_programmer/helpers/avr_isp_worker_rw.c | 5 +++-- .../external/avr_isp_programmer/lib/driver/avr_isp_prog.c | 1 + .../external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c | 2 -- .../external/weather_station/protocols/lacrosse_tx141thbv2.c | 5 ----- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c index 76e0a80b0..51b4f8846 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp.c @@ -152,6 +152,7 @@ bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) { } } } + if(instance->spi) avr_isp_spi_sw_free(instance->spi); return false; } diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c index fc8d3b09f..0ee5cefa1 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c @@ -198,9 +198,10 @@ bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) { } avr_isp_end_pmode(instance->avr_isp); - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); - } while(0); + + furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + if(instance->callback) { if(instance->chip_arr_ind > avr_isp_chip_arr_size) { instance->callback(instance->context, "No detect", instance->chip_detect, 0); diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c index b457e4c27..b3c81f3b1 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c @@ -317,6 +317,7 @@ static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) { } } } + if(instance->spi) avr_isp_spi_sw_free(instance->spi); return false; } diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c index f60850c84..c6d9d54c8 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c @@ -18,7 +18,6 @@ struct AvrIspSpiSw { AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed) { AvrIspSpiSw* instance = malloc(sizeof(AvrIspSpiSw)); instance->speed_wait_time = speed; - instance->miso = AVR_ISP_SPI_SW_MISO; instance->mosi = AVR_ISP_SPI_SW_MOSI; instance->sck = AVR_ISP_SPI_SW_SCK; @@ -40,7 +39,6 @@ void avr_isp_spi_sw_free(AvrIspSpiSw* instance) { furi_hal_gpio_init(instance->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(instance->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(instance->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - free(instance); } diff --git a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c b/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c index 33a61cee0..f2fddd40c 100644 --- a/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c +++ b/applications/external/weather_station/protocols/lacrosse_tx141thbv2.c @@ -217,11 +217,6 @@ void ws_protocol_decoder_lacrosse_tx141thbv2_feed(void* context, bool level, uin ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2) && (DURATION_DIFF(duration, ws_protocol_lacrosse_tx141thbv2_const.te_short * 4) < ws_protocol_lacrosse_tx141thbv2_const.te_delta * 2))) { - FURI_LOG_E( - "WS", - "%llX %d", - instance->decoder.decode_data, - instance->decoder.decode_count_bit); if((instance->decoder.decode_count_bit == ws_protocol_lacrosse_tx141thbv2_const.min_count_bit_for_found) || (instance->decoder.decode_count_bit == LACROSSE_TX141TH_BV2_BIT_COUNT)) { From c2997bb1fcaac33df4f3431f6e1f88fd09926bb5 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 9 Apr 2023 23:56:41 +0300 Subject: [PATCH 04/22] Trying to fix button issues in sbughz remote --- applications/main/subghz/views/transmitter.c | 1 + applications/main/subghz_remote/subghz_remote_app.c | 2 ++ lib/subghz/blocks/custom_btn.c | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/applications/main/subghz/views/transmitter.c b/applications/main/subghz/views/transmitter.c index e8c53d1ed..2bec77690 100644 --- a/applications/main/subghz/views/transmitter.c +++ b/applications/main/subghz/views/transmitter.c @@ -137,6 +137,7 @@ bool subghz_view_transmitter_input(InputEvent* event, void* context) { true); if(can_be_sent && event->key == InputKeyOk && event->type == InputTypePress) { + subghz_custom_btn_set(0); with_view_model( subghz_transmitter->view, SubGhzViewTransmitterModel * model, diff --git a/applications/main/subghz_remote/subghz_remote_app.c b/applications/main/subghz_remote/subghz_remote_app.c index 040273838..a6225e1b5 100644 --- a/applications/main/subghz_remote/subghz_remote_app.c +++ b/applications/main/subghz_remote/subghz_remote_app.c @@ -354,6 +354,8 @@ bool subghz_remote_key_load( bool res = false; + subghz_custom_btn_set(0); + do { // load frequency from file if(!flipper_format_read_uint32(fff_file, "Frequency", &preset->frequency, 1)) { diff --git a/lib/subghz/blocks/custom_btn.c b/lib/subghz/blocks/custom_btn.c index dd1436798..3023e09ea 100644 --- a/lib/subghz/blocks/custom_btn.c +++ b/lib/subghz/blocks/custom_btn.c @@ -1,7 +1,7 @@ #include "custom_btn.h" -static uint8_t custom_btn_id; -static uint8_t custom_btn_original; +static uint8_t custom_btn_id = 0; +static uint8_t custom_btn_original = 0; static uint8_t custom_btn_max_btns = 0; void subghz_custom_btn_set(uint8_t b) { From 4c7fa05bfe46fdddd0863bb252f7e6b7c7f26169 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 10 Apr 2023 02:55:16 +0300 Subject: [PATCH 05/22] Add alutech table to enviroment alloc and free --- lib/subghz/environment.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index b39b259d4..5ded243c4 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -16,6 +16,7 @@ SubGhzEnvironment* subghz_environment_alloc() { instance->protocol_registry = NULL; instance->came_atomo_rainbow_table_file_name = NULL; instance->nice_flor_s_rainbow_table_file_name = NULL; + instance->alutech_at_4n_rainbow_table_file_name = NULL; return instance; } @@ -26,6 +27,7 @@ void subghz_environment_free(SubGhzEnvironment* instance) { instance->protocol_registry = NULL; instance->came_atomo_rainbow_table_file_name = NULL; instance->nice_flor_s_rainbow_table_file_name = NULL; + instance->alutech_at_4n_rainbow_table_file_name = NULL; subghz_keystore_free(instance->keystore); free(instance); From b9ccb274a77bf1f8aac56afbab7a3cc98fb6cf8f Mon Sep 17 00:00:00 2001 From: hedger Date: Mon, 10 Apr 2023 18:46:22 +0400 Subject: [PATCH 06/22] ufbt: project & debugging updates (#2572) * ufbt: removed warning in "channel=dev" update mode * ufbt: removed API version warning; added get_blackmagic & get_apiversion targets * ufbt: updater project template to include blackmagic & jlink targets * ufbt: project template: fixes & updates * ufbt: project template: added config update shortcut * sdk: using fixed names for file components --- .gitignore | 2 +- scripts/sconsdist.py | 6 +- scripts/ufbt/SConstruct | 22 +++++++ .../ufbt/project_template/.vscode/launch.json | 63 +++++++++---------- .../ufbt/project_template/.vscode/tasks.json | 36 +++++++---- .../app_template/application.fam | 2 +- scripts/ufbt/site_tools/ufbt_state.py | 6 -- site_scons/extapps.scons | 2 +- 8 files changed, 83 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 81e985db7..89e129ace 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,7 @@ bindings/ Brewfile.lock.json # Visual Studio Code -.vscode/ +/.vscode/ # Kate .kateproject diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index 2e28ebef4..af2554d0a 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -181,9 +181,9 @@ class Main(App): ) as zf: for component_key in sdk_components_keys: component_path = self._dist_components.get(component_key) - components_paths[component_key] = basename(component_path) if component_key.endswith(".dir"): + components_paths[component_key] = basename(component_path) for root, dirnames, files in walk(component_path): if "__pycache__" in dirnames: dirnames.remove("__pycache__") @@ -199,7 +199,9 @@ class Main(App): ), ) else: - zf.write(component_path, basename(component_path)) + # We use fixed names for files to avoid having to regenerate VSCode project + components_paths[component_key] = component_key + zf.write(component_path, component_key) zf.writestr( "components.json", diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index a82189c14..7228e2f51 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -163,6 +163,18 @@ dist_env.Alias("flash", openocd_target) if env["FORCE"]: env.AlwaysBuild(openocd_target) + +firmware_jflash = dist_env.JFlash( + dist_env["UFBT_STATE_DIR"].File("jflash"), + dist_env["FW_BIN"], + JFLASHADDR="0x20000000", +) +dist_env.Alias("firmware_jflash", firmware_jflash) +dist_env.Alias("jflash", firmware_jflash) +if env["FORCE"]: + env.AlwaysBuild(firmware_jflash) + + firmware_debug = dist_env.PhonyTarget( "debug", "${GDBPYCOM}", @@ -391,3 +403,13 @@ AddPostAction( dist_env.Precious(app_template_dist) dist_env.NoClean(app_template_dist) dist_env.Alias("create", app_template_dist) + +dist_env.PhonyTarget( + "get_blackmagic", + "@echo $( ${BLACKMAGIC_ADDR} $)", +) + +dist_env.PhonyTarget( + "get_apiversion", + "@echo $( ${UFBT_API_VERSION} $)", +) diff --git a/scripts/ufbt/project_template/.vscode/launch.json b/scripts/ufbt/project_template/.vscode/launch.json index d9c98dcc1..697de9a49 100644 --- a/scripts/ufbt/project_template/.vscode/launch.json +++ b/scripts/ufbt/project_template/.vscode/launch.json @@ -2,19 +2,16 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "inputs": [ - // { - // "id": "BLACKMAGIC", - // "type": "command", - // "command": "shellCommand.execute", - // "args": { - // "useSingleResult": true, - // "env": { - // "PATH": "${workspaceFolder};${env:PATH}" - // }, - // "command": "./fbt get_blackmagic", - // "description": "Get Blackmagic device", - // } - // }, + { + "id": "BLACKMAGIC", + "type": "command", + "command": "shellCommand.execute", + "args": { + "description": "Get Blackmagic device", + "useSingleResult": true, + "command": "ufbt -s get_blackmagic", + } + }, ], "configurations": [ { @@ -57,26 +54,26 @@ ], // "showDevDebugOutput": "raw", }, - // { - // "name": "Attach FW (blackmagic)", - // "cwd": "${workspaceFolder}", - // "executable": "@UFBT_FIRMWARE_ELF@", - // "request": "attach", - // "type": "cortex-debug", - // "servertype": "external", - // "gdbTarget": "${input:BLACKMAGIC}", - // "svdFile": "@UFBT_DEBUG_DIR@/STM32WB55_CM4.svd", - // "rtos": "FreeRTOS", - // "postAttachCommands": [ - // "monitor swdp_scan", - // "attach 1", - // "set confirm off", - // "set mem inaccessible-by-default off", - // "source @UFBT_DEBUG_DIR@/flipperapps.py", - // "fap-set-debug-elf-root @UFBT_DEBUG_ELF_DIR@" - // ] - // // "showDevDebugOutput": "raw", - // }, + { + "name": "Attach FW (blackmagic)", + "cwd": "${workspaceFolder}", + "executable": "@UFBT_FIRMWARE_ELF@", + "request": "attach", + "type": "cortex-debug", + "servertype": "external", + "gdbTarget": "${input:BLACKMAGIC}", + "svdFile": "@UFBT_DEBUG_DIR@/STM32WB55_CM4.svd", + "rtos": "FreeRTOS", + "postAttachCommands": [ + "monitor swdp_scan", + "attach 1", + "set confirm off", + "set mem inaccessible-by-default off", + "source @UFBT_DEBUG_DIR@/flipperapps.py", + "fap-set-debug-elf-root @UFBT_DEBUG_ELF_DIR@" + ] + // "showDevDebugOutput": "raw", + }, { "name": "Attach FW (JLink)", "cwd": "${workspaceFolder}", diff --git a/scripts/ufbt/project_template/.vscode/tasks.json b/scripts/ufbt/project_template/.vscode/tasks.json index 6343bba7b..4b3f4bda5 100644 --- a/scripts/ufbt/project_template/.vscode/tasks.json +++ b/scripts/ufbt/project_template/.vscode/tasks.json @@ -20,24 +20,30 @@ "type": "shell", "command": "ufbt" }, + { + "label": "Clean", + "group": "build", + "type": "shell", + "command": "ufbt -c" + }, { "label": "Flash FW (ST-Link)", "group": "build", "type": "shell", "command": "ufbt FORCE=1 flash" }, - // { - // "label": "[NOTIMPL] Flash FW (blackmagic)", - // "group": "build", - // "type": "shell", - // "command": "ufbt flash_blackmagic" - // }, - // { - // "label": "[NOTIMPL] Flash FW (JLink)", - // "group": "build", - // "type": "shell", - // "command": "ufbt FORCE=1 jflash" - // }, + { + "label": "Flash FW (blackmagic)", + "group": "build", + "type": "shell", + "command": "ufbt flash_blackmagic" + }, + { + "label": "Flash FW (JLink)", + "group": "build", + "type": "shell", + "command": "ufbt FORCE=1 jflash" + }, { "label": "Flash FW (USB, with resources)", "group": "build", @@ -49,6 +55,12 @@ "group": "build", "type": "shell", "command": "ufbt update" + }, + { + "label": "Update VSCode config for current SDK", + "group": "build", + "type": "shell", + "command": "ufbt vscode_dist" } ] } \ No newline at end of file diff --git a/scripts/ufbt/project_template/app_template/application.fam b/scripts/ufbt/project_template/app_template/application.fam index 31fadb207..37a4ce665 100644 --- a/scripts/ufbt/project_template/app_template/application.fam +++ b/scripts/ufbt/project_template/app_template/application.fam @@ -6,7 +6,7 @@ App( apptype=FlipperAppType.EXTERNAL, entry_point="@FBT_APPID@_app", stack_size=2 * 1024, - fap_category="Misc", + fap_category="Examples", # Optional values # fap_version=(0, 1), # (major, minor) fap_icon="@FBT_APPID@.png", # 10x10 1-bit PNG diff --git a/scripts/ufbt/site_tools/ufbt_state.py b/scripts/ufbt/site_tools/ufbt_state.py index 6ba8c6962..76c6e9acf 100644 --- a/scripts/ufbt/site_tools/ufbt_state.py +++ b/scripts/ufbt/site_tools/ufbt_state.py @@ -75,12 +75,6 @@ def generate(env, **kw): if not sdk_state["meta"]["hw_target"].endswith(sdk_data["hardware"]): raise StopError("SDK state file doesn't match hardware target") - if sdk_state["meta"]["version"] != ufbt_state["version"]: - warn( - WarningOnByDefault, - f"Version mismatch: SDK state vs uFBT: {sdk_state['meta']['version']} vs {ufbt_state['version']}", - ) - scripts_dir = sdk_current_sdk_dir_node.Dir(sdk_components["scripts.dir"]) env.SetDefault( # Paths diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 798b85ea1..89ee49242 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -1,5 +1,4 @@ from dataclasses import dataclass, field -from os.path import dirname from SCons.Node import NodeList from SCons.Warnings import warn, WarningOnByDefault @@ -131,6 +130,7 @@ Depends(sdk_source, appenv.ProcessSdkDepends(f"{amalgamated_api}.d")) appenv["SDK_DIR"] = appenv.Dir("${BUILD_DIR}/sdk_headers") sdk_header_tree = appenv.SDKHeaderTreeExtractor(appenv["SDK_DIR"], amalgamated_api) +Depends(sdk_header_tree, appenv["SDK_DEFINITION"]) # AlwaysBuild(sdk_tree) Alias("sdk_tree", sdk_header_tree) extapps.sdk_tree = sdk_header_tree From 8f752b7eee90320691cec6c5485dbe45776c803b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 10 Apr 2023 18:47:20 +0300 Subject: [PATCH 07/22] Revert changes due to Null pointer dereference --- applications/external/avr_isp_programmer/helpers/avr_isp.c | 1 - .../external/avr_isp_programmer/helpers/avr_isp_worker_rw.c | 5 ++--- .../external/avr_isp_programmer/lib/driver/avr_isp_prog.c | 1 - .../external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c | 2 ++ 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c index 51b4f8846..76e0a80b0 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp.c @@ -152,7 +152,6 @@ bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) { } } } - if(instance->spi) avr_isp_spi_sw_free(instance->spi); return false; } diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c index 209551a47..f586e1645 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c @@ -198,10 +198,9 @@ bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) { } avr_isp_end_pmode(instance->avr_isp); + furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + } while(0); - - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); - if(instance->callback) { if(instance->chip_arr_ind > avr_isp_chip_arr_size) { instance->callback(instance->context, "No detect", instance->chip_detect, 0); diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c index b3c81f3b1..b457e4c27 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c @@ -317,7 +317,6 @@ static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) { } } } - if(instance->spi) avr_isp_spi_sw_free(instance->spi); return false; } diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c index c6d9d54c8..f60850c84 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c @@ -18,6 +18,7 @@ struct AvrIspSpiSw { AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed) { AvrIspSpiSw* instance = malloc(sizeof(AvrIspSpiSw)); instance->speed_wait_time = speed; + instance->miso = AVR_ISP_SPI_SW_MISO; instance->mosi = AVR_ISP_SPI_SW_MOSI; instance->sck = AVR_ISP_SPI_SW_SCK; @@ -39,6 +40,7 @@ void avr_isp_spi_sw_free(AvrIspSpiSw* instance) { furi_hal_gpio_init(instance->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(instance->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(instance->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + free(instance); } From 7ac7b708840d29daf8f358f629119f61b859aaa0 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 10 Apr 2023 19:51:55 +0400 Subject: [PATCH 08/22] [FL-3241] NFC disable EMV support (#2571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * nfc: remove read emv from extra actions * nfc: remove read emv Co-authored-by: あく --- applications/main/nfc/scenes/nfc_scene_read.c | 5 -- .../nfc/scenes/nfc_scene_read_card_type.c | 12 --- lib/nfc/nfc_device.h | 1 - lib/nfc/nfc_worker.c | 80 ------------------- lib/nfc/nfc_worker.h | 1 - lib/nfc/nfc_worker_i.h | 1 - 6 files changed, 100 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_read.c b/applications/main/nfc/scenes/nfc_scene_read.c index 4252883b2..938f2da67 100644 --- a/applications/main/nfc/scenes/nfc_scene_read.c +++ b/applications/main/nfc/scenes/nfc_scene_read.c @@ -85,11 +85,6 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireReadSuccess); DOLPHIN_DEED(DolphinDeedNfcReadSuccess); consumed = true; - } else if(event.event == NfcWorkerEventReadBankCard) { - notification_message(nfc->notifications, &sequence_success); - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvReadSuccess); - DOLPHIN_DEED(DolphinDeedNfcReadSuccess); - consumed = true; } else if(event.event == NfcWorkerEventReadMfClassicDictAttackRequired) { if(mf_classic_dict_check_presence(MfClassicDictTypeSystem)) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDictAttack); diff --git a/applications/main/nfc/scenes/nfc_scene_read_card_type.c b/applications/main/nfc/scenes/nfc_scene_read_card_type.c index 94262aa1e..8023026c3 100644 --- a/applications/main/nfc/scenes/nfc_scene_read_card_type.c +++ b/applications/main/nfc/scenes/nfc_scene_read_card_type.c @@ -5,7 +5,6 @@ enum SubmenuIndex { SubmenuIndexReadMifareClassic, SubmenuIndexReadMifareDesfire, SubmenuIndexReadMfUltralight, - SubmenuIndexReadEMV, SubmenuIndexReadNFCA, }; @@ -37,12 +36,6 @@ void nfc_scene_read_card_type_on_enter(void* context) { SubmenuIndexReadMfUltralight, nfc_scene_read_card_type_submenu_callback, nfc); - submenu_add_item( - submenu, - "Read EMV card", - SubmenuIndexReadEMV, - nfc_scene_read_card_type_submenu_callback, - nfc); submenu_add_item( submenu, "Read NFC-A data", @@ -75,11 +68,6 @@ bool nfc_scene_read_card_type_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); consumed = true; } - if(event.event == SubmenuIndexReadEMV) { - nfc->dev->dev_data.read_mode = NfcReadModeEMV; - scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); - consumed = true; - } if(event.event == SubmenuIndexReadNFCA) { nfc->dev->dev_data.read_mode = NfcReadModeNFCA; scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); diff --git a/lib/nfc/nfc_device.h b/lib/nfc/nfc_device.h index 8b2e6e5ba..df37ec3df 100644 --- a/lib/nfc/nfc_device.h +++ b/lib/nfc/nfc_device.h @@ -56,7 +56,6 @@ typedef enum { NfcReadModeMfClassic, NfcReadModeMfUltralight, NfcReadModeMfDesfire, - NfcReadModeEMV, NfcReadModeNFCA, } NfcReadMode; diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index c2b89c71a..28a1f6827 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -229,69 +229,6 @@ static bool nfc_worker_read_mf_desfire(NfcWorker* nfc_worker, FuriHalNfcTxRxCont return read_success; } -static bool nfc_worker_read_bank_card(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { - bool read_success = false; - EmvApplication emv_app = {}; - EmvData* result = &nfc_worker->dev_data->emv_data; - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false); - reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog); - } - - // Bank cards require strong field to start application. If we find AID, try at least several - // times to start EMV application - uint8_t start_application_attempts = 0; - while(start_application_attempts < 3) { - if(nfc_worker->state != NfcWorkerStateRead) break; - start_application_attempts++; - if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; - if(emv_read_bank_card(tx_rx, &emv_app)) { - FURI_LOG_D(TAG, "Bank card number read from %d attempt", start_application_attempts); - break; - } else if(emv_app.aid_len && !emv_app.app_started) { - FURI_LOG_D( - TAG, - "AID found but failed to start EMV app from %d attempt", - start_application_attempts); - furi_hal_nfc_sleep(); - continue; - } else { - FURI_LOG_D(TAG, "Failed to find AID"); - break; - } - } - // Copy data - if(emv_app.aid_len) { - result->aid_len = emv_app.aid_len; - memcpy(result->aid, emv_app.aid, result->aid_len); - read_success = true; - } - if(emv_app.card_number_len) { - result->number_len = emv_app.card_number_len; - memcpy(result->number, emv_app.card_number, result->number_len); - } - if(emv_app.name_found) { - memcpy(result->name, emv_app.name, sizeof(emv_app.name)); - } - if(emv_app.exp_month) { - result->exp_mon = emv_app.exp_month; - result->exp_year = emv_app.exp_year; - } - if(emv_app.country_code) { - result->country_code = emv_app.country_code; - } - if(emv_app.currency_code) { - result->currency_code = emv_app.currency_code; - } - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - reader_analyzer_stop(nfc_worker->reader_analyzer); - } - - return read_success; -} - static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) { FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; @@ -315,14 +252,6 @@ static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; } card_read = true; - } else if(nfc_data->interface == FuriHalNfcInterfaceIsoDep) { - FURI_LOG_I(TAG, "ISO14443-4 card detected"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV; - if(!nfc_worker_read_bank_card(nfc_worker, tx_rx)) { - FURI_LOG_I(TAG, "Unknown card. Save UID"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; - } - card_read = true; } else { nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; card_read = true; @@ -358,9 +287,6 @@ void nfc_worker_read(NfcWorker* nfc_worker) { } else if(dev_data->protocol == NfcDeviceProtocolMifareDesfire) { event = NfcWorkerEventReadMfDesfire; break; - } else if(dev_data->protocol == NfcDeviceProtocolEMV) { - event = NfcWorkerEventReadBankCard; - break; } else if(dev_data->protocol == NfcDeviceProtocolUnknown) { event = NfcWorkerEventReadUidNfcA; break; @@ -444,12 +370,6 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) { event = NfcWorkerEventReadMfDesfire; break; } - } else if(read_mode == NfcReadModeEMV) { - nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV; - if(nfc_worker_read_bank_card(nfc_worker, &tx_rx)) { - event = NfcWorkerEventReadBankCard; - break; - } } else if(read_mode == NfcReadModeNFCA) { nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; event = NfcWorkerEventReadUidNfcA; diff --git a/lib/nfc/nfc_worker.h b/lib/nfc/nfc_worker.h index ce542828a..8e993fc6a 100644 --- a/lib/nfc/nfc_worker.h +++ b/lib/nfc/nfc_worker.h @@ -39,7 +39,6 @@ typedef enum { NfcWorkerEventReadMfClassicDone, NfcWorkerEventReadMfClassicLoadKeyCache, NfcWorkerEventReadMfClassicDictAttackRequired, - NfcWorkerEventReadBankCard, // Nfc worker common events NfcWorkerEventSuccess, diff --git a/lib/nfc/nfc_worker_i.h b/lib/nfc/nfc_worker_i.h index 9733426ab..701ecb90c 100644 --- a/lib/nfc/nfc_worker_i.h +++ b/lib/nfc/nfc_worker_i.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include From c2fa8a2b184e0cb86770c0b3092aa1833de3f37e Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 10 Apr 2023 18:47:20 +0300 Subject: [PATCH 09/22] Revert "Revert changes due to Null pointer dereference" This reverts commit 8f752b7eee90320691cec6c5485dbe45776c803b. --- applications/external/avr_isp_programmer/helpers/avr_isp.c | 1 + .../external/avr_isp_programmer/helpers/avr_isp_worker_rw.c | 5 +++-- .../external/avr_isp_programmer/lib/driver/avr_isp_prog.c | 1 + .../external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c | 2 -- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c index 76e0a80b0..51b4f8846 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp.c @@ -152,6 +152,7 @@ bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) { } } } + if(instance->spi) avr_isp_spi_sw_free(instance->spi); return false; } diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c index f586e1645..209551a47 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c @@ -198,9 +198,10 @@ bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) { } avr_isp_end_pmode(instance->avr_isp); - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); - } while(0); + + furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + if(instance->callback) { if(instance->chip_arr_ind > avr_isp_chip_arr_size) { instance->callback(instance->context, "No detect", instance->chip_detect, 0); diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c index b457e4c27..b3c81f3b1 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c @@ -317,6 +317,7 @@ static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) { } } } + if(instance->spi) avr_isp_spi_sw_free(instance->spi); return false; } diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c index f60850c84..c6d9d54c8 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_spi_sw.c @@ -18,7 +18,6 @@ struct AvrIspSpiSw { AvrIspSpiSw* avr_isp_spi_sw_init(AvrIspSpiSwSpeed speed) { AvrIspSpiSw* instance = malloc(sizeof(AvrIspSpiSw)); instance->speed_wait_time = speed; - instance->miso = AVR_ISP_SPI_SW_MISO; instance->mosi = AVR_ISP_SPI_SW_MOSI; instance->sck = AVR_ISP_SPI_SW_SCK; @@ -40,7 +39,6 @@ void avr_isp_spi_sw_free(AvrIspSpiSw* instance) { furi_hal_gpio_init(instance->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(instance->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); furi_hal_gpio_init(instance->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - free(instance); } From 243fbfc19a0ebfde591e439696d2283875635e37 Mon Sep 17 00:00:00 2001 From: SkorP Date: Mon, 10 Apr 2023 20:39:33 +0400 Subject: [PATCH 10/22] AVR_ISP: fix NULL pointer dereference --- applications/external/avr_isp_programmer/helpers/avr_isp.c | 1 + .../external/avr_isp_programmer/lib/driver/avr_isp_prog.c | 1 + 2 files changed, 2 insertions(+) diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c index 51b4f8846..ab7c6f496 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp.c @@ -153,6 +153,7 @@ bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) { } } if(instance->spi) avr_isp_spi_sw_free(instance->spi); + instance->spi = NULL; return false; } diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c index b3c81f3b1..ad6489cf0 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c @@ -318,6 +318,7 @@ static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) { } } if(instance->spi) avr_isp_spi_sw_free(instance->spi); + instance->spi = NULL; return false; } From 206eb7946bef5534af9c7d3f3a0f5120528ebc66 Mon Sep 17 00:00:00 2001 From: p0ns Date: Mon, 10 Apr 2023 20:37:57 -0300 Subject: [PATCH 11/22] Implements an array for baudrates --- applications/external/gps_nmea_uart/gps.c | 20 +++++++------------ .../external/gps_nmea_uart/gps_uart.c | 2 +- .../external/gps_nmea_uart/gps_uart.h | 6 +++--- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/applications/external/gps_nmea_uart/gps.c b/applications/external/gps_nmea_uart/gps.c index 0f4a7a1d5..a0c6ead03 100644 --- a/applications/external/gps_nmea_uart/gps.c +++ b/applications/external/gps_nmea_uart/gps.c @@ -139,20 +139,14 @@ int32_t gps_app(void* p) { switch(event.input.key) { case InputKeyUp: gps_uart_deinit_thread(gps_uart); - switch(gps_uart->baudrate) { - case GPS_BAUDRATE_9k: - gps_uart->baudrate = GPS_BAUDRATE_57k; - break; - case GPS_BAUDRATE_57k: - gps_uart->baudrate = GPS_BAUDRATE_115k; - break; - case GPS_BAUDRATE_115k: - gps_uart->baudrate = GPS_BAUDRATE_9k; - break; - - default: - break; + const int baudrate_length = + sizeof(gps_baudrates) / sizeof(gps_baudrates[0]); + current_gps_baudrate++; + if(current_gps_baudrate >= baudrate_length) { + current_gps_baudrate = 0; } + gps_uart->baudrate = gps_baudrates[current_gps_baudrate]; + gps_uart_init_thread(gps_uart); gps_uart->changing_baudrate = true; view_port_update(view_port); diff --git a/applications/external/gps_nmea_uart/gps_uart.c b/applications/external/gps_nmea_uart/gps_uart.c index 39538b74b..4e66aa284 100644 --- a/applications/external/gps_nmea_uart/gps_uart.c +++ b/applications/external/gps_nmea_uart/gps_uart.c @@ -169,7 +169,7 @@ GpsUart* gps_uart_enable() { gps_uart->notifications = furi_record_open(RECORD_NOTIFICATION); - gps_uart->baudrate = GPS_BAUDRATE_57k; + gps_uart->baudrate = gps_baudrates[current_gps_baudrate]; gps_uart_init_thread(gps_uart); diff --git a/applications/external/gps_nmea_uart/gps_uart.h b/applications/external/gps_nmea_uart/gps_uart.h index 5a42b9c58..152f4cd7f 100644 --- a/applications/external/gps_nmea_uart/gps_uart.h +++ b/applications/external/gps_nmea_uart/gps_uart.h @@ -3,11 +3,11 @@ #include #include -#define GPS_BAUDRATE_9k 9600 -#define GPS_BAUDRATE_57k 57600 -#define GPS_BAUDRATE_115k 115200 #define RX_BUF_SIZE 1024 +static const int gps_baudrates[5] = {9600, 19200, 38400, 57600, 115200}; +static int current_gps_baudrate = 3; + typedef struct { bool valid; float latitude; From 33e8bae78bc19821d662edd131a956580ac8bdb2 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 12 Apr 2023 10:07:05 +0400 Subject: [PATCH 12/22] Bugfix: ISP Programmer and SubGhz (#2574) * AVR_ISP: fix NULL pointer dereference * SubGhz: double back with a blocked transmission in this region * SubGhz: fix speaker, when a transmission is blocked in this region * SubGhz: fix speaker * SubGhz: return region * AVR Flasher: cleanup code Co-authored-by: Aleksandr Kutuzov --- applications/external/avr_isp_programmer/helpers/avr_isp.c | 7 ++++++- .../external/avr_isp_programmer/lib/driver/avr_isp_prog.c | 7 ++++++- applications/main/subghz/scenes/subghz_scene_read_raw.c | 6 +++++- applications/main/subghz/scenes/subghz_scene_transmitter.c | 4 +--- applications/main/subghz/subghz_i.c | 7 +++++-- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c index 51b4f8846..283c17bfd 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp.c @@ -152,7 +152,12 @@ bool avr_isp_auto_set_spi_speed_start_pmode(AvrIsp* instance) { } } } - if(instance->spi) avr_isp_spi_sw_free(instance->spi); + + if(instance->spi) { + avr_isp_spi_sw_free(instance->spi); + instance->spi = NULL; + } + return false; } diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c index b3c81f3b1..bbb6d4739 100644 --- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c +++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c @@ -317,7 +317,12 @@ static bool avr_isp_prog_auto_set_spi_speed_start_pmode(AvrIspProg* instance) { } } } - if(instance->spi) avr_isp_spi_sw_free(instance->spi); + + if(instance->spi) { + avr_isp_spi_sw_free(instance->spi); + instance->spi = NULL; + } + return false; } diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 96acc90ee..09440b32b 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -230,7 +230,11 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { subghz->txrx->rx_key_state = SubGhzRxKeyStateBack; - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); + subghz_read_raw_set_status( + subghz->subghz_read_raw, + SubGhzReadRAWStatusIDLE, + "", + subghz->txrx->raw_threshold_rssi); } else { if(scene_manager_has_previous_scene( subghz->scene_manager, SubGhzSceneSaved) || diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index c8663cc8e..712e50071 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -70,9 +70,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { } if((subghz->txrx->txrx_state == SubGhzTxRxStateIDLE) || (subghz->txrx->txrx_state == SubGhzTxRxStateSleep)) { - if(!subghz_tx_start(subghz, subghz->txrx->fff_data)) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowOnlyRx); - } else { + if(subghz_tx_start(subghz, subghz->txrx->fff_data)) { subghz->state_notifications = SubGhzNotificationStateTx; subghz_scene_transmitter_update_data_show(subghz); DOLPHIN_DEED(DolphinDeedSubGhzSend); diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 94713ddba..18d87c76b 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -105,9 +105,11 @@ static bool subghz_tx(SubGhz* subghz, uint32_t frequency) { furi_hal_subghz_set_frequency_and_path(frequency); furi_hal_gpio_write(&gpio_cc1101_g0, false); furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - subghz_speaker_on(subghz); bool ret = furi_hal_subghz_tx(); - subghz->txrx->txrx_state = SubGhzTxRxStateTx; + if(ret) { + subghz_speaker_on(subghz); + subghz->txrx->txrx_state = SubGhzTxRxStateTx; + } return ret; } @@ -115,6 +117,7 @@ void subghz_idle(SubGhz* subghz) { furi_assert(subghz); furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); + subghz_speaker_off(subghz); subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; } From 5d7bdca835e83c6925d7802774ac1ffe03766368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 12 Apr 2023 19:45:13 +0800 Subject: [PATCH 13/22] FuriHal: pwr pulls for some pins (#2579) --- firmware/targets/f18/furi_hal/furi_hal_resources.c | 5 +++-- firmware/targets/f7/furi_hal/furi_hal_resources.c | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 19bc9f998..4a7015d13 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -166,8 +166,9 @@ void furi_hal_resources_init() { furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); // Explicit pulls pins - furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + LL_PWR_EnablePUPDCfg(); + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index df9530079..912912b4a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -153,10 +153,11 @@ void furi_hal_resources_init() { // Button pins furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); - // Explicit pulls pins - furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow); - furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow); + // Explicit, surviving reset, pulls + LL_PWR_EnablePUPDCfg(); + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_9); // gpio_infrared_tx + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker + LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); From 39186004cc2e988388f84d13ed07a93500b284ae Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 12 Apr 2023 19:42:24 +0300 Subject: [PATCH 14/22] Update UART terminal https://github.com/cool4uma/UART_Terminal --- .../scenes/uart_terminal_scene_console_output.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c b/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c index 38a5a20e4..7882a900a 100644 --- a/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c +++ b/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c @@ -113,14 +113,10 @@ void uart_terminal_scene_console_output_on_enter(void* context) { // Send command with CR+LF or newline '\n' if(app->is_command && app->selected_tx_string) { - if(app->TERMINAL_MODE == 1) { - // char buffer[240]; - // snprintf(buffer, 240, "%s\r\n", (app->selected_tx_string)); - // uart_terminal_uart_tx((unsigned char *)buffer, strlen(buffer)); + if(app->TERMINAL_MODE == 1){ uart_terminal_uart_tx( (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); - uart_terminal_uart_tx((uint8_t*)("\r"), 1); - uart_terminal_uart_tx((uint8_t*)("\n"), 1); + uart_terminal_uart_tx((uint8_t*)("\r\n"), 2); } else { uart_terminal_uart_tx( (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); @@ -149,9 +145,4 @@ void uart_terminal_scene_console_output_on_exit(void* context) { // Unregister rx callback uart_terminal_uart_set_handle_rx_data_cb(app->uart, NULL); - - // Automatically logut when exiting view - //if(app->is_command) { - // uart_terminal_uart_tx((uint8_t*)("exit\n"), strlen("exit\n")); - //} } \ No newline at end of file From 37fb330b362dba3b01b7c6ca6a200564211dc1b7 Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Thu, 13 Apr 2023 17:47:38 +0300 Subject: [PATCH 15/22] [FL-3226] Deep Sleep Idle (#2569) * Improve RNG error handling * Sync RTC shadow registers on Stop mode exit * Implement working STOP2 mode * Fix formatting * FuriHal: disable SWD pins if debug is disabled * Power: cleanup battery info view, handle zero current report from gauge * Fbt: add command line argument for extra global defines * FuriHal: cleanup debug defines in power and os, drop deep_insomnia counter. * Add a setting to disable deep sleep * Clean up furi_hal_power * FuriHal,FapLoader,Debug: implement debug in stop mode, workaround resume in stop * FuriHal: document OS and power subsystems debugging * Furi: enable debug interface on crash --------- Co-authored-by: Aleksandr Kutuzov --- applications/main/fap_loader/fap_loader_app.c | 5 +- .../power_settings_app/views/battery_info.c | 51 +++++++------- .../settings/system/system_settings.c | 21 ++++++ debug/flipperapps.py | 3 +- documentation/FuriHalDebuging.md | 26 +++++++ documentation/fbt.md | 1 + firmware/targets/f18/api_symbols.csv | 13 ++-- .../targets/f18/furi_hal/furi_hal_resources.c | 3 + .../targets/f18/furi_hal/furi_hal_resources.h | 3 + firmware/targets/f7/api_symbols.csv | 13 ++-- firmware/targets/f7/ble_glue/ble_glue.c | 6 -- firmware/targets/f7/furi_hal/furi_hal_clock.c | 9 ++- firmware/targets/f7/furi_hal/furi_hal_debug.c | 21 ++++++ firmware/targets/f7/furi_hal/furi_hal_os.c | 30 ++++++-- firmware/targets/f7/furi_hal/furi_hal_power.c | 69 +++++++++---------- .../targets/f7/furi_hal/furi_hal_random.c | 42 ++++++----- .../targets/f7/furi_hal/furi_hal_resources.c | 3 + .../targets/f7/furi_hal/furi_hal_resources.h | 3 + firmware/targets/f7/furi_hal/furi_hal_rtc.c | 15 ++-- .../targets/furi_hal_include/furi_hal_debug.h | 3 + .../targets/furi_hal_include/furi_hal_power.h | 6 -- .../targets/furi_hal_include/furi_hal_rtc.h | 4 ++ furi/core/check.c | 3 + furi/core/core_defines.h | 4 ++ site_scons/cc.scons | 1 + site_scons/commandline.scons | 8 +++ 26 files changed, 246 insertions(+), 120 deletions(-) create mode 100644 documentation/FuriHalDebuging.md diff --git a/applications/main/fap_loader/fap_loader_app.c b/applications/main/fap_loader/fap_loader_app.c index f5c7af024..7af5244ae 100644 --- a/applications/main/fap_loader/fap_loader_app.c +++ b/applications/main/fap_loader/fap_loader_app.c @@ -1,6 +1,7 @@ #include "fap_loader_app.h" #include +#include #include #include @@ -23,8 +24,6 @@ struct FapLoader { Loading* loading; }; -volatile bool fap_loader_debug_active = false; - bool fap_loader_load_name_and_icon( FuriString* path, Storage* storage, @@ -111,7 +110,7 @@ static bool fap_loader_run_selected_app(FapLoader* loader) { FuriThread* thread = flipper_application_spawn(loader->app, NULL); /* This flag is set by the debugger - to break on app start */ - if(fap_loader_debug_active) { + if(furi_hal_debug_is_gdb_session_active()) { FURI_LOG_W(TAG, "Triggering BP for debugger"); /* After hitting this, you can set breakpoints in your .fap's code * Note that you have to toggle breakpoints that were set before */ diff --git a/applications/settings/power_settings_app/views/battery_info.c b/applications/settings/power_settings_app/views/battery_info.c index 7394fd3c5..0956cae4f 100644 --- a/applications/settings/power_settings_app/views/battery_info.c +++ b/applications/settings/power_settings_app/views/battery_info.c @@ -4,8 +4,8 @@ #include #include -#define LOW_CHARGE_THRESHOLD 10 -#define HIGH_DRAIN_CURRENT_THRESHOLD 100 +#define LOW_CHARGE_THRESHOLD (10) +#define HIGH_DRAIN_CURRENT_THRESHOLD (-100) struct BatteryInfo { View* view; @@ -25,14 +25,13 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { char header[20] = {}; char value[20] = {}; - int32_t drain_current = data->gauge_current * (-1000); - uint32_t charge_current = data->gauge_current * 1000; + int32_t current = 1000.0f * data->gauge_current; // Draw battery canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28); - if(charge_current > 0) { + if(current > 0) { canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14); - } else if(drain_current > HIGH_DRAIN_CURRENT_THRESHOLD) { + } else if(current < HIGH_DRAIN_CURRENT_THRESHOLD) { canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14); } else if(data->charge < LOW_CHARGE_THRESHOLD) { canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14); @@ -44,7 +43,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { elements_bubble(canvas, 53, 0, 71, 39); // Set text - if(charge_current > 0) { + if(current > 0) { snprintf(emote, sizeof(emote), "%s", "Yummy!"); snprintf(header, sizeof(header), "%s", "Charging at"); snprintf( @@ -53,34 +52,36 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { "%lu.%luV %lumA", (uint32_t)(data->vbus_voltage), (uint32_t)(data->vbus_voltage * 10) % 10, - charge_current); - } else if(drain_current > 0) { + current); + } else if(current < 0) { snprintf( emote, sizeof(emote), "%s", - drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!"); + current < HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!"); snprintf(header, sizeof(header), "%s", "Consumption is"); snprintf( value, sizeof(value), "%ld %s", - drain_current, - drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); - } else if(drain_current != 0) { - snprintf(header, 20, "..."); - } else if(data->charge_voltage_limit < 4.2) { - // Non-default battery charging limit, mention it - snprintf(emote, sizeof(emote), "Charged!"); - snprintf(header, sizeof(header), "Limited to"); - snprintf( - value, - sizeof(value), - "%lu.%luV", - (uint32_t)(data->charge_voltage_limit), - (uint32_t)(data->charge_voltage_limit * 10) % 10); + ABS(current), + current < HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); + } else if(data->vbus_voltage > 0) { + if(data->charge_voltage_limit < 4.2) { + // Non-default battery charging limit, mention it + snprintf(emote, sizeof(emote), "Charged!"); + snprintf(header, sizeof(header), "Limited to"); + snprintf( + value, + sizeof(value), + "%lu.%luV", + (uint32_t)(data->charge_voltage_limit), + (uint32_t)(data->charge_voltage_limit * 10) % 10); + } else { + snprintf(header, sizeof(header), "Charged!"); + } } else { - snprintf(header, sizeof(header), "Charged!"); + snprintf(header, sizeof(header), "Napping..."); } canvas_draw_str_aligned(canvas, 92, y + 3, AlignCenter, AlignCenter, emote); diff --git a/applications/settings/system/system_settings.c b/applications/settings/system/system_settings.c index cb74d7a83..597710a53 100644 --- a/applications/settings/system/system_settings.c +++ b/applications/settings/system/system_settings.c @@ -141,6 +141,21 @@ static void hand_orient_changed(VariableItem* item) { loader_update_menu(); } +const char* const sleep_method[] = { + "Default", + "Legacy", +}; + +static void sleep_method_changed(VariableItem* item) { + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, sleep_method[index]); + if(index) { + furi_hal_rtc_set_flag(FuriHalRtcFlagLegacySleep); + } else { + furi_hal_rtc_reset_flag(FuriHalRtcFlagLegacySleep); + } +} + static uint32_t system_settings_exit(void* context) { UNUSED(context); return VIEW_NONE; @@ -218,6 +233,12 @@ SystemSettings* system_settings_alloc() { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, heap_trace_mode_text[value_index]); + item = variable_item_list_add( + app->var_item_list, "Sleep Method", COUNT_OF(sleep_method), sleep_method_changed, app); + value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) ? 1 : 0; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, sleep_method[value_index]); + view_set_previous_callback( variable_item_list_get_view(app->var_item_list), system_settings_exit); view_dispatcher_add_view( diff --git a/debug/flipperapps.py b/debug/flipperapps.py index 1dc5ebd04..90582c1e4 100644 --- a/debug/flipperapps.py +++ b/debug/flipperapps.py @@ -135,6 +135,7 @@ class FlipperAppStateHelper: self.app_list_ptr = None self.app_list_entry_type = None self._current_apps: list[AppState] = [] + self.set_debug_mode(True) def _walk_app_list(self, list_head): while list_head: @@ -195,7 +196,7 @@ class FlipperAppStateHelper: self.set_debug_mode(False) def set_debug_mode(self, mode: bool) -> None: - gdb.execute(f"set variable fap_loader_debug_active = {int(mode)}") + gdb.execute(f"set variable furi_hal_debug_gdb_session_active = {int(mode)}") # Init additional 'fap-set-debug-elf-root' command and set up hooks diff --git a/documentation/FuriHalDebuging.md b/documentation/FuriHalDebuging.md new file mode 100644 index 000000000..8ff770163 --- /dev/null +++ b/documentation/FuriHalDebuging.md @@ -0,0 +1,26 @@ +# Furi HAL Debugging + +Some Furi subsystem got additional debugging features that can be enabled by adding additional defines to firmware compilation. +Usually they are used for low level tracing and profiling or signal redirection/duplication. + + +## FuriHalOs + +`--extra-define=FURI_HAL_OS_DEBUG` enables tick, tick suppression, idle and time flow. + +There are 3 signals that will be exposed to external GPIO pins: + +- `AWAKE` - `PA7` - High when system is busy with computations, low when sleeping. Can be used to track transitions to sleep mode. +- `TICK` - `PA6` - Flipped on system tick, only flips when no tick suppression in progress. Can be used to track tick skew and abnormal task scheduling. +- `SECOND` - `PA4` - Flipped each second. Can be used for tracing RT issue: time flow disturbance means system doesn't conforms Hard RT. + + + +## FuriHalPower + +`--extra-define=FURI_HAL_POWER_DEBUG` enables power subsystem mode transitions tracing. + +There are 2 signals that will be exposed to external GPIO pins: + +- `WFI` - `PB2` - Light sleep (wait for interrupt) used. Basically this is lightest and most non-breaking things power save mode. All function and debug should work correctly in this mode. +- `STOP` - `PC3` - STOP mode used. Platform deep sleep mode. Extremely fragile mode where most of the silicon is disabled or in unusable state. Debugging MCU in this mode is nearly impossible. \ No newline at end of file diff --git a/documentation/fbt.md b/documentation/fbt.md index 14d63e9ce..23b2e2b55 100644 --- a/documentation/fbt.md +++ b/documentation/fbt.md @@ -105,6 +105,7 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio - `--options optionfile.py` (default value `fbt_options.py`) - load a file with multiple configuration values - `--extra-int-apps=app1,app2,appN` - force listed apps to be built as internal with the `firmware` target - `--extra-ext-apps=app1,app2,appN` - force listed apps to be built as external with the `firmware_extapps` target +- `--extra-define=A --extra-define=B=C ` - extra global defines that will be passed to the C/C++ compiler, can be specified multiple times - `--proxy-env=VAR1,VAR2` - additional environment variables to expose to subprocesses spawned by `fbt`. By default, `fbt` sanitizes the execution environment and doesn't forward all inherited environment variables. You can find the list of variables that are always forwarded in the `environ.scons` file. ## Configuration diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 5d5b7bbcf..493f59634 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,+,21.0,, +Version,+,22.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -901,6 +901,7 @@ Function,+,furi_hal_crypto_verify_enclave,_Bool,"uint8_t*, uint8_t*" Function,+,furi_hal_crypto_verify_key,_Bool,uint8_t Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_enable,void, +Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,-,furi_hal_deinit_early,void, Function,-,furi_hal_flash_erase,void,uint8_t Function,-,furi_hal_flash_get_base,size_t, @@ -983,7 +984,6 @@ Function,-,furi_hal_os_init,void, Function,+,furi_hal_os_tick,void, Function,+,furi_hal_power_check_otg_status,void, Function,+,furi_hal_power_debug_get,void,"PropertyValueCallback, void*" -Function,+,furi_hal_power_deep_sleep_available,_Bool, Function,+,furi_hal_power_disable_external_3_3v,void, Function,+,furi_hal_power_disable_otg,void, Function,+,furi_hal_power_enable_external_3_3v,void, @@ -1059,6 +1059,7 @@ Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits Function,+,furi_hal_rtc_set_log_level,void,uint8_t Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t" +Function,+,furi_hal_rtc_sync_shadow,void, Function,+,furi_hal_rtc_validate_datetime,_Bool,FuriHalRtcDateTime* Function,+,furi_hal_speaker_acquire,_Bool,uint32_t Function,-,furi_hal_speaker_deinit,void, @@ -2149,6 +2150,8 @@ Variable,+,gpio_ext_pd0,const GpioPin, Variable,+,gpio_ext_pe4,const GpioPin, Variable,+,gpio_i2c_power_scl,const GpioPin, Variable,+,gpio_i2c_power_sda,const GpioPin, +Variable,+,gpio_ibutton,const GpioPin, +Variable,+,gpio_periph_power,const GpioPin, Variable,+,gpio_pins,const GpioPinRecord[], Variable,+,gpio_pins_count,const size_t, Variable,+,gpio_sdcard_cd,const GpioPin, @@ -2157,11 +2160,13 @@ Variable,+,gpio_speaker,const GpioPin, Variable,+,gpio_spi_d_miso,const GpioPin, Variable,+,gpio_spi_d_mosi,const GpioPin, Variable,+,gpio_spi_d_sck,const GpioPin, +Variable,+,gpio_swclk,const GpioPin, +Variable,+,gpio_swdio,const GpioPin, Variable,+,gpio_usart_rx,const GpioPin, Variable,+,gpio_usart_tx,const GpioPin, Variable,+,gpio_usb_dm,const GpioPin, Variable,+,gpio_usb_dp,const GpioPin, -Variable,+,gpio_ibutton,const GpioPin, +Variable,+,gpio_vibro,const GpioPin, Variable,+,input_pins,const InputPin[], Variable,+,input_pins_count,const size_t, Variable,+,message_blink_set_color_blue,const NotificationMessage, @@ -2309,7 +2314,6 @@ Variable,+,message_red_255,const NotificationMessage, Variable,+,message_sound_off,const NotificationMessage, Variable,+,message_vibro_off,const NotificationMessage, Variable,+,message_vibro_on,const NotificationMessage, -Variable,+,gpio_periph_power,const GpioPin, Variable,+,sequence_audiovisual_alert,const NotificationSequence, Variable,+,sequence_blink_blue_10,const NotificationSequence, Variable,+,sequence_blink_blue_100,const NotificationSequence, @@ -2364,4 +2368,3 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface, Variable,+,usb_hid,FuriHalUsbInterface, Variable,+,usb_hid_u2f,FuriHalUsbInterface, Variable,+,usbd_devfs,const usbd_driver, -Variable,+,gpio_vibro,const GpioPin, diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 4a7015d13..6db483dbc 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -6,6 +6,9 @@ #define TAG "FuriHalResources" +const GpioPin gpio_swdio = {.port = GPIOA, .pin = LL_GPIO_PIN_13}; +const GpioPin gpio_swclk = {.port = GPIOA, .pin = LL_GPIO_PIN_14}; + const GpioPin gpio_vibro = {.port = GPIOA, .pin = LL_GPIO_PIN_8}; const GpioPin gpio_ibutton = {.port = GPIOB, .pin = LL_GPIO_PIN_14}; diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.h b/firmware/targets/f18/furi_hal/furi_hal_resources.h index 3c4708d15..7d2caab36 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.h @@ -50,6 +50,9 @@ extern const size_t input_pins_count; extern const GpioPinRecord gpio_pins[]; extern const size_t gpio_pins_count; +extern const GpioPin gpio_swdio; +extern const GpioPin gpio_swclk; + extern const GpioPin gpio_vibro; extern const GpioPin gpio_ibutton; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 89984352a..3ef57813b 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,+,21.0,, +Version,+,22.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1082,6 +1082,7 @@ Function,+,furi_hal_crypto_verify_enclave,_Bool,"uint8_t*, uint8_t*" Function,+,furi_hal_crypto_verify_key,_Bool,uint8_t Function,+,furi_hal_debug_disable,void, Function,+,furi_hal_debug_enable,void, +Function,+,furi_hal_debug_is_gdb_session_active,_Bool, Function,-,furi_hal_deinit_early,void, Function,-,furi_hal_flash_erase,void,uint8_t Function,-,furi_hal_flash_get_base,size_t, @@ -1212,7 +1213,6 @@ Function,-,furi_hal_os_init,void, Function,+,furi_hal_os_tick,void, Function,+,furi_hal_power_check_otg_status,void, Function,+,furi_hal_power_debug_get,void,"PropertyValueCallback, void*" -Function,+,furi_hal_power_deep_sleep_available,_Bool, Function,+,furi_hal_power_disable_external_3_3v,void, Function,+,furi_hal_power_disable_otg,void, Function,+,furi_hal_power_enable_external_3_3v,void, @@ -1313,6 +1313,7 @@ Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits Function,+,furi_hal_rtc_set_log_level,void,uint8_t Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t" +Function,+,furi_hal_rtc_sync_shadow,void, Function,+,furi_hal_rtc_validate_datetime,_Bool,FuriHalRtcDateTime* Function,+,furi_hal_speaker_acquire,_Bool,uint32_t Function,-,furi_hal_speaker_deinit,void, @@ -3076,10 +3077,12 @@ Variable,+,gpio_ext_pc1,const GpioPin, Variable,+,gpio_ext_pc3,const GpioPin, Variable,+,gpio_i2c_power_scl,const GpioPin, Variable,+,gpio_i2c_power_sda,const GpioPin, +Variable,+,gpio_ibutton,const GpioPin, Variable,+,gpio_infrared_rx,const GpioPin, Variable,+,gpio_infrared_tx,const GpioPin, Variable,+,gpio_nfc_cs,const GpioPin, Variable,+,gpio_nfc_irq_rfid_pull,const GpioPin, +Variable,+,gpio_periph_power,const GpioPin, Variable,+,gpio_pins,const GpioPinRecord[], Variable,+,gpio_pins_count,const size_t, Variable,+,gpio_rf_sw_0,const GpioPin, @@ -3096,11 +3099,13 @@ Variable,+,gpio_spi_r_miso,const GpioPin, Variable,+,gpio_spi_r_mosi,const GpioPin, Variable,+,gpio_spi_r_sck,const GpioPin, Variable,+,gpio_subghz_cs,const GpioPin, +Variable,+,gpio_swclk,const GpioPin, +Variable,+,gpio_swdio,const GpioPin, Variable,+,gpio_usart_rx,const GpioPin, Variable,+,gpio_usart_tx,const GpioPin, Variable,+,gpio_usb_dm,const GpioPin, Variable,+,gpio_usb_dp,const GpioPin, -Variable,+,gpio_ibutton,const GpioPin, +Variable,+,gpio_vibro,const GpioPin, Variable,+,input_pins,const InputPin[], Variable,+,input_pins_count,const size_t, Variable,+,lfrfid_protocols,const ProtocolBase*[], @@ -3249,7 +3254,6 @@ Variable,+,message_red_255,const NotificationMessage, Variable,+,message_sound_off,const NotificationMessage, Variable,+,message_vibro_off,const NotificationMessage, Variable,+,message_vibro_on,const NotificationMessage, -Variable,+,gpio_periph_power,const GpioPin, Variable,+,sequence_audiovisual_alert,const NotificationSequence, Variable,+,sequence_blink_blue_10,const NotificationSequence, Variable,+,sequence_blink_blue_100,const NotificationSequence, @@ -3307,4 +3311,3 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface, Variable,+,usb_hid,FuriHalUsbInterface, Variable,+,usb_hid_u2f,FuriHalUsbInterface, Variable,+,usbd_devfs,const usbd_driver, -Variable,+,gpio_vibro,const GpioPin, diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 83562c73e..a2f2f1a94 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -58,12 +58,6 @@ void ble_glue_init() { ble_glue = malloc(sizeof(BleGlue)); ble_glue->status = BleGlueStatusStartup; - // Configure the system Power Mode - // Select HSI as system clock source after Wake Up from Stop mode - LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); - /* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */ - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); - #ifdef BLE_GLUE_DEBUG APPD_Init(); #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index cf19451ec..d85524ce4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -63,6 +63,10 @@ void furi_hal_clock_init() { LL_RCC_HSI_Enable(); while(!HS_CLOCK_IS_READY()) ; + /* Select HSI as system clock source after Wake Up from Stop mode + * Must be set before enabling CSS */ + LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); + LL_RCC_HSE_EnableCSS(); /* LSE and LSI1 configuration and activation */ @@ -215,11 +219,14 @@ void furi_hal_clock_switch_to_hsi() { void furi_hal_clock_switch_to_pll() { LL_RCC_HSE_Enable(); LL_RCC_PLL_Enable(); + LL_RCC_PLLSAI1_Enable(); while(!LL_RCC_HSE_IsReady()) ; while(!LL_RCC_PLL_IsReady()) ; + while(!LL_RCC_PLLSAI1_IsReady()) + ; LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); @@ -296,4 +303,4 @@ void furi_hal_clock_mco_disable() { LL_RCC_MSI_Disable(); while(LL_RCC_MSI_IsReady() != 0) ; -} \ No newline at end of file +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_debug.c b/firmware/targets/f7/furi_hal/furi_hal_debug.c index 3b5dfe622..3dc03ea69 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_debug.c +++ b/firmware/targets/f7/furi_hal/furi_hal_debug.c @@ -3,12 +3,26 @@ #include #include +#include +#include + +volatile bool furi_hal_debug_gdb_session_active = false; + void furi_hal_debug_enable() { // Low power mode debug LL_DBGMCU_EnableDBGSleepMode(); LL_DBGMCU_EnableDBGStopMode(); LL_DBGMCU_EnableDBGStandbyMode(); LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + // SWD GPIO + furi_hal_gpio_init_ex( + &gpio_swdio, + GpioModeAltFunctionPushPull, + GpioPullUp, + GpioSpeedVeryHigh, + GpioAltFn0JTMS_SWDIO); + furi_hal_gpio_init_ex( + &gpio_swclk, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn0JTCK_SWCLK); } void furi_hal_debug_disable() { @@ -17,4 +31,11 @@ void furi_hal_debug_disable() { LL_DBGMCU_DisableDBGStopMode(); LL_DBGMCU_DisableDBGStandbyMode(); LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48); + // SWD GPIO + furi_hal_gpio_init_simple(&gpio_swdio, GpioModeAnalog); + furi_hal_gpio_init_simple(&gpio_swclk, GpioModeAnalog); } + +bool furi_hal_debug_is_gdb_session_active() { + return furi_hal_debug_gdb_session_active; +} \ No newline at end of file diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index ee9743e62..3fc1fbea8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -28,11 +28,24 @@ // Arbitrary (but small) number for better tick consistency #define FURI_HAL_OS_EXTRA_CNT 3 +#ifndef FURI_HAL_OS_DEBUG_AWAKE_GPIO +#define FURI_HAL_OS_DEBUG_AWAKE_GPIO (&gpio_ext_pa7) +#endif + +#ifndef FURI_HAL_OS_DEBUG_TICK_GPIO +#define FURI_HAL_OS_DEBUG_TICK_GPIO (&gpio_ext_pa6) +#endif + +#ifndef FURI_HAL_OS_DEBUG_SECOND_GPIO +#define FURI_HAL_OS_DEBUG_SECOND_GPIO (&gpio_ext_pa4) +#endif + #ifdef FURI_HAL_OS_DEBUG #include void furi_hal_os_timer_callback() { - furi_hal_gpio_write(&gpio_ext_pa4, !furi_hal_gpio_read(&gpio_ext_pa4)); + furi_hal_gpio_write( + FURI_HAL_OS_DEBUG_SECOND_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_SECOND_GPIO)); } #endif @@ -44,9 +57,11 @@ void furi_hal_os_init() { furi_hal_idle_timer_init(); #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_ext_pa6, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_AWAKE_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_TICK_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_SECOND_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1); + FuriTimer* second_timer = furi_timer_alloc(furi_hal_os_timer_callback, FuriTimerTypePeriodic, NULL); furi_timer_start(second_timer, FURI_HAL_OS_TICK_HZ); @@ -58,7 +73,8 @@ void furi_hal_os_init() { void furi_hal_os_tick() { if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pa6, !furi_hal_gpio_read(&gpio_ext_pa6)); + furi_hal_gpio_write( + FURI_HAL_OS_DEBUG_TICK_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_TICK_GPIO)); #endif xPortSysTickHandler(); } @@ -121,14 +137,14 @@ static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { furi_hal_idle_timer_start(FURI_HAL_OS_TICKS_TO_IDLE_CNT(expected_idle_ticks)); #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pa7, 0); + furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 0); #endif // Go to sleep mode furi_hal_power_sleep(); #ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pa7, 1); + furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1); #endif // Calculate how much time we spent in the sleep diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index fd601ec7e..9a87cef15 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -19,15 +21,16 @@ #define TAG "FuriHalPower" -#ifdef FURI_HAL_POWER_DEEP_SLEEP_ENABLED -#define FURI_HAL_POWER_DEEP_INSOMNIA 0 -#else -#define FURI_HAL_POWER_DEEP_INSOMNIA 1 +#ifndef FURI_HAL_POWER_DEBUG_WFI_GPIO +#define FURI_HAL_POWER_DEBUG_WFI_GPIO (&gpio_ext_pb2) +#endif + +#ifndef FURI_HAL_POWER_DEBUG_STOP_GPIO +#define FURI_HAL_POWER_DEBUG_STOP_GPIO (&gpio_ext_pc3) #endif typedef struct { volatile uint8_t insomnia; - volatile uint8_t deep_insomnia; volatile uint8_t suppress_charge; uint8_t gauge_initialized; @@ -36,7 +39,6 @@ typedef struct { static volatile FuriHalPower furi_hal_power = { .insomnia = 0, - .deep_insomnia = FURI_HAL_POWER_DEEP_INSOMNIA, .suppress_charge = 0, }; @@ -79,19 +81,23 @@ const ParamCEDV cedv = { }; void furi_hal_power_init() { +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_WFI_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_STOP_GPIO, GpioModeOutputPushPull); + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); +#endif + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); bq27220_init(&furi_hal_i2c_handle_power, &cedv); bq25896_init(&furi_hal_i2c_handle_power); furi_hal_i2c_release(&furi_hal_i2c_handle_power); -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_init_simple(&gpio_ext_pb2, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); -#endif - FURI_LOG_I(TAG, "Init OK"); } @@ -140,11 +146,12 @@ bool furi_hal_power_sleep_available() { return furi_hal_power.insomnia == 0; } -bool furi_hal_power_deep_sleep_available() { - return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; +static inline bool furi_hal_power_deep_sleep_available() { + return furi_hal_bt_is_alive() && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) && + !furi_hal_debug_is_gdb_session_active(); } -void furi_hal_power_light_sleep() { +static inline void furi_hal_power_light_sleep() { __WFI(); } @@ -152,17 +159,15 @@ static inline void furi_hal_power_suspend_aux_periphs() { // Disable USART furi_hal_uart_suspend(FuriHalUartIdUSART1); furi_hal_uart_suspend(FuriHalUartIdLPUART1); - // TODO: Disable USB } static inline void furi_hal_power_resume_aux_periphs() { // Re-enable USART furi_hal_uart_resume(FuriHalUartIdUSART1); furi_hal_uart_resume(FuriHalUartIdLPUART1); - // TODO: Re-enable USB } -void furi_hal_power_deep_sleep() { +static inline void furi_hal_power_deep_sleep() { furi_hal_power_suspend_aux_periphs(); while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) @@ -187,8 +192,6 @@ void furi_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); // Prepare deep sleep - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); LL_LPM_EnableDeepSleep(); #if defined(__CC_ARM) @@ -200,13 +203,6 @@ void furi_hal_power_deep_sleep() { LL_LPM_EnableSleep(); - // Make sure that values differ to prevent disaster on wfi - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); - - LL_PWR_ClearFlag_C1STOP_C1STB(); - LL_PWR_ClearFlag_C2STOP_C2STB(); - /* Release ENTRY_STOP_MODE semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); @@ -220,28 +216,25 @@ void furi_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); furi_hal_power_resume_aux_periphs(); + furi_hal_rtc_sync_shadow(); } void furi_hal_power_sleep() { if(furi_hal_power_deep_sleep_available()) { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pc3, 1); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 1); #endif - furi_hal_power_deep_sleep(); - -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pc3, 0); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0); #endif } else { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pb2, 1); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 1); #endif - furi_hal_power_light_sleep(); - -#ifdef FURI_HAL_OS_DEBUG - furi_hal_gpio_write(&gpio_ext_pb2, 0); +#ifdef FURI_HAL_POWER_DEBUG + furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0); #endif } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_random.c b/firmware/targets/f7/furi_hal/furi_hal_random.c index f36407cc1..d3461c4d1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_random.c +++ b/firmware/targets/f7/furi_hal/furi_hal_random.c @@ -9,19 +9,35 @@ #define TAG "FuriHalRandom" +static uint32_t furi_hal_random_read_rng() { + while(LL_RNG_IsActiveFlag_CECS(RNG) && LL_RNG_IsActiveFlag_SECS(RNG) && + !LL_RNG_IsActiveFlag_DRDY(RNG)) { + /* Error handling as described in RM0434, pg. 582-583 */ + if(LL_RNG_IsActiveFlag_CECS(RNG)) { + /* Clock error occurred */ + LL_RNG_ClearFlag_CEIS(RNG); + } + + if(LL_RNG_IsActiveFlag_SECS(RNG)) { + /* Noise source error occurred */ + LL_RNG_ClearFlag_SEIS(RNG); + + for(uint32_t i = 0; i < 12; ++i) { + const volatile uint32_t discard = LL_RNG_ReadRandData32(RNG); + UNUSED(discard); + } + } + } + + return LL_RNG_ReadRandData32(RNG); +} + uint32_t furi_hal_random_get() { while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID)) ; LL_RNG_Enable(RNG); - while(!LL_RNG_IsActiveFlag_DRDY(RNG)) - ; - - if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) { - furi_crash("TRNG error"); - } - - uint32_t random_val = LL_RNG_ReadRandData32(RNG); + const uint32_t random_val = furi_hal_random_read_rng(); LL_RNG_Disable(RNG); LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0); @@ -35,15 +51,7 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) { LL_RNG_Enable(RNG); for(uint32_t i = 0; i < len; i += 4) { - while(!LL_RNG_IsActiveFlag_DRDY(RNG)) - ; - - if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) { - furi_crash("TRNG error"); - } - - uint32_t random_val = LL_RNG_ReadRandData32(RNG); - + const uint32_t random_val = furi_hal_random_read_rng(); uint8_t len_cur = ((i + 4) < len) ? (4) : (len - i); memcpy(&buf[i], &random_val, len_cur); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 912912b4a..abfd977e5 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -6,6 +6,9 @@ #define TAG "FuriHalResources" +const GpioPin gpio_swdio = {.port = GPIOA, .pin = LL_GPIO_PIN_13}; +const GpioPin gpio_swclk = {.port = GPIOA, .pin = LL_GPIO_PIN_14}; + const GpioPin gpio_vibro = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; const GpioPin gpio_ibutton = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index f29917300..6e585c518 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -50,6 +50,9 @@ extern const size_t input_pins_count; extern const GpioPinRecord gpio_pins[]; extern const size_t gpio_pins_count; +extern const GpioPin gpio_swdio; +extern const GpioPin gpio_swclk; + extern const GpioPin gpio_vibro; extern const GpioPin gpio_ibutton; diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 84e7fe395..7bd45c35d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -165,6 +165,14 @@ void furi_hal_rtc_init() { FURI_LOG_I(TAG, "Init OK"); } +void furi_hal_rtc_sync_shadow() { + if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) { + LL_RTC_ClearFlag_RS(RTC); + while(!LL_RTC_IsActiveFlag_RS(RTC)) { + }; + } +} + uint32_t furi_hal_rtc_get_register(FuriHalRtcRegister reg) { return LL_RTC_BAK_GetRegister(RTC, reg); } @@ -312,12 +320,7 @@ void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) { /* Exit Initialization mode */ LL_RTC_DisableInitMode(RTC); - /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ - if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) { - LL_RTC_ClearFlag_RS(RTC); - while(!LL_RTC_IsActiveFlag_RS(RTC)) { - }; - } + furi_hal_rtc_sync_shadow(); /* Enable write protection */ LL_RTC_EnableWriteProtection(RTC); diff --git a/firmware/targets/furi_hal_include/furi_hal_debug.h b/firmware/targets/furi_hal_include/furi_hal_debug.h index 88397bbba..befbb4f40 100644 --- a/firmware/targets/furi_hal_include/furi_hal_debug.h +++ b/firmware/targets/furi_hal_include/furi_hal_debug.h @@ -18,6 +18,9 @@ void furi_hal_debug_enable(); /** Disable MCU debug */ void furi_hal_debug_disable(); +/** Check if GDB debug session is active */ +bool furi_hal_debug_is_gdb_session_active(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/furi_hal_include/furi_hal_power.h b/firmware/targets/furi_hal_include/furi_hal_power.h index 462e20e41..00182fa28 100644 --- a/firmware/targets/furi_hal_include/furi_hal_power.h +++ b/firmware/targets/furi_hal_include/furi_hal_power.h @@ -58,12 +58,6 @@ void furi_hal_power_insomnia_exit(); */ bool furi_hal_power_sleep_available(); -/** Check if deep sleep availble - * - * @return true if available - */ -bool furi_hal_power_deep_sleep_available(); - /** Go to sleep */ void furi_hal_power_sleep(); diff --git a/firmware/targets/furi_hal_include/furi_hal_rtc.h b/firmware/targets/furi_hal_include/furi_hal_rtc.h index b16b04a68..0d9f46f01 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rtc.h +++ b/firmware/targets/furi_hal_include/furi_hal_rtc.h @@ -30,6 +30,7 @@ typedef enum { FuriHalRtcFlagLock = (1 << 2), FuriHalRtcFlagC2Update = (1 << 3), FuriHalRtcFlagHandOrient = (1 << 4), + FuriHalRtcFlagLegacySleep = (1 << 5), } FuriHalRtcFlag; typedef enum { @@ -85,6 +86,9 @@ void furi_hal_rtc_deinit_early(); /** Initialize RTC subsystem */ void furi_hal_rtc_init(); +/** Force sync shadow registers */ +void furi_hal_rtc_sync_shadow(); + /** Get RTC register content * * @param[in] reg The register identifier diff --git a/furi/core/check.c b/furi/core/check.c index 910527cee..64f9f72f1 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,8 @@ FURI_NORETURN void __furi_crash() { if(debug) { furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); furi_hal_console_puts("\033[0m\r\n"); + furi_hal_debug_enable(); + RESTORE_REGISTERS_AND_HALT_MCU(true); } else { furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message); diff --git a/furi/core/core_defines.h b/furi/core/core_defines.h index 03a364abd..830bb191c 100644 --- a/furi/core/core_defines.h +++ b/furi/core/core_defines.h @@ -24,6 +24,10 @@ extern "C" { }) #endif +#ifndef ABS +#define ABS(a) ({ (a) < 0 ? -(a) : (a); }) +#endif + #ifndef ROUND_UP_TO #define ROUND_UP_TO(a, b) \ ({ \ diff --git a/site_scons/cc.scons b/site_scons/cc.scons index 1eb6a3376..55ab72ba6 100644 --- a/site_scons/cc.scons +++ b/site_scons/cc.scons @@ -36,6 +36,7 @@ ENV.AppendUnique( ], CPPDEFINES=[ "_GNU_SOURCE", + *GetOption("extra_defines"), ], LINKFLAGS=[ "-mcpu=cortex-m4", diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons index d832a466e..2e9486627 100644 --- a/site_scons/commandline.scons +++ b/site_scons/commandline.scons @@ -26,6 +26,14 @@ AddOption( help="List of applications to add to firmware's built-ins. Also see FIRMWARE_APP_SET and FIRMWARE_APPS", ) +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( "--extra-ext-apps", action="store", From 9ede95954bb998239ca01ad42a2ea3c7fff7ee54 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:44:03 +0300 Subject: [PATCH 16/22] fbt format --- .../uart_terminal/scenes/uart_terminal_scene_console_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c b/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c index 7882a900a..6988c42de 100644 --- a/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c +++ b/applications/external/uart_terminal/scenes/uart_terminal_scene_console_output.c @@ -113,7 +113,7 @@ void uart_terminal_scene_console_output_on_enter(void* context) { // Send command with CR+LF or newline '\n' if(app->is_command && app->selected_tx_string) { - if(app->TERMINAL_MODE == 1){ + if(app->TERMINAL_MODE == 1) { uart_terminal_uart_tx( (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); uart_terminal_uart_tx((uint8_t*)("\r\n"), 2); From c7637a0fda141fe63940e5b9e1655a6c29ceb3b0 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 13 Apr 2023 21:20:29 +0300 Subject: [PATCH 17/22] Update TOTP https://github.com/akopachov/flipper-zero_authenticator --- .../external/totp/cli/commands/pin/pin.c | 13 + .../external/totp/cli/commands/reset/reset.c | 2 +- .../external/totp/lib/base32/base32.h | 2 +- .../external/totp/lib/base64/base64.c | 6 +- .../external/totp/lib/polyfills/strnlen.h | 3 + .../external/totp/services/config/config.c | 53 +++- .../external/totp/services/config/config.h | 7 +- .../external/totp/services/config/constants.h | 2 +- .../external/totp/services/crypto/crypto.c | 11 +- .../external/totp/services/hmac/hmac_common.h | 4 - .../external/totp/services/totp/totp.c | 4 +- applications/external/totp/totp_app.c | 13 +- .../external/totp/types/plugin_state.h | 2 +- applications/external/totp/types/token_info.c | 2 - applications/external/totp/types/token_info.h | 19 +- applications/external/totp/ui/constants.h | 4 +- .../totp/ui/fonts/mode-nine/mode_nine.c | 1 + .../totp/ui/fonts/mode-nine/mode_nine.h | 1 - .../external/totp/ui/scene_director.c | 16 -- .../external/totp/ui/scene_director.h | 12 - .../ui/scenes/add_new_token/totp_input_text.c | 1 - .../ui/scenes/add_new_token/totp_input_text.h | 4 +- .../add_new_token/totp_scene_add_new_token.c | 8 - .../add_new_token/totp_scene_add_new_token.h | 4 - .../scenes/app_settings/totp_app_settings.c | 8 - .../scenes/app_settings/totp_app_settings.h | 4 +- .../authenticate/totp_scene_authenticate.c | 8 - .../authenticate/totp_scene_authenticate.h | 2 - .../totp_scene_generate_token.c | 250 ++++++++---------- .../totp_scene_generate_token.h | 2 - .../scenes/token_menu/totp_scene_token_menu.c | 8 - .../scenes/token_menu/totp_scene_token_menu.h | 2 - applications/external/totp/ui/ui_controls.c | 4 +- .../totp/workers/bt_type_code/bt_type_code.c | 38 +-- .../totp/workers/bt_type_code/bt_type_code.h | 31 +-- .../generate_totp_code/generate_totp_code.c | 181 +++++++++++++ .../generate_totp_code/generate_totp_code.h | 49 ++++ .../workers/{common.c => type_code_common.c} | 16 +- .../workers/{common.h => type_code_common.h} | 4 +- .../workers/usb_type_code/usb_type_code.c | 26 +- .../workers/usb_type_code/usb_type_code.h | 19 +- 41 files changed, 505 insertions(+), 341 deletions(-) create mode 100644 applications/external/totp/workers/generate_totp_code/generate_totp_code.c create mode 100644 applications/external/totp/workers/generate_totp_code/generate_totp_code.h rename applications/external/totp/workers/{common.c => type_code_common.c} (88%) rename applications/external/totp/workers/{common.h => type_code_common.h} (83%) diff --git a/applications/external/totp/cli/commands/pin/pin.c b/applications/external/totp/cli/commands/pin/pin.c index 92c9c59c4..9b9038ae7 100644 --- a/applications/external/totp/cli/commands/pin/pin.c +++ b/applications/external/totp/cli/commands/pin/pin.c @@ -121,6 +121,19 @@ void totp_cli_command_pin_handle(PluginState* plugin_state, FuriString* args, Cl memset(&new_pin[0], 0, TOTP_IV_SIZE); } + char* backup_path = totp_config_file_backup(); + if(backup_path != NULL) { + TOTP_CLI_PRINTF_WARNING("Backup conf file %s has been created\r\n", backup_path); + TOTP_CLI_PRINTF_WARNING( + "Once you make sure everything is fine and works as expected, please delete this backup file\r\n"); + free(backup_path); + } else { + memset_s(&new_pin[0], TOTP_IV_SIZE, 0, TOTP_IV_SIZE); + TOTP_CLI_PRINTF_ERROR( + "An error has occurred during taking backup of config file\r\n"); + break; + } + if(plugin_state->current_scene == TotpSceneGenerateToken) { totp_scene_director_activate_scene(plugin_state, TotpSceneNone, NULL); load_generate_token_scene = true; diff --git a/applications/external/totp/cli/commands/reset/reset.c b/applications/external/totp/cli/commands/reset/reset.c index c7928db31..cd2d1bf46 100644 --- a/applications/external/totp/cli/commands/reset/reset.c +++ b/applications/external/totp/cli/commands/reset/reset.c @@ -1,7 +1,7 @@ #include "reset.h" #include -#include +#include #include "../../cli_helpers.h" #include "../../../services/config/config.h" diff --git a/applications/external/totp/lib/base32/base32.h b/applications/external/totp/lib/base32/base32.h index 8cb9bddcb..a0ec86e82 100644 --- a/applications/external/totp/lib/base32/base32.h +++ b/applications/external/totp/lib/base32/base32.h @@ -27,7 +27,7 @@ #pragma once -#include +#include #include /** diff --git a/applications/external/totp/lib/base64/base64.c b/applications/external/totp/lib/base64/base64.c index 1dfcf8814..dd0a12b5e 100644 --- a/applications/external/totp/lib/base64/base64.c +++ b/applications/external/totp/lib/base64/base64.c @@ -22,14 +22,14 @@ static const uint8_t dtable[] = {0x3e, 0x80, 0x80, 0x80, 0x3f, 0x34, 0x35, 0x36, 0x80, 0x80, 0x80, 0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33}; -// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + static uint8_t get_dtable_value(uint8_t index) { return (index < 43 || index > 122) ? 0x80 : dtable[index - 43]; } uint8_t* base64_decode(const uint8_t* src, size_t len, size_t* out_len, size_t* out_size) { - uint8_t *out; - uint8_t *pos; + uint8_t* out; + uint8_t* pos; uint8_t in[4]; uint8_t block[4]; uint8_t tmp; diff --git a/applications/external/totp/lib/polyfills/strnlen.h b/applications/external/totp/lib/polyfills/strnlen.h index 7dcef3a18..4fe0d540c 100644 --- a/applications/external/totp/lib/polyfills/strnlen.h +++ b/applications/external/totp/lib/polyfills/strnlen.h @@ -1,3 +1,6 @@ +#pragma once +#pragma weak strnlen + #include size_t strnlen(const char* s, size_t maxlen); \ No newline at end of file diff --git a/applications/external/totp/services/config/config.c b/applications/external/totp/services/config/config.c index adc85cbe5..0453338d3 100644 --- a/applications/external/totp/services/config/config.c +++ b/applications/external/totp/services/config/config.c @@ -9,7 +9,7 @@ #define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("authenticator") #define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf" -#define CONFIG_FILE_BACKUP_PATH CONFIG_FILE_PATH ".backup" +#define CONFIG_FILE_BACKUP_BASE_PATH CONFIG_FILE_PATH ".backup" #define CONFIG_FILE_TEMP_PATH CONFIG_FILE_PATH ".tmp" #define CONFIG_FILE_ORIG_PATH CONFIG_FILE_PATH ".orig" #define CONFIG_FILE_PATH_PREVIOUS EXT_PATH("apps/Misc") "/totp.conf" @@ -39,6 +39,34 @@ static void totp_close_config_file(FlipperFormat* file) { flipper_format_free(file); } +/** + * @brief Tries to take a config file backup + * @param storage storage record + * @return backup path if backup successfully taken; \c NULL otherwise + */ +static char* totp_config_file_backup_i(Storage* storage) { + uint8_t backup_path_size = sizeof(CONFIG_FILE_BACKUP_BASE_PATH) + 5; + char* backup_path = malloc(backup_path_size); + furi_check(backup_path != NULL); + memcpy(backup_path, CONFIG_FILE_BACKUP_BASE_PATH, sizeof(CONFIG_FILE_BACKUP_BASE_PATH)); + uint16_t i = 1; + bool backup_file_exists; + while((backup_file_exists = storage_common_exists(storage, backup_path)) && i <= 9999) { + snprintf(backup_path, backup_path_size, CONFIG_FILE_BACKUP_BASE_PATH ".%" PRIu16, i); + i++; + } + + if(backup_file_exists || + storage_common_copy(storage, CONFIG_FILE_PATH, backup_path) != FSE_OK) { + FURI_LOG_E(LOGGING_TAG, "Unable to take a backup"); + free(backup_path); + return NULL; + } + + FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", backup_path); + return backup_path; +} + /** * @brief Opens or creates TOTP application standard config file * @param storage storage record to use @@ -250,6 +278,13 @@ static TotpConfigFileUpdateResult return update_result; } +char* totp_config_file_backup() { + Storage* storage = totp_open_storage(); + char* result = totp_config_file_backup_i(storage); + totp_close_storage(); + return result; +} + TotpConfigFileUpdateResult totp_config_file_save_new_token(const TokenInfo* token_info) { Storage* cfg_storage = totp_open_storage(); FlipperFormat* file; @@ -513,20 +548,16 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st CONFIG_FILE_ACTUAL_VERSION); totp_close_config_file(fff_data_file); - if(storage_common_stat(storage, CONFIG_FILE_BACKUP_PATH, NULL) == FSE_OK) { - storage_simply_remove(storage, CONFIG_FILE_BACKUP_PATH); - } + char* backup_path = totp_config_file_backup_i(storage); - if(storage_common_copy(storage, CONFIG_FILE_PATH, CONFIG_FILE_BACKUP_PATH) == FSE_OK) { - FURI_LOG_I(LOGGING_TAG, "Took config file backup to %s", CONFIG_FILE_BACKUP_PATH); + if(backup_path != NULL) { if(totp_open_config_file(storage, &fff_data_file) != TotpConfigFileOpenSuccess) { result = TotpConfigFileOpenError; break; } FlipperFormat* fff_backup_data_file = flipper_format_file_alloc(storage); - if(!flipper_format_file_open_existing( - fff_backup_data_file, CONFIG_FILE_BACKUP_PATH)) { + if(!flipper_format_file_open_existing(fff_backup_data_file, backup_path)) { flipper_format_file_close(fff_backup_data_file); flipper_format_free(fff_backup_data_file); result = TotpConfigFileOpenError; @@ -551,12 +582,12 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st flipper_format_file_close(fff_backup_data_file); flipper_format_free(fff_backup_data_file); flipper_format_rewind(fff_data_file); + free(backup_path); } else { FURI_LOG_E( LOGGING_TAG, - "An error occurred during taking backup of %s into %s before migration", - CONFIG_FILE_PATH, - CONFIG_FILE_BACKUP_PATH); + "An error occurred during taking backup of %s before migration", + CONFIG_FILE_PATH); result = TotpConfigFileOpenError; break; } diff --git a/applications/external/totp/services/config/config.h b/applications/external/totp/services/config/config.h index 3d325368d..5bd169525 100644 --- a/applications/external/totp/services/config/config.h +++ b/applications/external/totp/services/config/config.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include "../../types/plugin_state.h" #include "../../types/token_info.h" #include "constants.h" @@ -60,6 +59,12 @@ enum TotpConfigFileUpdateResults { TotpConfigFileUpdateError }; +/** + * @brief Tries to take a config file backup + * @return backup path if backup successfully taken; \c NULL otherwise + */ +char* totp_config_file_backup(); + /** * @brief Saves all the settings and tokens to an application config file * @param plugin_state application state diff --git a/applications/external/totp/services/config/constants.h b/applications/external/totp/services/config/constants.h index 9924aefe2..7137e2374 100644 --- a/applications/external/totp/services/config/constants.h +++ b/applications/external/totp/services/config/constants.h @@ -1,7 +1,7 @@ #pragma once #define CONFIG_FILE_HEADER "Flipper TOTP plugin config file" -#define CONFIG_FILE_ACTUAL_VERSION 4 +#define CONFIG_FILE_ACTUAL_VERSION (4) #define TOTP_CONFIG_KEY_TIMEZONE "Timezone" #define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName" diff --git a/applications/external/totp/services/crypto/crypto.c b/applications/external/totp/services/crypto/crypto.c index ed4775dfb..00f5ab0a8 100644 --- a/applications/external/totp/services/crypto/crypto.c +++ b/applications/external/totp/services/crypto/crypto.c @@ -1,14 +1,15 @@ #include "crypto.h" -#include -#include +#include +#include +#include #include "../config/config.h" #include "../../types/common.h" #include "memset_s.h" -#define CRYPTO_KEY_SLOT 2 +#define CRYPTO_KEY_SLOT (2) #define CRYPTO_VERIFY_KEY "FFF_Crypto_pass" -#define CRYPTO_VERIFY_KEY_LENGTH 16 -#define CRYPTO_ALIGNMENT_FACTOR 16 +#define CRYPTO_VERIFY_KEY_LENGTH (16) +#define CRYPTO_ALIGNMENT_FACTOR (16) uint8_t* totp_crypto_encrypt( const uint8_t* plain_data, diff --git a/applications/external/totp/services/hmac/hmac_common.h b/applications/external/totp/services/hmac/hmac_common.h index 9c5b5828f..0cd56ed99 100644 --- a/applications/external/totp/services/hmac/hmac_common.h +++ b/applications/external/totp/services/hmac/hmac_common.h @@ -9,11 +9,7 @@ #define _GLHMAC_CONCAT_(prefix, suffix) prefix##suffix #define _GLHMAC_CONCAT(prefix, suffix) _GLHMAC_CONCAT_(prefix, suffix) -#if GL_HMAC_NAME == 5 -#define HMAC_ALG md5 -#else #define HMAC_ALG _GLHMAC_CONCAT(sha, GL_HMAC_NAME) -#endif #define GL_HMAC_CTX _GLHMAC_CONCAT(HMAC_ALG, _ctx) #define GL_HMAC_FN _GLHMAC_CONCAT(hmac_, HMAC_ALG) diff --git a/applications/external/totp/services/totp/totp.c b/applications/external/totp/services/totp/totp.c index f6e0401e6..45a283b06 100644 --- a/applications/external/totp/services/totp/totp.c +++ b/applications/external/totp/services/totp/totp.c @@ -1,15 +1,13 @@ #include "totp.h" -#include #include #include -#include #include +#include #include "../hmac/hmac_sha1.h" #include "../hmac/hmac_sha256.h" #include "../hmac/hmac_sha512.h" #include "../hmac/byteswap.h" -#include "../../lib/timezone_utils/timezone_utils.h" #define HMAC_MAX_RESULT_SIZE HMAC_SHA512_RESULT_SIZE diff --git a/applications/external/totp/totp_app.c b/applications/external/totp/totp_app.c index 74ec52f2c..0b70167a2 100644 --- a/applications/external/totp/totp_app.c +++ b/applications/external/totp/totp_app.c @@ -1,10 +1,7 @@ -#include -#include #include #include #include #include -#include #include #include #include @@ -21,7 +18,7 @@ #include "services/crypto/crypto.h" #include "cli/cli.h" -#define IDLE_TIMEOUT 60000 +#define IDLE_TIMEOUT (60000) static void render_callback(Canvas* const canvas, void* ctx) { furi_assert(ctx); @@ -97,6 +94,7 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) { plugin_state->gui = furi_record_open(RECORD_GUI); plugin_state->notification_app = furi_record_open(RECORD_NOTIFICATION); plugin_state->dialogs_app = furi_record_open(RECORD_DIALOGS); + memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); if(totp_config_file_load_base(plugin_state) != TotpConfigFileOpenSuccess) { totp_dialogs_config_loading_error(plugin_state); @@ -104,10 +102,6 @@ static bool totp_plugin_state_init(PluginState* const plugin_state) { } plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(plugin_state->mutex == NULL) { - FURI_LOG_E(LOGGING_TAG, "Cannot create mutex\r\n"); - return false; - } #ifdef TOTP_BADBT_TYPE_ENABLED if(plugin_state->automation_method & AutomationMethodBadBt) { @@ -162,7 +156,7 @@ int32_t totp_app() { } TotpCliContext* cli_context = totp_cli_register_command_handler(plugin_state, event_queue); - totp_scene_director_init_scenes(plugin_state); + if(!totp_activate_initial_scene(plugin_state)) { FURI_LOG_E(LOGGING_TAG, "An error ocurred during activating initial scene\r\n"); totp_plugin_state_free(plugin_state); @@ -210,7 +204,6 @@ int32_t totp_app() { totp_cli_unregister_command_handler(cli_context); totp_scene_director_deactivate_active_scene(plugin_state); - totp_scene_director_dispose(plugin_state); view_port_enabled_set(view_port, false); gui_remove_view_port(plugin_state->gui, view_port); diff --git a/applications/external/totp/types/plugin_state.h b/applications/external/totp/types/plugin_state.h index b1d34a662..cacf68426 100644 --- a/applications/external/totp/types/plugin_state.h +++ b/applications/external/totp/types/plugin_state.h @@ -12,7 +12,7 @@ #include "../workers/bt_type_code/bt_type_code.h" #endif -#define TOTP_IV_SIZE 16 +#define TOTP_IV_SIZE (16) /** * @brief Application state structure diff --git a/applications/external/totp/types/token_info.c b/applications/external/totp/types/token_info.c index b8196c56b..5b85de719 100644 --- a/applications/external/totp/types/token_info.c +++ b/applications/external/totp/types/token_info.c @@ -1,9 +1,7 @@ #include "token_info.h" -#include #include #include #include -#include #include "common.h" #include "../services/crypto/crypto.h" diff --git a/applications/external/totp/types/token_info.h b/applications/external/totp/types/token_info.h index 688e8028d..21968553f 100644 --- a/applications/external/totp/types/token_info.h +++ b/applications/external/totp/types/token_info.h @@ -2,15 +2,15 @@ #include #include -#include +#include -#define TOTP_TOKEN_DURATION_DEFAULT 30 +#define TOTP_TOKEN_DURATION_DEFAULT (30) #define TOTP_TOKEN_ALGO_SHA1_NAME "sha1" #define TOTP_TOKEN_ALGO_STEAM_NAME "steam" #define TOTP_TOKEN_ALGO_SHA256_NAME "sha256" #define TOTP_TOKEN_ALGO_SHA512_NAME "sha512" -#define TOTP_TOKEN_MAX_LENGTH 255 +#define TOTP_TOKEN_MAX_LENGTH (255) #define PLAIN_TOKEN_ENCODING_BASE32_NAME "base32" #define PLAIN_TOKEN_ENCODING_BASE64_NAME "base64" @@ -95,12 +95,23 @@ enum TokenAutomationFeatures { TOKEN_AUTOMATION_FEATURE_TYPE_SLOWER = 0b100 }; +/** + * @brief Plain token secret encodings. + */ enum PlainTokenSecretEncodings { + + /** + * @brief Base32 encoding + */ PLAIN_TOKEN_ENCODING_BASE32 = 0, + + /** + * @brief Base64 encoding + */ PLAIN_TOKEN_ENCODING_BASE64 = 1 }; -#define TOTP_TOKEN_DIGITS_MAX_COUNT 8 +#define TOTP_TOKEN_DIGITS_MAX_COUNT (8) /** * @brief TOTP token information diff --git a/applications/external/totp/ui/constants.h b/applications/external/totp/ui/constants.h index 9caf90c4e..81c2edf92 100644 --- a/applications/external/totp/ui/constants.h +++ b/applications/external/totp/ui/constants.h @@ -1,6 +1,6 @@ #pragma once -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 +#define SCREEN_WIDTH (128) +#define SCREEN_HEIGHT (64) #define SCREEN_WIDTH_CENTER (SCREEN_WIDTH >> 1) #define SCREEN_HEIGHT_CENTER (SCREEN_HEIGHT >> 1) diff --git a/applications/external/totp/ui/fonts/mode-nine/mode_nine.c b/applications/external/totp/ui/fonts/mode-nine/mode_nine.c index add4f47ef..ca2191789 100644 --- a/applications/external/totp/ui/fonts/mode-nine/mode_nine.c +++ b/applications/external/totp/ui/fonts/mode-nine/mode_nine.c @@ -1,4 +1,5 @@ #include "mode_nine.h" +#include /* GENERATED BY https://github.com/pavius/the-dot-factory */ diff --git a/applications/external/totp/ui/fonts/mode-nine/mode_nine.h b/applications/external/totp/ui/fonts/mode-nine/mode_nine.h index 67fa33afe..516e261f8 100644 --- a/applications/external/totp/ui/fonts/mode-nine/mode_nine.h +++ b/applications/external/totp/ui/fonts/mode-nine/mode_nine.h @@ -3,7 +3,6 @@ /* GENERATED BY https://github.com/pavius/the-dot-factory */ #include "../font_info.h" -#include /* Font data for ModeNine 15pt */ extern const FONT_INFO modeNine_15ptFontInfo; diff --git a/applications/external/totp/ui/scene_director.c b/applications/external/totp/ui/scene_director.c index c77e88ab4..c6f709006 100644 --- a/applications/external/totp/ui/scene_director.c +++ b/applications/external/totp/ui/scene_director.c @@ -62,14 +62,6 @@ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state } } -void totp_scene_director_init_scenes(PluginState* const plugin_state) { - totp_scene_authenticate_init(plugin_state); - totp_scene_generate_token_init(plugin_state); - totp_scene_add_new_token_init(plugin_state); - totp_scene_token_menu_init(plugin_state); - totp_scene_app_settings_init(plugin_state); -} - void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state) { switch(plugin_state->current_scene) { case TotpSceneGenerateToken: @@ -94,14 +86,6 @@ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_ } } -void totp_scene_director_dispose(const PluginState* const plugin_state) { - totp_scene_generate_token_free(plugin_state); - totp_scene_authenticate_free(plugin_state); - totp_scene_add_new_token_free(plugin_state); - totp_scene_token_menu_free(plugin_state); - totp_scene_app_settings_free(plugin_state); -} - bool totp_scene_director_handle_event(PluginEvent* const event, PluginState* const plugin_state) { bool processing = true; switch(plugin_state->current_scene) { diff --git a/applications/external/totp/ui/scene_director.h b/applications/external/totp/ui/scene_director.h index 541a63f1c..71709978f 100644 --- a/applications/external/totp/ui/scene_director.h +++ b/applications/external/totp/ui/scene_director.h @@ -22,12 +22,6 @@ void totp_scene_director_activate_scene( */ void totp_scene_director_deactivate_active_scene(PluginState* const plugin_state); -/** - * @brief Initializes all the available scenes - * @param plugin_state application state - */ -void totp_scene_director_init_scenes(PluginState* const plugin_state); - /** * @brief Renders current scene * @param canvas canvas to render at @@ -35,12 +29,6 @@ void totp_scene_director_init_scenes(PluginState* const plugin_state); */ void totp_scene_director_render(Canvas* const canvas, PluginState* const plugin_state); -/** - * @brief Disposes all the available scenes - * @param plugin_state application state - */ -void totp_scene_director_dispose(const PluginState* const plugin_state); - /** * @brief Handles application event for the current scene * @param event event to be handled diff --git a/applications/external/totp/ui/scenes/add_new_token/totp_input_text.c b/applications/external/totp/ui/scenes/add_new_token/totp_input_text.c index 6956ec1ad..bbe0b7726 100644 --- a/applications/external/totp/ui/scenes/add_new_token/totp_input_text.c +++ b/applications/external/totp/ui/scenes/add_new_token/totp_input_text.c @@ -1,6 +1,5 @@ #include "totp_input_text.h" #include -#include "../../../lib/polyfills/strnlen.h" void view_draw(View* view, Canvas* canvas) { furi_assert(view); diff --git a/applications/external/totp/ui/scenes/add_new_token/totp_input_text.h b/applications/external/totp/ui/scenes/add_new_token/totp_input_text.h index 145e8904d..ffbfde692 100644 --- a/applications/external/totp/ui/scenes/add_new_token/totp_input_text.h +++ b/applications/external/totp/ui/scenes/add_new_token/totp_input_text.h @@ -6,6 +6,8 @@ #include "../../../types/plugin_state.h" #include "../../../types/plugin_event.h" +#define INPUT_BUFFER_SIZE (255) + typedef struct { char* user_input; size_t user_input_length; @@ -20,8 +22,6 @@ typedef struct { void* callback_data; } InputTextSceneContext; -#define INPUT_BUFFER_SIZE 255 - typedef struct { TextInput* text_input; View* text_input_view; diff --git a/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c b/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c index 800d7e672..3f8e4fd93 100644 --- a/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c +++ b/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c @@ -44,10 +44,6 @@ typedef struct { FuriString* duration_text; } SceneState; -void totp_scene_add_new_token_init(const PluginState* plugin_state) { - UNUSED(plugin_state); -} - static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) { SceneState* scene_state = result->callback_data; free(scene_state->token_name); @@ -354,7 +350,3 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) { free(plugin_state->current_scene_state); plugin_state->current_scene_state = NULL; } - -void totp_scene_add_new_token_free(const PluginState* plugin_state) { - UNUSED(plugin_state); -} diff --git a/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h b/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h index c412e5f0f..e05a95dbd 100644 --- a/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h +++ b/applications/external/totp/ui/scenes/add_new_token/totp_scene_add_new_token.h @@ -1,8 +1,6 @@ #pragma once #include -#include -#include #include "../../../types/plugin_state.h" #include "../../../types/plugin_event.h" @@ -10,11 +8,9 @@ typedef struct { uint16_t current_token_index; } TokenAddEditSceneContext; -void totp_scene_add_new_token_init(const PluginState* plugin_state); void totp_scene_add_new_token_activate( PluginState* plugin_state, const TokenAddEditSceneContext* context); void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state); bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state); void totp_scene_add_new_token_deactivate(PluginState* plugin_state); -void totp_scene_add_new_token_free(const PluginState* plugin_state); diff --git a/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c b/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c index 93fd3d915..d2cf629d2 100644 --- a/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c +++ b/applications/external/totp/ui/scenes/app_settings/totp_app_settings.c @@ -44,10 +44,6 @@ typedef struct { Control selected_control; } SceneState; -void totp_scene_app_settings_init(const PluginState* plugin_state) { - UNUSED(plugin_state); -} - void totp_scene_app_settings_activate( PluginState* plugin_state, const AppSettingsSceneContext* context) { @@ -332,7 +328,3 @@ void totp_scene_app_settings_deactivate(PluginState* plugin_state) { free(plugin_state->current_scene_state); plugin_state->current_scene_state = NULL; } - -void totp_scene_app_settings_free(const PluginState* plugin_state) { - UNUSED(plugin_state); -} \ No newline at end of file diff --git a/applications/external/totp/ui/scenes/app_settings/totp_app_settings.h b/applications/external/totp/ui/scenes/app_settings/totp_app_settings.h index 1721186ed..a0e408b00 100644 --- a/applications/external/totp/ui/scenes/app_settings/totp_app_settings.h +++ b/applications/external/totp/ui/scenes/app_settings/totp_app_settings.h @@ -8,7 +8,6 @@ typedef struct { uint16_t current_token_index; } AppSettingsSceneContext; -void totp_scene_app_settings_init(const PluginState* plugin_state); void totp_scene_app_settings_activate( PluginState* plugin_state, const AppSettingsSceneContext* context); @@ -16,5 +15,4 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu bool totp_scene_app_settings_handle_event( const PluginEvent* const event, PluginState* plugin_state); -void totp_scene_app_settings_deactivate(PluginState* plugin_state); -void totp_scene_app_settings_free(const PluginState* plugin_state); \ No newline at end of file +void totp_scene_app_settings_deactivate(PluginState* plugin_state); \ No newline at end of file diff --git a/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.c b/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.c index 17beb64c6..c0a0b5744 100644 --- a/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.c +++ b/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.c @@ -18,10 +18,6 @@ typedef struct { uint8_t code_length; } SceneState; -void totp_scene_authenticate_init(PluginState* plugin_state) { - memset(&plugin_state->iv[0], 0, TOTP_IV_SIZE); -} - void totp_scene_authenticate_activate(PluginState* plugin_state) { SceneState* scene_state = malloc(sizeof(SceneState)); furi_check(scene_state != NULL); @@ -162,7 +158,3 @@ void totp_scene_authenticate_deactivate(PluginState* plugin_state) { free(plugin_state->current_scene_state); plugin_state->current_scene_state = NULL; } - -void totp_scene_authenticate_free(const PluginState* plugin_state) { - UNUSED(plugin_state); -} diff --git a/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.h b/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.h index b8fe174ae..5ddd44a4a 100644 --- a/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.h +++ b/applications/external/totp/ui/scenes/authenticate/totp_scene_authenticate.h @@ -4,11 +4,9 @@ #include "../../../types/plugin_state.h" #include "../../../types/plugin_event.h" -void totp_scene_authenticate_init(PluginState* plugin_state); void totp_scene_authenticate_activate(PluginState* plugin_state); void totp_scene_authenticate_render(Canvas* const canvas, PluginState* plugin_state); bool totp_scene_authenticate_handle_event( const PluginEvent* const event, PluginState* plugin_state); void totp_scene_authenticate_deactivate(PluginState* plugin_state); -void totp_scene_authenticate_free(const PluginState* plugin_state); diff --git a/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c b/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c index f27b24835..92a45eb4a 100644 --- a/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.c @@ -2,39 +2,44 @@ #include #include #include +#include #include "totp_scene_generate_token.h" #include "../../../types/token_info.h" #include "../../../types/common.h" #include "../../constants.h" -#include "../../../services/totp/totp.h" #include "../../../services/config/config.h" -#include "../../../services/crypto/crypto.h" -#include "../../../services/convert/convert.h" -#include "../../../lib/polyfills/memset_s.h" -#include "../../../lib/roll_value/roll_value.h" #include "../../scene_director.h" #include "../token_menu/totp_scene_token_menu.h" #include "../../../features_config.h" +#include "../../../workers/generate_totp_code/generate_totp_code.h" #include "../../../workers/usb_type_code/usb_type_code.h" #ifdef TOTP_BADBT_TYPE_ENABLED #include "../../../workers/bt_type_code/bt_type_code.h" #endif #include "../../fonts/mode-nine/mode_nine.h" -static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY"; -static const uint8_t PROGRESS_BAR_MARGIN = 3; -static const uint8_t PROGRESS_BAR_HEIGHT = 4; +#define PROGRESS_BAR_MARGIN (3) +#define PROGRESS_BAR_HEIGHT (4) + +typedef struct { + uint8_t progress_bar_x; + uint8_t progress_bar_width; + uint8_t code_total_length; + uint8_t code_offset_x; + uint8_t code_offset_x_inc; + uint8_t code_offset_y; +} UiPrecalculatedDimensions; typedef struct { uint16_t current_token_index; char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1]; - bool need_token_update; TokenInfo* current_token; - uint32_t last_token_gen_time; TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context; NotificationMessage const** notification_sequence_new_token; - NotificationMessage const** notification_sequence_badusb; + NotificationMessage const** notification_sequence_automation; FuriMutex* last_code_update_sync; + TotpGenerateCodeWorkerContext* generate_code_worker_context; + UiPrecalculatedDimensions ui_precalculated_dimensions; } SceneState; static const NotificationSequence* @@ -80,7 +85,7 @@ static const NotificationSequence* static const NotificationSequence* get_notification_sequence_automation(const PluginState* plugin_state, SceneState* scene_state) { - if(scene_state->notification_sequence_badusb == NULL) { + if(scene_state->notification_sequence_automation == NULL) { uint8_t i = 0; uint8_t length = 3; if(plugin_state->notification_method & NotificationMethodVibro) { @@ -91,110 +96,100 @@ static const NotificationSequence* length += 6; } - scene_state->notification_sequence_badusb = malloc(sizeof(void*) * length); - furi_check(scene_state->notification_sequence_badusb != NULL); + scene_state->notification_sequence_automation = malloc(sizeof(void*) * length); + furi_check(scene_state->notification_sequence_automation != NULL); - scene_state->notification_sequence_badusb[i++] = &message_blue_255; + scene_state->notification_sequence_automation[i++] = &message_blue_255; if(plugin_state->notification_method & NotificationMethodVibro) { - scene_state->notification_sequence_badusb[i++] = &message_vibro_on; + scene_state->notification_sequence_automation[i++] = &message_vibro_on; } if(plugin_state->notification_method & NotificationMethodSound) { - scene_state->notification_sequence_badusb[i++] = &message_note_d5; //-V525 - scene_state->notification_sequence_badusb[i++] = &message_delay_50; - scene_state->notification_sequence_badusb[i++] = &message_note_e4; - scene_state->notification_sequence_badusb[i++] = &message_delay_50; - scene_state->notification_sequence_badusb[i++] = &message_note_f3; + scene_state->notification_sequence_automation[i++] = &message_note_d5; //-V525 + scene_state->notification_sequence_automation[i++] = &message_delay_50; + scene_state->notification_sequence_automation[i++] = &message_note_e4; + scene_state->notification_sequence_automation[i++] = &message_delay_50; + scene_state->notification_sequence_automation[i++] = &message_note_f3; } - scene_state->notification_sequence_badusb[i++] = &message_delay_50; + scene_state->notification_sequence_automation[i++] = &message_delay_50; if(plugin_state->notification_method & NotificationMethodVibro) { - scene_state->notification_sequence_badusb[i++] = &message_vibro_off; + scene_state->notification_sequence_automation[i++] = &message_vibro_off; } if(plugin_state->notification_method & NotificationMethodSound) { - scene_state->notification_sequence_badusb[i++] = &message_sound_off; + scene_state->notification_sequence_automation[i++] = &message_sound_off; } - scene_state->notification_sequence_badusb[i++] = NULL; + scene_state->notification_sequence_automation[i++] = NULL; } - return (NotificationSequence*)scene_state->notification_sequence_badusb; -} - -static void - int_token_to_str(uint64_t i_token_code, char* str, TokenDigitsCount len, TokenHashAlgo algo) { - if(i_token_code == OTP_ERROR) { - memset(&str[0], '-', len); - } else { - if(algo == STEAM) { - for(uint8_t i = 0; i < len; i++) { - str[i] = STEAM_ALGO_ALPHABET[i_token_code % 26]; - i_token_code = i_token_code / 26; - } - } else { - for(int8_t i = len - 1; i >= 0; i--) { - str[i] = CONVERT_DIGIT_TO_CHAR(i_token_code % 10); - i_token_code = i_token_code / 10; - } - } - } - - str[len] = '\0'; -} - -static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) { - switch(algo) { - case SHA1: - case STEAM: - return TOTP_ALGO_SHA1; - case SHA256: - return TOTP_ALGO_SHA256; - case SHA512: - return TOTP_ALGO_SHA512; - default: - break; - } - - return NULL; + return (NotificationSequence*)scene_state->notification_sequence_automation; } static void update_totp_params(PluginState* const plugin_state) { SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; if(scene_state->current_token_index < plugin_state->tokens_count) { - TokenInfo* tokenInfo = + scene_state->current_token = list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data; - - scene_state->need_token_update = true; - scene_state->current_token = tokenInfo; + totp_generate_code_worker_notify( + scene_state->generate_code_worker_context, TotpGenerateCodeWorkerEventForceUpdate); } } static void draw_totp_code(Canvas* const canvas, const SceneState* const scene_state) { uint8_t code_length = scene_state->current_token->digits; + uint8_t offset_x = scene_state->ui_precalculated_dimensions.code_offset_x; uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width; - uint8_t total_length = code_length * (char_width + modeNine_15ptFontInfo.spacePixels); - uint8_t offset_x = (SCREEN_WIDTH - total_length) >> 1; - uint8_t offset_y = SCREEN_HEIGHT_CENTER - (modeNine_15ptFontInfo.height >> 1); + uint8_t offset_x_inc = scene_state->ui_precalculated_dimensions.code_offset_x_inc; for(uint8_t i = 0; i < code_length; i++) { char ch = scene_state->last_code[i]; - uint8_t char_index = ch - modeNine_15ptFontInfo.startChar; - canvas_draw_xbm( - canvas, - offset_x, - offset_y, - char_width, - modeNine_15ptFontInfo.height, - &modeNine_15ptFontInfo.data[modeNine_15ptFontInfo.charInfo[char_index].offset]); + if(ch >= modeNine_15ptFontInfo.startChar && ch <= modeNine_15ptFontInfo.endChar) { + uint8_t char_index = ch - modeNine_15ptFontInfo.startChar; + canvas_draw_xbm( + canvas, + offset_x, + scene_state->ui_precalculated_dimensions.code_offset_y, + char_width, + modeNine_15ptFontInfo.height, + &modeNine_15ptFontInfo.data[modeNine_15ptFontInfo.charInfo[char_index].offset]); + } - offset_x += char_width + modeNine_15ptFontInfo.spacePixels; + offset_x += offset_x_inc; } } -void totp_scene_generate_token_init(const PluginState* plugin_state) { - UNUSED(plugin_state); +static void on_new_token_code_generated(bool time_left, void* context) { + const PluginState* plugin_state = context; + SceneState* scene_state = plugin_state->current_scene_state; + uint8_t char_width = modeNine_15ptFontInfo.charInfo[0].width; + scene_state->ui_precalculated_dimensions.code_total_length = + scene_state->current_token->digits * (char_width + modeNine_15ptFontInfo.spacePixels); + scene_state->ui_precalculated_dimensions.code_offset_x = + (SCREEN_WIDTH - scene_state->ui_precalculated_dimensions.code_total_length) >> 1; + scene_state->ui_precalculated_dimensions.code_offset_x_inc = + char_width + modeNine_15ptFontInfo.spacePixels; + scene_state->ui_precalculated_dimensions.code_offset_y = + SCREEN_HEIGHT_CENTER - (modeNine_15ptFontInfo.height >> 1); + + if(time_left) { + notification_message( + plugin_state->notification_app, + get_notification_sequence_new_token(plugin_state, plugin_state->current_scene_state)); + } +} + +static void on_code_lifetime_updated_generated(float code_lifetime_percent, void* context) { + SceneState* scene_state = context; + scene_state->ui_precalculated_dimensions.progress_bar_width = + (uint8_t)((float)(SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1)) * code_lifetime_percent); + scene_state->ui_precalculated_dimensions.progress_bar_x = + ((SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1) - + scene_state->ui_precalculated_dimensions.progress_bar_width) >> + 1) + + PROGRESS_BAR_MARGIN; } void totp_scene_generate_token_activate( @@ -234,15 +229,14 @@ void totp_scene_generate_token_activate( } else { scene_state->current_token_index = context->current_token_index; } - scene_state->need_token_update = true; + plugin_state->current_scene_state = scene_state; FURI_LOG_D(LOGGING_TAG, "Timezone set to: %f", (double)plugin_state->timezone_offset); - update_totp_params(plugin_state); scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal); if(plugin_state->automation_method & AutomationMethodBadUsb) { scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start( - &scene_state->last_code[0], + scene_state->last_code, TOTP_TOKEN_DIGITS_MAX_COUNT + 1, scene_state->last_code_update_sync); } @@ -255,11 +249,28 @@ void totp_scene_generate_token_activate( } totp_bt_type_code_worker_start( plugin_state->bt_type_code_worker_context, - &scene_state->last_code[0], + scene_state->last_code, TOTP_TOKEN_DIGITS_MAX_COUNT + 1, scene_state->last_code_update_sync); } #endif + + scene_state->generate_code_worker_context = totp_generate_code_worker_start( + scene_state->last_code, + &scene_state->current_token, + scene_state->last_code_update_sync, + plugin_state->timezone_offset, + plugin_state->iv); + + totp_generate_code_worker_set_code_generated_handler( + scene_state->generate_code_worker_context, &on_new_token_code_generated, plugin_state); + + totp_generate_code_worker_set_lifetime_changed_handler( + scene_state->generate_code_worker_context, + &on_code_lifetime_updated_generated, + scene_state); + + update_totp_params(plugin_state); } void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_state) { @@ -281,54 +292,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ return; } - SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; - FuriHalRtcDateTime curr_dt; - furi_hal_rtc_get_datetime(&curr_dt); - uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - - bool is_new_token_time = curr_ts % scene_state->current_token->duration == 0; - if(is_new_token_time && scene_state->last_token_gen_time != curr_ts) { - scene_state->need_token_update = true; - } - - if(scene_state->need_token_update) { - scene_state->need_token_update = false; - scene_state->last_token_gen_time = curr_ts; - - const TokenInfo* tokenInfo = scene_state->current_token; - - if(tokenInfo->token != NULL && tokenInfo->token_length > 0) { - furi_mutex_acquire(scene_state->last_code_update_sync, FuriWaitForever); - size_t key_length; - uint8_t* key = totp_crypto_decrypt( - tokenInfo->token, tokenInfo->token_length, &plugin_state->iv[0], &key_length); - - int_token_to_str( - totp_at( - get_totp_algo_impl(tokenInfo->algo), - key, - key_length, - curr_ts, - plugin_state->timezone_offset, - tokenInfo->duration), - scene_state->last_code, - tokenInfo->digits, - tokenInfo->algo); - memset_s(key, key_length, 0, key_length); - free(key); - } else { - furi_mutex_acquire(scene_state->last_code_update_sync, FuriWaitForever); - int_token_to_str(0, scene_state->last_code, tokenInfo->digits, tokenInfo->algo); - } - - furi_mutex_release(scene_state->last_code_update_sync); - - if(is_new_token_time) { - notification_message( - plugin_state->notification_app, - get_notification_sequence_new_token(plugin_state, scene_state)); - } - } + const SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; canvas_set_font(canvas, FontPrimary); uint16_t token_name_width = canvas_string_width(canvas, scene_state->current_token->name); @@ -356,17 +320,11 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ draw_totp_code(canvas, scene_state); - const uint8_t TOKEN_LIFETIME = scene_state->current_token->duration; - float percentDone = (float)(TOKEN_LIFETIME - curr_ts % TOKEN_LIFETIME) / (float)TOKEN_LIFETIME; - uint8_t barWidth = (uint8_t)((float)(SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1)) * percentDone); - uint8_t barX = - ((SCREEN_WIDTH - (PROGRESS_BAR_MARGIN << 1) - barWidth) >> 1) + PROGRESS_BAR_MARGIN; - canvas_draw_box( canvas, - barX, + scene_state->ui_precalculated_dimensions.progress_bar_x, SCREEN_HEIGHT - PROGRESS_BAR_MARGIN - PROGRESS_BAR_HEIGHT, - barWidth, + scene_state->ui_precalculated_dimensions.progress_bar_width, PROGRESS_BAR_HEIGHT); if(plugin_state->tokens_count > 1) { @@ -496,6 +454,8 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) { if(plugin_state->current_scene_state == NULL) return; SceneState* scene_state = (SceneState*)plugin_state->current_scene_state; + totp_generate_code_worker_stop(scene_state->generate_code_worker_context); + if(plugin_state->automation_method & AutomationMethodBadUsb) { totp_usb_type_code_worker_stop(scene_state->usb_type_code_worker_context); } @@ -509,8 +469,8 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) { free(scene_state->notification_sequence_new_token); } - if(scene_state->notification_sequence_badusb != NULL) { - free(scene_state->notification_sequence_badusb); + if(scene_state->notification_sequence_automation != NULL) { + free(scene_state->notification_sequence_automation); } furi_mutex_free(scene_state->last_code_update_sync); @@ -518,7 +478,3 @@ void totp_scene_generate_token_deactivate(PluginState* plugin_state) { free(scene_state); plugin_state->current_scene_state = NULL; } - -void totp_scene_generate_token_free(const PluginState* plugin_state) { - UNUSED(plugin_state); -} diff --git a/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.h b/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.h index 44a3b1c0f..e183f53d2 100644 --- a/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.h +++ b/applications/external/totp/ui/scenes/generate_token/totp_scene_generate_token.h @@ -8,7 +8,6 @@ typedef struct { uint16_t current_token_index; } GenerateTokenSceneContext; -void totp_scene_generate_token_init(const PluginState* plugin_state); void totp_scene_generate_token_activate( PluginState* plugin_state, const GenerateTokenSceneContext* context); @@ -17,4 +16,3 @@ bool totp_scene_generate_token_handle_event( const PluginEvent* const event, PluginState* plugin_state); void totp_scene_generate_token_deactivate(PluginState* plugin_state); -void totp_scene_generate_token_free(const PluginState* plugin_state); diff --git a/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.c b/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.c index 6c6986c65..7b00f0a1b 100644 --- a/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.c +++ b/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.c @@ -24,10 +24,6 @@ typedef struct { TotpNullable_uint16_t current_token_index; } SceneState; -void totp_scene_token_menu_init(const PluginState* plugin_state) { - UNUSED(plugin_state); -} - void totp_scene_token_menu_activate( PluginState* plugin_state, const TokenMenuSceneContext* context) { @@ -204,7 +200,3 @@ void totp_scene_token_menu_deactivate(PluginState* plugin_state) { free(plugin_state->current_scene_state); plugin_state->current_scene_state = NULL; } - -void totp_scene_token_menu_free(const PluginState* plugin_state) { - UNUSED(plugin_state); -} diff --git a/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.h b/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.h index 059b8e571..f9d4b4cbf 100644 --- a/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.h +++ b/applications/external/totp/ui/scenes/token_menu/totp_scene_token_menu.h @@ -8,11 +8,9 @@ typedef struct { uint16_t current_token_index; } TokenMenuSceneContext; -void totp_scene_token_menu_init(const PluginState* plugin_state); void totp_scene_token_menu_activate( PluginState* plugin_state, const TokenMenuSceneContext* context); void totp_scene_token_menu_render(Canvas* const canvas, PluginState* plugin_state); bool totp_scene_token_menu_handle_event(const PluginEvent* const event, PluginState* plugin_state); void totp_scene_token_menu_deactivate(PluginState* plugin_state); -void totp_scene_token_menu_free(const PluginState* plugin_state); diff --git a/applications/external/totp/ui/ui_controls.c b/applications/external/totp/ui/ui_controls.c index af029dd9f..d5e86aa58 100644 --- a/applications/external/totp/ui/ui_controls.c +++ b/applications/external/totp/ui/ui_controls.c @@ -2,8 +2,8 @@ #include #include "constants.h" -#define TEXT_BOX_HEIGHT 13 -#define TEXT_BOX_MARGIN 4 +#define TEXT_BOX_HEIGHT (13) +#define TEXT_BOX_MARGIN (4) void ui_control_text_box_render( Canvas* const canvas, diff --git a/applications/external/totp/workers/bt_type_code/bt_type_code.c b/applications/external/totp/workers/bt_type_code/bt_type_code.c index ec4c1619d..5a1f56298 100644 --- a/applications/external/totp/workers/bt_type_code/bt_type_code.c +++ b/applications/external/totp/workers/bt_type_code/bt_type_code.c @@ -1,10 +1,11 @@ #include "bt_type_code.h" #include +#include #include #include #include "../../types/common.h" #include "../../types/token_info.h" -#include "../common.h" +#include "../type_code_common.h" #define HID_BT_KEYS_STORAGE_PATH EXT_PATH("authenticator/.bt_hid.keys") @@ -16,15 +17,15 @@ static inline bool totp_type_code_worker_stop_requested() { static void totp_type_code_worker_bt_set_app_mac(uint8_t* mac) { uint8_t max_i; size_t uid_size = furi_hal_version_uid_size(); - if(uid_size < 6) { + if(uid_size < TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN) { max_i = uid_size; } else { - max_i = 6; + max_i = TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN; } const uint8_t* uid = furi_hal_version_uid(); memcpy(mac, uid, max_i); - for(uint8_t i = max_i; i < 6; i++) { + for(uint8_t i = max_i; i < TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN; i++) { mac[i] = 0; } @@ -39,23 +40,21 @@ static void totp_type_code_worker_type_code(TotpBtTypeCodeWorkerContext* context i++; } while(!context->is_connected && i < 100 && !totp_type_code_worker_stop_requested()); - if(context->is_connected && furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) { + if(context->is_connected && + furi_mutex_acquire(context->code_buffer_sync, 500) == FuriStatusOk) { totp_type_code_worker_execute_automation( &furi_hal_bt_hid_kb_press, &furi_hal_bt_hid_kb_release, - context->string, - context->string_length, + context->code_buffer, + context->code_buffer_size, context->flags); - furi_mutex_release(context->string_sync); + furi_mutex_release(context->code_buffer_sync); } } static int32_t totp_type_code_worker_callback(void* context) { furi_check(context); FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(context_mutex == NULL) { - return 251; - } TotpBtTypeCodeWorkerContext* bt_context = context; @@ -92,13 +91,13 @@ static void connection_status_changed_callback(BtStatus status, void* context) { void totp_bt_type_code_worker_start( TotpBtTypeCodeWorkerContext* context, - char* code_buf, - uint8_t code_buf_length, - FuriMutex* code_buf_update_sync) { + char* code_buffer, + uint8_t code_buffer_size, + FuriMutex* code_buffer_sync) { furi_check(context != NULL); - context->string = code_buf; - context->string_length = code_buf_length; - context->string_sync = code_buf_update_sync; + context->code_buffer = code_buffer; + context->code_buffer_size = code_buffer_size; + context->code_buffer_sync = code_buffer_sync; context->thread = furi_thread_alloc(); furi_thread_set_name(context->thread, "TOTPBtHidWorker"); furi_thread_set_stack_size(context->thread, 1024); @@ -137,7 +136,6 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() { bt_keys_storage_set_storage_path(context->bt, HID_BT_KEYS_STORAGE_PATH); #if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME - totp_type_code_worker_bt_set_app_mac(&context->bt_mac[0]); memcpy( &context->previous_bt_name[0], furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard), @@ -148,8 +146,10 @@ TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init() { TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN); char new_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN]; snprintf(new_name, sizeof(new_name), "%s TOTP Auth", furi_hal_version_get_name_ptr()); + uint8_t new_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN]; + totp_type_code_worker_bt_set_app_mac(new_bt_mac); furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, new_name); - furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, context->bt_mac); + furi_hal_bt_set_profile_mac_addr(FuriHalBtProfileHidKeyboard, new_bt_mac); #endif if(!bt_set_profile(context->bt, BtProfileHidKeyboard)) { diff --git a/applications/external/totp/workers/bt_type_code/bt_type_code.h b/applications/external/totp/workers/bt_type_code/bt_type_code.h index edbe52e14..6c7e502c6 100644 --- a/applications/external/totp/workers/bt_type_code/bt_type_code.h +++ b/applications/external/totp/workers/bt_type_code/bt_type_code.h @@ -1,49 +1,50 @@ #pragma once #include -#include -#include +#include +#include +#include +#include #include #include "../../features_config.h" #if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME -#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN 18 +#define TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH #define TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE #endif typedef uint8_t TotpBtTypeCodeWorkerEvent; typedef struct { - char* string; - uint8_t string_length; + char* code_buffer; + uint8_t code_buffer_size; uint8_t flags; FuriThread* thread; - FuriMutex* string_sync; + FuriMutex* code_buffer_sync; Bt* bt; bool is_advertising; bool is_connected; #if TOTP_TARGET_FIRMWARE == TOTP_FIRMWARE_XTREME - uint8_t bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN]; - char previous_bt_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN + 1]; + char previous_bt_name[TOTP_BT_WORKER_BT_ADV_NAME_MAX_LEN]; uint8_t previous_bt_mac[TOTP_BT_WORKER_BT_MAC_ADDRESS_LEN]; #endif } TotpBtTypeCodeWorkerContext; enum TotpBtTypeCodeWorkerEvents { - TotpBtTypeCodeWorkerEventReserved = 0b0000, - TotpBtTypeCodeWorkerEventStop = 0b0100, - TotpBtTypeCodeWorkerEventType = 0b1000 + TotpBtTypeCodeWorkerEventReserved = 0b00, + TotpBtTypeCodeWorkerEventStop = 0b01, + TotpBtTypeCodeWorkerEventType = 0b10 }; TotpBtTypeCodeWorkerContext* totp_bt_type_code_worker_init(); void totp_bt_type_code_worker_free(TotpBtTypeCodeWorkerContext* context); void totp_bt_type_code_worker_start( TotpBtTypeCodeWorkerContext* context, - char* code_buf, - uint8_t code_buf_length, - FuriMutex* code_buf_update_sync); + char* code_buffer, + uint8_t code_buffer_size, + FuriMutex* code_buffer_sync); void totp_bt_type_code_worker_stop(TotpBtTypeCodeWorkerContext* context); void totp_bt_type_code_worker_notify( TotpBtTypeCodeWorkerContext* context, TotpBtTypeCodeWorkerEvent event, - uint8_t flags); \ No newline at end of file + uint8_t flags); diff --git a/applications/external/totp/workers/generate_totp_code/generate_totp_code.c b/applications/external/totp/workers/generate_totp_code/generate_totp_code.c new file mode 100644 index 000000000..4919cf942 --- /dev/null +++ b/applications/external/totp/workers/generate_totp_code/generate_totp_code.c @@ -0,0 +1,181 @@ +#include "generate_totp_code.h" +#include "../../services/crypto/crypto.h" +#include "../../services/totp/totp.h" +#include "../../services/convert/convert.h" +#include +#include + +#define ONE_SEC_MS (1000) + +static const char* STEAM_ALGO_ALPHABET = "23456789BCDFGHJKMNPQRTVWXY"; + +static void + int_token_to_str(uint64_t i_token_code, char* str, TokenDigitsCount len, TokenHashAlgo algo) { + str[len] = '\0'; + if(i_token_code == OTP_ERROR) { + memset(&str[0], '-', len); + } else { + if(algo == STEAM) { + for(uint8_t i = 0; i < len; i++) { + str[i] = STEAM_ALGO_ALPHABET[i_token_code % 26]; + i_token_code = i_token_code / 26; + } + } else { + for(int8_t i = len - 1; i >= 0; i--) { + str[i] = CONVERT_DIGIT_TO_CHAR(i_token_code % 10); + i_token_code = i_token_code / 10; + } + } + } +} + +static TOTP_ALGO get_totp_algo_impl(TokenHashAlgo algo) { + switch(algo) { + case SHA1: + case STEAM: + return TOTP_ALGO_SHA1; + case SHA256: + return TOTP_ALGO_SHA256; + case SHA512: + return TOTP_ALGO_SHA512; + default: + break; + } + + return NULL; +} + +static void generate_totp_code( + TotpGenerateCodeWorkerContext* context, + const TokenInfo* token_info, + uint32_t current_ts) { + if(token_info->token != NULL && token_info->token_length > 0) { + size_t key_length; + uint8_t* key = totp_crypto_decrypt( + token_info->token, token_info->token_length, context->iv, &key_length); + + int_token_to_str( + totp_at( + get_totp_algo_impl(token_info->algo), + key, + key_length, + current_ts, + context->timezone_offset, + token_info->duration), + context->code_buffer, + token_info->digits, + token_info->algo); + memset_s(key, key_length, 0, key_length); + free(key); + } else { + int_token_to_str(0, context->code_buffer, token_info->digits, token_info->algo); + } +} + +static int32_t totp_generate_worker_callback(void* context) { + furi_check(context); + + TotpGenerateCodeWorkerContext* t_context = context; + + while(true) { + uint32_t flags = furi_thread_flags_wait( + TotpGenerateCodeWorkerEventStop | TotpGenerateCodeWorkerEventForceUpdate, + FuriFlagWaitAny, + ONE_SEC_MS); + + if(flags == + (uint32_t) + FuriFlagErrorTimeout) { // If timeout, consider as no error, as we expect this and can handle gracefully + flags = 0; + } + + furi_check((flags & FuriFlagError) == 0); //-V562 + + if(flags & TotpGenerateCodeWorkerEventStop) break; + + const TokenInfo* token_info = *(t_context->token_info); + if(token_info == NULL) { + continue; + } + + uint32_t curr_ts = furi_hal_rtc_get_timestamp(); + + bool time_left = false; + if(flags & TotpGenerateCodeWorkerEventForceUpdate || + (time_left = (curr_ts % token_info->duration) == 0)) { + if(furi_mutex_acquire(t_context->code_buffer_sync, FuriWaitForever) == FuriStatusOk) { + generate_totp_code(t_context, token_info, curr_ts); + curr_ts = furi_hal_rtc_get_timestamp(); + furi_mutex_release(t_context->code_buffer_sync); + if(t_context->on_new_code_generated_handler != NULL) { + (*(t_context->on_new_code_generated_handler))( + time_left, t_context->on_new_code_generated_handler_context); + } + } + } + + if(t_context->on_code_lifetime_changed_handler != NULL) { + (*(t_context->on_code_lifetime_changed_handler))( + (float)(token_info->duration - curr_ts % token_info->duration) / + (float)token_info->duration, + t_context->on_code_lifetime_changed_handler_context); + } + } + + return 0; +} + +TotpGenerateCodeWorkerContext* totp_generate_code_worker_start( + char* code_buffer, + TokenInfo** token_info, + FuriMutex* code_buffer_sync, + float timezone_offset, + uint8_t* iv) { + TotpGenerateCodeWorkerContext* context = malloc(sizeof(TotpGenerateCodeWorkerContext)); + furi_check(context != NULL); + context->code_buffer = code_buffer; + context->token_info = token_info; + context->code_buffer_sync = code_buffer_sync; + context->timezone_offset = timezone_offset; + context->iv = iv; + context->thread = furi_thread_alloc(); + furi_thread_set_name(context->thread, "TOTPGenerateWorker"); + furi_thread_set_stack_size(context->thread, 2048); + furi_thread_set_context(context->thread, context); + furi_thread_set_callback(context->thread, totp_generate_worker_callback); + furi_thread_start(context->thread); + return context; +} + +void totp_generate_code_worker_stop(TotpGenerateCodeWorkerContext* context) { + furi_check(context != NULL); + furi_thread_flags_set(furi_thread_get_id(context->thread), TotpGenerateCodeWorkerEventStop); + furi_thread_join(context->thread); + furi_thread_free(context->thread); + free(context); +} + +void totp_generate_code_worker_notify( + TotpGenerateCodeWorkerContext* context, + TotpGenerateCodeWorkerEvent event) { + furi_check(context != NULL); + furi_thread_flags_set(furi_thread_get_id(context->thread), event); +} + +void totp_generate_code_worker_set_code_generated_handler( + TotpGenerateCodeWorkerContext* context, + TOTP_NEW_CODE_GENERATED_HANDLER on_new_code_generated_handler, + void* on_new_code_generated_handler_context) { + furi_check(context != NULL); + context->on_new_code_generated_handler = on_new_code_generated_handler; + context->on_new_code_generated_handler_context = on_new_code_generated_handler_context; +} + +void totp_generate_code_worker_set_lifetime_changed_handler( + TotpGenerateCodeWorkerContext* context, + TOTP_CODE_LIFETIME_CHANGED_HANDLER on_code_lifetime_changed_handler, + void* on_code_lifetime_changed_handler_context) { + furi_check(context != NULL); + context->on_code_lifetime_changed_handler = on_code_lifetime_changed_handler; + context->on_code_lifetime_changed_handler_context = on_code_lifetime_changed_handler_context; +} \ No newline at end of file diff --git a/applications/external/totp/workers/generate_totp_code/generate_totp_code.h b/applications/external/totp/workers/generate_totp_code/generate_totp_code.h new file mode 100644 index 000000000..c7a93dc95 --- /dev/null +++ b/applications/external/totp/workers/generate_totp_code/generate_totp_code.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include "../../types/token_info.h" + +typedef uint8_t TotpGenerateCodeWorkerEvent; + +typedef void (*TOTP_NEW_CODE_GENERATED_HANDLER)(bool time_left, void* context); +typedef void (*TOTP_CODE_LIFETIME_CHANGED_HANDLER)(float code_lifetime_percent, void* context); + +typedef struct { + char* code_buffer; + FuriThread* thread; + FuriMutex* code_buffer_sync; + TokenInfo** token_info; + float timezone_offset; + uint8_t* iv; + TOTP_NEW_CODE_GENERATED_HANDLER on_new_code_generated_handler; + void* on_new_code_generated_handler_context; + TOTP_CODE_LIFETIME_CHANGED_HANDLER on_code_lifetime_changed_handler; + void* on_code_lifetime_changed_handler_context; +} TotpGenerateCodeWorkerContext; + +enum TotGenerateCodeWorkerEvents { + TotpGenerateCodeWorkerEventReserved = 0b00, + TotpGenerateCodeWorkerEventStop = 0b01, + TotpGenerateCodeWorkerEventForceUpdate = 0b10 +}; + +TotpGenerateCodeWorkerContext* totp_generate_code_worker_start( + char* code_buffer, + TokenInfo** token_info, + FuriMutex* code_buffer_sync, + float timezone_offset, + uint8_t* iv); +void totp_generate_code_worker_stop(TotpGenerateCodeWorkerContext* context); +void totp_generate_code_worker_notify( + TotpGenerateCodeWorkerContext* context, + TotpGenerateCodeWorkerEvent event); +void totp_generate_code_worker_set_code_generated_handler( + TotpGenerateCodeWorkerContext* context, + TOTP_NEW_CODE_GENERATED_HANDLER on_new_code_generated_handler, + void* on_new_code_generated_handler_context); +void totp_generate_code_worker_set_lifetime_changed_handler( + TotpGenerateCodeWorkerContext* context, + TOTP_CODE_LIFETIME_CHANGED_HANDLER on_code_lifetime_changed_handler, + void* on_code_lifetime_changed_handler_context); \ No newline at end of file diff --git a/applications/external/totp/workers/common.c b/applications/external/totp/workers/type_code_common.c similarity index 88% rename from applications/external/totp/workers/common.c rename to applications/external/totp/workers/type_code_common.c index 8ad0c2b46..fa5e7290f 100644 --- a/applications/external/totp/workers/common.c +++ b/applications/external/totp/workers/type_code_common.c @@ -1,6 +1,6 @@ -#include "common.h" -#include -#include +#include "type_code_common.h" +#include +#include #include "../../services/convert/convert.h" static const uint8_t hid_number_keys[] = { @@ -42,18 +42,18 @@ static void totp_type_code_worker_press_key( void totp_type_code_worker_execute_automation( TOTP_AUTOMATION_KEY_HANDLER key_press_fn, TOTP_AUTOMATION_KEY_HANDLER key_release_fn, - const char* string, - uint8_t string_length, + const char* code_buffer, + uint8_t code_buffer_size, TokenAutomationFeature features) { furi_delay_ms(500); uint8_t i = 0; totp_type_code_worker_press_key( HID_KEYBOARD_CAPS_LOCK, key_press_fn, key_release_fn, features); - while(i < string_length && string[i] != 0) { - uint8_t char_index = CONVERT_CHAR_TO_DIGIT(string[i]); + while(i < code_buffer_size && code_buffer[i] != 0) { + uint8_t char_index = CONVERT_CHAR_TO_DIGIT(code_buffer[i]); if(char_index > 9) { - char_index = string[i] - 0x41 + 10; + char_index = code_buffer[i] - 0x41 + 10; } if(char_index > 35) break; diff --git a/applications/external/totp/workers/common.h b/applications/external/totp/workers/type_code_common.h similarity index 83% rename from applications/external/totp/workers/common.h rename to applications/external/totp/workers/type_code_common.h index 5e3a2006e..1516928cf 100644 --- a/applications/external/totp/workers/common.h +++ b/applications/external/totp/workers/type_code_common.h @@ -7,6 +7,6 @@ typedef bool (*TOTP_AUTOMATION_KEY_HANDLER)(uint16_t key); void totp_type_code_worker_execute_automation( TOTP_AUTOMATION_KEY_HANDLER key_press_fn, TOTP_AUTOMATION_KEY_HANDLER key_release_fn, - const char* string, - uint8_t string_length, + const char* code_buffer, + uint8_t code_buffer_size, TokenAutomationFeature features); \ No newline at end of file diff --git a/applications/external/totp/workers/usb_type_code/usb_type_code.c b/applications/external/totp/workers/usb_type_code/usb_type_code.c index 5f7ccddf8..10034907d 100644 --- a/applications/external/totp/workers/usb_type_code/usb_type_code.c +++ b/applications/external/totp/workers/usb_type_code/usb_type_code.c @@ -1,7 +1,8 @@ #include "usb_type_code.h" +#include #include "../../services/convert/convert.h" #include "../../types/token_info.h" -#include "../common.h" +#include "../type_code_common.h" static void totp_type_code_worker_restore_usb_mode(TotpUsbTypeCodeWorkerContext* context) { if(context->usb_mode_prev != NULL) { @@ -25,14 +26,14 @@ static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* contex } while(!furi_hal_hid_is_connected() && i < 100 && !totp_type_code_worker_stop_requested()); if(furi_hal_hid_is_connected() && - furi_mutex_acquire(context->string_sync, 500) == FuriStatusOk) { + furi_mutex_acquire(context->code_buffer_sync, 500) == FuriStatusOk) { totp_type_code_worker_execute_automation( &furi_hal_hid_kb_press, &furi_hal_hid_kb_release, - context->string, - context->string_length, + context->code_buffer, + context->code_buffer_size, context->flags); - furi_mutex_release(context->string_sync); + furi_mutex_release(context->code_buffer_sync); furi_delay_ms(100); } @@ -43,9 +44,6 @@ static void totp_type_code_worker_type_code(TotpUsbTypeCodeWorkerContext* contex static int32_t totp_type_code_worker_callback(void* context) { furi_check(context); FuriMutex* context_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(context_mutex == NULL) { - return 251; - } while(true) { uint32_t flags = furi_thread_flags_wait( @@ -70,14 +68,14 @@ static int32_t totp_type_code_worker_callback(void* context) { } TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start( - char* code_buf, - uint8_t code_buf_length, - FuriMutex* code_buf_update_sync) { + char* code_buffer, + uint8_t code_buffer_size, + FuriMutex* code_buffer_sync) { TotpUsbTypeCodeWorkerContext* context = malloc(sizeof(TotpUsbTypeCodeWorkerContext)); furi_check(context != NULL); - context->string = code_buf; - context->string_length = code_buf_length; - context->string_sync = code_buf_update_sync; + context->code_buffer = code_buffer; + context->code_buffer_size = code_buffer_size; + context->code_buffer_sync = code_buffer_sync; context->thread = furi_thread_alloc(); context->usb_mode_prev = NULL; furi_thread_set_name(context->thread, "TOTPUsbHidWorker"); diff --git a/applications/external/totp/workers/usb_type_code/usb_type_code.h b/applications/external/totp/workers/usb_type_code/usb_type_code.h index d0ea600ce..21213f4d4 100644 --- a/applications/external/totp/workers/usb_type_code/usb_type_code.h +++ b/applications/external/totp/workers/usb_type_code/usb_type_code.h @@ -1,17 +1,20 @@ #pragma once #include -#include -#include +#include +#include +#include +#include +#include typedef uint8_t TotpUsbTypeCodeWorkerEvent; typedef struct { - char* string; - uint8_t string_length; + char* code_buffer; + uint8_t code_buffer_size; uint8_t flags; FuriThread* thread; - FuriMutex* string_sync; + FuriMutex* code_buffer_sync; FuriHalUsbInterface* usb_mode_prev; } TotpUsbTypeCodeWorkerContext; @@ -22,9 +25,9 @@ enum TotpUsbTypeCodeWorkerEvents { }; TotpUsbTypeCodeWorkerContext* totp_usb_type_code_worker_start( - char* code_buf, - uint8_t code_buf_length, - FuriMutex* code_buf_update_sync); + char* code_buffer, + uint8_t code_buffer_size, + FuriMutex* code_buffer_sync); void totp_usb_type_code_worker_stop(TotpUsbTypeCodeWorkerContext* context); void totp_usb_type_code_worker_notify( TotpUsbTypeCodeWorkerContext* context, From 7922e3bb16086391f98e3e4241d277e0745f1331 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Apr 2023 00:09:48 +0300 Subject: [PATCH 18/22] docs and changelogs --- CHANGELOG.md | 28 ++++++++++++++-------------- ReadMe.md | 4 ++-- documentation/HowToBuild.md | 18 +++++++++++++----- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63d36c013..21134f6a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,18 @@ ### New changes -* **SubGHz: Keyboard lock fixed** -### Previous changes -* SubGHz: AN-Motors AT4 - Add manually fixes -* SubGHz: StarLine ignore option (in Read -> Config) (by @gid9798 | PR #410) -* Plugins: Fix `Repeat: 200` bug in SubGHz Remote and Bruteforcer -* Plugins: Update **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) (Steam guard support) -* Plugins: Update **UART Terminal** [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main) (AT commands support) -* Plugins: Add IR Scope app. (by @kallanreed | PR #407) -* OFW: scripts: sconsdist: added stub file artifact for older ufbt -* OFW: Graphics cleanup and icon rotation -* OFW: Moved ufbt to fbt codebase -* OFW: SD Driver: do not cache sd status. -* OFW: Furi: more gpio checks in HAL -* OFW: WeatherStation: fix protocol TX141TH-BV2 +* If you have copied apps into `apps` folder - remove `apps` folder on your microSD before installing this release to avoid issues! +* SubGHz: (Bug that I decided to keep as a feature) You can change default button (Ok) for remote by holding custom button and pressing back at same time (same can be used to restore your button if you changed it accidentally) - Be careful, it might be unstable, I will make proper option to change button in next releases +* SubGHz: Fixes for custom button bugs in SubGHz Remote app +* SubGHz: Add alutech table to enviroment alloc and free +* Plugins: Update **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) +* Plugins: Update **UART Terminal** [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main) +* OFW: Deep Sleep Idle - **Improves battery usage!!!** +* OFW: FuriHal: pwr pulls for some pins +* OFW: Bugfix: ISP Programmer and SubGhz +* OFW: AVR_ISP: fix NULL pointer dereference +* OFW: Fix gpio state isp programmer +* OFW: ufbt: project & debugging updates +* OFW: FuriHal: fix gpio naming and add explicit pulls for vibro, speaker and ir_tx -> **Breaking API change, api was changed from 20.x to 21.x** +**(this will make your manually copied plugins not work, update them in same way you installed them, or delete `apps` folder and then install firmware, if you using extra pack builds (with `e` in version) all apps in _Extra will be updated automatically)** #### [🎲 Download latest extra apps pack](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip) diff --git a/ReadMe.md b/ReadMe.md index dbe0e5bb6..ec188293d 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -10,7 +10,7 @@
-Our goal is to make all features possible on this device without any limitations! +Most stable custom firmware focused on new features and improvements of original firmware components, with almost no UI changes
@@ -103,7 +103,7 @@ Encoders made by @assasinfil & @xMasterX: ## Please support development of the project The majority of this project is developed and maintained by me, @xMasterX. -I'm unemployed because of the war, and the only income I receive is from your donations. +I'm unemployed, and the only income I receive is from your donations. Our team is small and the guys are working on this project as much as they can solely based on the enthusiasm they have for this project and the community. - @assasinfil - SubGHz - @Svaarich - UI design and animations diff --git a/documentation/HowToBuild.md b/documentation/HowToBuild.md index 92bd4e418..bc0084e9a 100644 --- a/documentation/HowToBuild.md +++ b/documentation/HowToBuild.md @@ -7,7 +7,6 @@ For development: - Git -- Python3 - VSCode ## Clone the Repository @@ -16,15 +15,24 @@ You should clone with ```shell $ git clone --recursive https://github.com/DarkFlippers/unleashed-firmware.git ``` +## VSCode integration + +`fbt` includes basic development environment configuration for VS Code. Run `./fbt vscode_dist` to deploy it. That will copy the initial environment configuration to the `.vscode` folder. After that, you can use that configuration by starting VS Code and choosing the firmware root folder in the "File > Open Folder" menu. # Build on Linux/macOS Check out `documentation/fbt.md` for details on building and flashing firmware. +### Compile plugin and run it on connected flipper + +```sh +./fbt COMPACT=1 DEBUG=0 launch_app APPSRC=applications_user/yourplugin +``` + ### Compile everything for development ```sh -./fbt +./fbt FIRMWARE_APP_SET=debug_pack updater_package ``` ### Compile everything for release + get updater package to update from microSD card @@ -35,7 +43,7 @@ Check out `documentation/fbt.md` for details on building and flashing firmware. Check `dist/` for build outputs. -Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device. +Use **`flipper-z-{target}-update-{suffix}.tgz`** to flash your device. # Build on Windows @@ -45,7 +53,7 @@ Check out `documentation/fbt.md` for details on building and flashing firmware. ### Compile everything for development ```sh -.\fbt.cmd +.\fbt.cmd FIRMWARE_APP_SET=debug_pack updater_package ``` ### Compile everything for release + get updater package to update from microSD card @@ -56,7 +64,7 @@ Check out `documentation/fbt.md` for details on building and flashing firmware. Check `dist/` for build outputs. -Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device. +Use **`flipper-z-{target}-update-{suffix}.tgz`** to flash your device. From 21b7df9ab7ed7ded6f9672a96714b2fe190a6bfb Mon Sep 17 00:00:00 2001 From: ushastoe Date: Fri, 14 Apr 2023 01:59:16 +0300 Subject: [PATCH 19/22] refactoring -fix TikTok Controller -fix icon in Mouse --- .../hid_app/assets/Pause_icon_9x9.png | Bin 0 -> 4559 bytes .../external/hid_app/views/hid_mouse.c | 18 ++++-- .../external/hid_app/views/hid_tiktok.c | 52 ++++++++++++------ 3 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 applications/external/hid_app/assets/Pause_icon_9x9.png diff --git a/applications/external/hid_app/assets/Pause_icon_9x9.png b/applications/external/hid_app/assets/Pause_icon_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..d72d712bbaa47429793bddbab0096de8d95045b4 GIT binary patch literal 4559 zcmb_e2{@Ep`+qDIilk5^(>)X17qL}Ra%XJ#G@vo$l8QAvw7WeLfeqNIjW zie#%4Ws9Ohkt_)zA(8&iw0OVoyWaPIz1Merb6wAz^PF?vzw^8A`*+THjyr6zR#ebX z002PIhGI#DTY1SNCj+Qy;zF6J+Xa^qPC0Hlssu2R|kg7RqqJglr@`Y`O6g3BV+ z1<4fW@`H^El$2u~X{!pn%}yNK7Vf-*@KL)p^VYuL!GVFv7n4Oj$vsoGqPqE^3siKY zyD#_xL~7W2(o5|~drJA^;!tT-O1msVxx4DV_pFBiFeD=i3K3r4FeP=33rGXJM*S5k z6>q;EDs<3w1rX6dJ5r@*u2d8isML3=Tm)1u2Ch5aWGDc!0KgLMHAezh6oLNFHYT%x zmsv5b>cGnjOS9yFQ&K>}D(e-}rgs5P=L1wd>9YGkn%ESnFI$!)73zK)XDuCCJPQbj zaEqF6>IsA4bxECp0$e?RzQ&g%BtdO;x{)KEGme5suB2U zsJ&x($9-0=IjFu`*-O3?nH-;_vyjpwV_Q2905m4*?@bdnMD=uczU}tvVGVwMcwyRa zh>J8?KHN54bW&OtP~K8E*u1N&t4W4eA$8rq)Gup0(Ch;Ev`u&zw8*DzQ+OIY5iTN3 znJ!B`?@+m3YpKHAxdSU{=Zi7#!cD##yydoshm66q(=EY6!0trTgzU2PL*I6ToPZo^ zL{F8hIhHftqcdF*w*Oni>iQ0R?hZZG6T@!D3mlMk6{0)TXv^h~<2qD&_v41O&wP`Q z2~-5cN9@bC+@5o*id7c!QA#>o$*my(Fbx?&oz$2c4Jdo#aiVbmh$)?jG+iqN)Wm1J z1AwCUi+5a(RkwX42LP672i9CSn=|j;B5|2g@;$AhGIeQiwx#L36=my{&1ZLpE>$?c z_>9>Sr!vw@*<06TG}0C%zE#e89DU!h0OZR@BM|qz7rAj(0Z(r z*U4Alj*~~NJde9+=vJuFyW9+2A`R(UZpHzsnq{frpxg@S@X&?*ayt(z-)9|+in4aI zb+fpx*wM>Tb{ad=O0Q7cg0Xv zC_O&ixkX|5$|#)8TpK@13k8+om|@bO%uKe`?TcbRe$y#;BUFrtkIs*pA7y`f^6`Vt z{6(aP$2x4~FRY+u#HwsEgf?`^UOb00Pe{A6wI(a|x!jdwq;uPB*l7U{Xvd>j3-SJm zD{GR}EUGe4>5WelncmECA9Sy{X3^q7p}nbBPOy>$&3OEO6e? zD7rG&>8kVmt2(LNQb(uyV6T`eLMJ-u6W}} z*v7OYlyoP0{-Y(Qma9F&LBnq5O?(%bK0Uv)cC_s`Ci-myW=(1ap!e81S_rOqiM^t| zQo487NGUzaZ66}OO5RkvyjHPx4@w5L0hQb2o9&eyl5N}^++5O38{iM94fHh+`twpu zQ}j|sNo>-%zkH!l;nu>i!WRF!4<^s(eWG6Z(I=xyy|3%7N7yjDp>NWsAcL@*hQ=4 zhnvEU!Yj@+pV?bA>x|u*aq(Ff6Bm)osLKnnP1BA(y*_r6E6YLCHECWFDXHrAP{;MmGB_E?=(^->kBrgg$~d-+2D>Hrq6 zs4wF!{y|oG)`MPGZ%yy>f|Lo(Hr#qPnx1qw zsWtl*`}yl?^22>sC++l;G#`6BAP<^-9vXM+*j@cDB{M1W{zz00dS}2+_nni)%j|C^ z>!vng*p)5i+uMt)_IQ#^$k5l?UKx`|Cer7E&mAqfRDx_Hm*|8vg(QT`nM$2p_qFO< zg3v#L%5eFYA| zA?&P5{EZD=hY;ot=*9M3nH)QRM6slGAr|M(kWHo8E})UhRH`BE}}iCZ|&snP>9WzQE+K%D4AgyEaC# zQ`F6Vq8W4a$#|#EgkYpal@(@NpPom}aZpmTMPFVUw0-gRpaM!UW!rOuHm~Uq6FPGb zs_iX~y6#YL{pQPpAot;RWU19%HJxxr^+0{B2ept9#2jkaSLIW6ODT)t&r%`bVS+uT(8I&ja3(jhI?b#De^`-^U^ z4RZA>w%Rw!Y4~{Xb)*JOv#_)~IQY;N89{eIa|g|LR-TD0uPZg}%o*QSsoTe$9N2?(3xmD+@=z1dI)+2P%BD zZS@F_47xT|(){hioUijg?9ZFdh056NUp&h^>mInzA5@Y*nmQf({n^pC4c67xjXE23 zPDQ3@YilZM6n|pW#=OnEk-4z$Nr=mLQJ>&yPusVS$<1|cQ!j_+PK4K$=7_RJ_=8uo zu8}HqDzuAgMdaa2Q`xmG`vwaJ3)?D+wG&oNnNB;5)PJQ{WInYYH|g0sJ%t`WJTi&0 zCe*AdC7%a*TWO?4z^BKa626W zd=CM-$k$Fw26+^B0RYThD0!rS#N@>QF#9~y$xY~HXG@}U+4>-ZOM~=-*gV)80M>5^ z;(>HONQj_8-b@Y|Ie51eiC{9wNLNEUj2+Jc@?lbf`H*Aq7AJbJADzfRZZJWt4>LmlTt0*#>SIuJ3iVmmUI#!Qs#t0vcqnXxbTq_**sz%ZjtV=&ljp+~as@uz zze&Q(^h_#vBnv(S3b}kIE|>MY%nrX%5I6&UEMk=%NM~{+xT_^0{c?dUK_Ns&!bLYg zVelv{&IxNk!WfYZ@M|$}2lLa^j>}+riT=YB?}WjUuvn6T(Z89(l4F2E@Shml*^z8G z0wKtuLpGLVBuq-5$z+fiSjZU9z++H&JRN3bgojWd7KcGGj17qxF9O}z$dLYn7wm7z zrTa?~DDnR(dj^*dW6b1;M8q1v{uNciiUA{95V3d*BLV@7*@(wttt`zfEePh8ICBeQoB@`IGe#m9bdndB&jw+Y zFxj9tgywO)k%&K;Sa4ZfKAcKPz9kz0MwUbX@tFY-V?4D z7mj`=AOFGJ=x=?|Gh`@C0jwg?uYK+a?f%tcF=1}7{z)KRvS-Oi0SI$O{u=x%!VCfq z1hEEivO!}*6o|(gp@@(d4u$ukVL=8Biy_kBBK`yo^nqZ=84dmr7OX7;!f#>yG!t;W zgn=L*GV_KD{ue68OH}U4tF(yOGazBvY-eDJ=xt?4$Y{_T8~^|S literal 0 HcmV?d00001 diff --git a/applications/external/hid_app/views/hid_mouse.c b/applications/external/hid_app/views/hid_mouse.c index 30a9d9d06..ca299c463 100644 --- a/applications/external/hid_app/views/hid_mouse.c +++ b/applications/external/hid_app/views/hid_mouse.c @@ -93,17 +93,23 @@ static void hid_mouse_draw_callback(Canvas* canvas, void* context) { // Ok if(model->left_mouse_pressed) { - canvas_draw_icon(canvas, 81, 25, &I_Ok_btn_pressed_13x13); - } else { - canvas_draw_icon(canvas, 83, 27, &I_Left_mouse_icon_9x9); + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 81, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); } + canvas_draw_icon(canvas, 83, 27, &I_Left_mouse_icon_9x9); + canvas_set_color(canvas, ColorBlack); // Back if(model->right_mouse_pressed) { - canvas_draw_icon(canvas, 108, 48, &I_Ok_btn_pressed_13x13); - } else { - canvas_draw_icon(canvas, 110, 50, &I_Right_mouse_icon_9x9); + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 108, 48, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); } + canvas_draw_icon(canvas, 110, 50, &I_Right_mouse_icon_9x9); + canvas_set_color(canvas, ColorBlack); } static void hid_mouse_process(HidMouse* hid_mouse, InputEvent* event) { diff --git a/applications/external/hid_app/views/hid_tiktok.c b/applications/external/hid_app/views/hid_tiktok.c index e1f9f4bed..d3cf4a110 100644 --- a/applications/external/hid_app/views/hid_tiktok.c +++ b/applications/external/hid_app/views/hid_tiktok.c @@ -19,6 +19,7 @@ typedef struct { bool ok_pressed; bool connected; bool is_cursor_set; + bool back_mouse_pressed; HidTransport transport; } HidTikTokModel; @@ -40,53 +41,63 @@ static void hid_tiktok_draw_callback(Canvas* canvas, void* context) { canvas_set_font(canvas, FontSecondary); // Keypad circles - canvas_draw_icon(canvas, 76, 8, &I_Circles_47x47); + canvas_draw_icon(canvas, 66, 8, &I_Circles_47x47); + + // Pause + if(model->back_mouse_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 106, 46, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 108, 48, &I_Pause_icon_9x9); + canvas_set_color(canvas, ColorBlack); // Up if(model->up_pressed) { canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13); + canvas_draw_icon(canvas, 83, 9, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, 0); canvas_set_color(canvas, ColorWhite); } - canvas_draw_icon(canvas, 96, 11, &I_Arr_up_7x9); + canvas_draw_icon(canvas, 86, 11, &I_Arr_up_7x9); canvas_set_color(canvas, ColorBlack); // Down if(model->down_pressed) { canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13); + canvas_draw_icon(canvas, 83, 41, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, 0); canvas_set_color(canvas, ColorWhite); } - canvas_draw_icon(canvas, 96, 44, &I_Arr_dwn_7x9); + canvas_draw_icon(canvas, 86, 44, &I_Arr_dwn_7x9); canvas_set_color(canvas, ColorBlack); // Left if(model->left_pressed) { canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13); + canvas_draw_icon(canvas, 67, 25, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, 0); canvas_set_color(canvas, ColorWhite); } - canvas_draw_icon(canvas, 81, 29, &I_Voldwn_6x6); + canvas_draw_icon(canvas, 71, 29, &I_Voldwn_6x6); canvas_set_color(canvas, ColorBlack); // Right if(model->right_pressed) { canvas_set_bitmap_mode(canvas, 1); - canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13); + canvas_draw_icon(canvas, 99, 25, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, 0); canvas_set_color(canvas, ColorWhite); } - canvas_draw_icon(canvas, 111, 29, &I_Volup_8x6); + canvas_draw_icon(canvas, 101, 29, &I_Volup_8x6); canvas_set_color(canvas, ColorBlack); // Ok if(model->ok_pressed) { - canvas_draw_icon(canvas, 91, 23, &I_Like_pressed_17x17); + canvas_draw_icon(canvas, 81, 23, &I_Like_pressed_17x17); } else { - canvas_draw_icon(canvas, 94, 27, &I_Like_def_11x9); + canvas_draw_icon(canvas, 84, 27, &I_Like_def_11x9); } // Exit canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); @@ -102,7 +113,8 @@ static void hid_tiktok_reset_cursor(HidTikTok* hid_tiktok) { furi_delay_ms(50); } // Move cursor from the corner - hid_hal_mouse_move(hid_tiktok->hid, 20, 120); + hid_hal_mouse_move(hid_tiktok->hid, 40, 120); + hid_hal_mouse_move(hid_tiktok->hid, 0, 120); furi_delay_ms(50); } @@ -120,6 +132,8 @@ static void hid_hal_consumer_key_press(hid_tiktok->hid, HID_CONSUMER_VOLUME_INCREMENT); } else if(event->key == InputKeyOk) { model->ok_pressed = true; + } else if(event->key == InputKeyBack) { + model->back_mouse_pressed = true; } } @@ -137,6 +151,8 @@ static void hid_hal_consumer_key_release(hid_tiktok->hid, HID_CONSUMER_VOLUME_INCREMENT); } else if(event->key == InputKeyOk) { model->ok_pressed = false; + } else if(event->key == InputKeyBack) { + model->back_mouse_pressed = false; } } @@ -169,16 +185,16 @@ static bool hid_tiktok_input_callback(InputEvent* event, void* context) { furi_delay_ms(50); hid_hal_mouse_release(hid_tiktok->hid, HID_MOUSE_BTN_LEFT); consumed = true; - } else if(event->key == InputKeyUp) { - // Emulate up swipe + } else if(event->key == InputKeyDown) { + // Swipe to new video hid_hal_mouse_scroll(hid_tiktok->hid, -6); hid_hal_mouse_scroll(hid_tiktok->hid, -12); hid_hal_mouse_scroll(hid_tiktok->hid, -19); hid_hal_mouse_scroll(hid_tiktok->hid, -12); hid_hal_mouse_scroll(hid_tiktok->hid, -6); consumed = true; - } else if(event->key == InputKeyDown) { - // Emulate down swipe + } else if(event->key == InputKeyUp) { + // Swipe to previous video hid_hal_mouse_scroll(hid_tiktok->hid, 6); hid_hal_mouse_scroll(hid_tiktok->hid, 12); hid_hal_mouse_scroll(hid_tiktok->hid, 19); @@ -186,7 +202,9 @@ static bool hid_tiktok_input_callback(InputEvent* event, void* context) { hid_hal_mouse_scroll(hid_tiktok->hid, 6); consumed = true; } else if(event->key == InputKeyBack) { - hid_hal_consumer_key_release_all(hid_tiktok->hid); + // Pause + hid_hal_mouse_press(hid_tiktok->hid, HID_MOUSE_BTN_RIGHT); + hid_hal_mouse_release(hid_tiktok->hid, HID_MOUSE_BTN_RIGHT); consumed = true; } } else if(event->type == InputTypeLong) { From 3191b327084b464685257426339e48e24c48e7f6 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Apr 2023 03:35:42 +0300 Subject: [PATCH 20/22] Youtube shorts remote, swap tiktok control buttons --- applications/external/hid_app/hid.c | 19 ++ applications/external/hid_app/hid.h | 2 + applications/external/hid_app/views.h | 1 + .../external/hid_app/views/hid_tiktok.c | 16 +- .../external/hid_app/views/hid_ytshorts.c | 268 ++++++++++++++++++ .../external/hid_app/views/hid_ytshorts.h | 14 + 6 files changed, 312 insertions(+), 8 deletions(-) create mode 100644 applications/external/hid_app/views/hid_ytshorts.c create mode 100644 applications/external/hid_app/views/hid_ytshorts.h diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c index 949ff63b3..b679c395c 100644 --- a/applications/external/hid_app/hid.c +++ b/applications/external/hid_app/hid.c @@ -10,6 +10,7 @@ enum HidDebugSubmenuIndex { HidSubmenuIndexKeyboard, HidSubmenuIndexMedia, HidSubmenuIndexTikTok, + HidSubmenuIndexYTShorts, HidSubmenuIndexMouse, 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 == HidSubmenuIndexYTShorts) { + app->view_id = BtHidViewYTShorts; + view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewYTShorts); } else if(index == HidSubmenuIndexMouseJiggler) { app->view_id = HidViewMouseJiggler; view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMouseJiggler); @@ -55,6 +59,7 @@ static void bt_hid_connection_status_changed_callback(BtStatus status, void* con hid_mouse_set_connected_status(hid->hid_mouse, connected); hid_mouse_jiggler_set_connected_status(hid->hid_mouse_jiggler, connected); hid_tiktok_set_connected_status(hid->hid_tiktok, connected); + hid_ytshorts_set_connected_status(hid->hid_ytshorts, connected); } static void hid_dialog_callback(DialogExResult result, void* context) { @@ -113,6 +118,12 @@ Hid* hid_alloc(HidTransport transport) { HidSubmenuIndexTikTok, hid_submenu_callback, app); + submenu_add_item( + app->device_type_submenu, + "YT Shorts Controller", + HidSubmenuIndexYTShorts, + hid_submenu_callback, + app); } submenu_add_item( app->device_type_submenu, @@ -166,6 +177,12 @@ Hid* hid_app_alloc_view(void* context) { view_dispatcher_add_view( app->view_dispatcher, BtHidViewTikTok, hid_tiktok_get_view(app->hid_tiktok)); + // YTShorts view + app->hid_ytshorts = hid_ytshorts_alloc(app); + view_set_previous_callback(hid_ytshorts_get_view(app->hid_ytshorts), hid_exit_confirm_view); + view_dispatcher_add_view( + app->view_dispatcher, BtHidViewYTShorts, hid_ytshorts_get_view(app->hid_ytshorts)); + // Mouse view app->hid_mouse = hid_mouse_alloc(app); view_set_previous_callback(hid_mouse_get_view(app->hid_mouse), hid_exit_confirm_view); @@ -209,6 +226,8 @@ void hid_free(Hid* app) { hid_mouse_jiggler_free(app->hid_mouse_jiggler); view_dispatcher_remove_view(app->view_dispatcher, BtHidViewTikTok); hid_tiktok_free(app->hid_tiktok); + view_dispatcher_remove_view(app->view_dispatcher, BtHidViewYTShorts); + hid_ytshorts_free(app->hid_ytshorts); view_dispatcher_free(app->view_dispatcher); // Close records diff --git a/applications/external/hid_app/hid.h b/applications/external/hid_app/hid.h index 8ed1664a3..1ff42c940 100644 --- a/applications/external/hid_app/hid.h +++ b/applications/external/hid_app/hid.h @@ -22,6 +22,7 @@ #include "views/hid_mouse.h" #include "views/hid_mouse_jiggler.h" #include "views/hid_tiktok.h" +#include "views/hid_ytshorts.h" #define HID_BT_KEYS_STORAGE_NAME ".bt_hid.keys" @@ -45,6 +46,7 @@ struct Hid { HidMouse* hid_mouse; HidMouseJiggler* hid_mouse_jiggler; HidTikTok* hid_tiktok; + HidYTShorts* hid_ytshorts; HidTransport transport; uint32_t view_id; diff --git a/applications/external/hid_app/views.h b/applications/external/hid_app/views.h index 2a44832e1..14cfa126f 100644 --- a/applications/external/hid_app/views.h +++ b/applications/external/hid_app/views.h @@ -6,5 +6,6 @@ typedef enum { HidViewMouse, HidViewMouseJiggler, BtHidViewTikTok, + BtHidViewYTShorts, HidViewExitConfirm, } HidView; \ No newline at end of file diff --git a/applications/external/hid_app/views/hid_tiktok.c b/applications/external/hid_app/views/hid_tiktok.c index d3cf4a110..3b48d32cb 100644 --- a/applications/external/hid_app/views/hid_tiktok.c +++ b/applications/external/hid_app/views/hid_tiktok.c @@ -187,20 +187,20 @@ static bool hid_tiktok_input_callback(InputEvent* event, void* context) { consumed = true; } else if(event->key == InputKeyDown) { // Swipe to new video - hid_hal_mouse_scroll(hid_tiktok->hid, -6); - hid_hal_mouse_scroll(hid_tiktok->hid, -12); - hid_hal_mouse_scroll(hid_tiktok->hid, -19); - hid_hal_mouse_scroll(hid_tiktok->hid, -12); - hid_hal_mouse_scroll(hid_tiktok->hid, -6); - consumed = true; - } else if(event->key == InputKeyUp) { - // Swipe to previous video hid_hal_mouse_scroll(hid_tiktok->hid, 6); hid_hal_mouse_scroll(hid_tiktok->hid, 12); hid_hal_mouse_scroll(hid_tiktok->hid, 19); hid_hal_mouse_scroll(hid_tiktok->hid, 12); hid_hal_mouse_scroll(hid_tiktok->hid, 6); consumed = true; + } else if(event->key == InputKeyUp) { + // Swipe to previous video + hid_hal_mouse_scroll(hid_tiktok->hid, -6); + hid_hal_mouse_scroll(hid_tiktok->hid, -12); + hid_hal_mouse_scroll(hid_tiktok->hid, -19); + hid_hal_mouse_scroll(hid_tiktok->hid, -12); + hid_hal_mouse_scroll(hid_tiktok->hid, -6); + consumed = true; } else if(event->key == InputKeyBack) { // Pause hid_hal_mouse_press(hid_tiktok->hid, HID_MOUSE_BTN_RIGHT); diff --git a/applications/external/hid_app/views/hid_ytshorts.c b/applications/external/hid_app/views/hid_ytshorts.c new file mode 100644 index 000000000..44ad02ff0 --- /dev/null +++ b/applications/external/hid_app/views/hid_ytshorts.c @@ -0,0 +1,268 @@ +#include "hid_ytshorts.h" +#include "../hid.h" +#include + +#include "hid_icons.h" + +#define TAG "HidYTShorts" + +struct HidYTShorts { + View* view; + Hid* hid; +}; + +typedef struct { + bool left_pressed; + bool up_pressed; + bool right_pressed; + bool down_pressed; + bool ok_pressed; + bool connected; + bool is_cursor_set; + bool back_mouse_pressed; + HidTransport transport; +} HidYTShortsModel; + +static void hid_ytshorts_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + HidYTShortsModel* 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, "Shorts"); + canvas_set_font(canvas, FontSecondary); + + // Keypad circles + canvas_draw_icon(canvas, 66, 8, &I_Circles_47x47); + + // Pause + if(model->back_mouse_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 106, 46, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 108, 48, &I_Pause_icon_9x9); + canvas_set_color(canvas, ColorBlack); + + // Up + if(model->up_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 83, 9, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 86, 11, &I_Arr_up_7x9); + canvas_set_color(canvas, ColorBlack); + + // Down + if(model->down_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 83, 41, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 86, 44, &I_Arr_dwn_7x9); + canvas_set_color(canvas, ColorBlack); + + // Left + if(model->left_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 67, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 71, 29, &I_Voldwn_6x6); + canvas_set_color(canvas, ColorBlack); + + // Right + if(model->right_pressed) { + canvas_set_bitmap_mode(canvas, 1); + canvas_draw_icon(canvas, 99, 25, &I_Pressed_Button_13x13); + canvas_set_bitmap_mode(canvas, 0); + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_icon(canvas, 101, 29, &I_Volup_8x6); + canvas_set_color(canvas, ColorBlack); + + // Ok + if(model->ok_pressed) { + canvas_draw_icon(canvas, 81, 23, &I_Like_pressed_17x17); + } else { + canvas_draw_icon(canvas, 84, 27, &I_Like_def_11x9); + } + // Exit + canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8); + canvas_set_font(canvas, FontSecondary); + elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); +} + +static void hid_ytshorts_reset_cursor(HidYTShorts* hid_ytshorts) { + // Set cursor to the phone's left up corner + // Delays to guarantee one packet per connection interval + for(size_t i = 0; i < 8; i++) { + hid_hal_mouse_move(hid_ytshorts->hid, -127, -127); + furi_delay_ms(50); + } + // Move cursor from the corner + hid_hal_mouse_move(hid_ytshorts->hid, 40, 120); + hid_hal_mouse_move(hid_ytshorts->hid, 0, 120); + furi_delay_ms(50); +} + +static void hid_ytshorts_process_press( + HidYTShorts* hid_ytshorts, + HidYTShortsModel* model, + InputEvent* event) { + if(event->key == InputKeyUp) { + model->up_pressed = true; + } else if(event->key == InputKeyDown) { + model->down_pressed = true; + } else if(event->key == InputKeyLeft) { + model->left_pressed = true; + hid_hal_consumer_key_press(hid_ytshorts->hid, HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = true; + hid_hal_consumer_key_press(hid_ytshorts->hid, HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = true; + } else if(event->key == InputKeyBack) { + model->back_mouse_pressed = true; + } +} + +static void hid_ytshorts_process_release( + HidYTShorts* hid_ytshorts, + HidYTShortsModel* model, + InputEvent* event) { + if(event->key == InputKeyUp) { + model->up_pressed = false; + } else if(event->key == InputKeyDown) { + model->down_pressed = false; + } else if(event->key == InputKeyLeft) { + model->left_pressed = false; + hid_hal_consumer_key_release(hid_ytshorts->hid, HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = false; + hid_hal_consumer_key_release(hid_ytshorts->hid, HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = false; + } else if(event->key == InputKeyBack) { + model->back_mouse_pressed = false; + } +} + +static bool hid_ytshorts_input_callback(InputEvent* event, void* context) { + furi_assert(context); + HidYTShorts* hid_ytshorts = context; + bool consumed = false; + + with_view_model( + hid_ytshorts->view, + HidYTShortsModel * model, + { + if(event->type == InputTypePress) { + hid_ytshorts_process_press(hid_ytshorts, model, event); + if(model->connected && !model->is_cursor_set) { + hid_ytshorts_reset_cursor(hid_ytshorts); + model->is_cursor_set = true; + } + consumed = true; + } else if(event->type == InputTypeRelease) { + hid_ytshorts_process_release(hid_ytshorts, model, event); + consumed = true; + } else if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + hid_hal_mouse_press(hid_ytshorts->hid, HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + hid_hal_mouse_release(hid_ytshorts->hid, HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + hid_hal_mouse_press(hid_ytshorts->hid, HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + hid_hal_mouse_release(hid_ytshorts->hid, HID_MOUSE_BTN_LEFT); + consumed = true; + } else if(event->key == InputKeyDown) { + // Swipe to new video + hid_hal_mouse_scroll(hid_ytshorts->hid, 6); + hid_hal_mouse_scroll(hid_ytshorts->hid, 8); + hid_hal_mouse_scroll(hid_ytshorts->hid, 10); + hid_hal_mouse_scroll(hid_ytshorts->hid, 8); + hid_hal_mouse_scroll(hid_ytshorts->hid, 6); + consumed = true; + } else if(event->key == InputKeyUp) { + // Swipe to previous video + hid_hal_mouse_scroll(hid_ytshorts->hid, -6); + hid_hal_mouse_scroll(hid_ytshorts->hid, -8); + hid_hal_mouse_scroll(hid_ytshorts->hid, -10); + hid_hal_mouse_scroll(hid_ytshorts->hid, -8); + hid_hal_mouse_scroll(hid_ytshorts->hid, -6); + consumed = true; + } else if(event->key == InputKeyBack) { + // Pause + hid_hal_mouse_press(hid_ytshorts->hid, HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + hid_hal_mouse_release(hid_ytshorts->hid, HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + consumed = true; + } + } else if(event->type == InputTypeLong) { + if(event->key == InputKeyBack) { + hid_hal_consumer_key_release_all(hid_ytshorts->hid); + model->is_cursor_set = false; + consumed = false; + } + } + }, + true); + + return consumed; +} + +HidYTShorts* hid_ytshorts_alloc(Hid* bt_hid) { + HidYTShorts* hid_ytshorts = malloc(sizeof(HidYTShorts)); + hid_ytshorts->hid = bt_hid; + hid_ytshorts->view = view_alloc(); + view_set_context(hid_ytshorts->view, hid_ytshorts); + view_allocate_model(hid_ytshorts->view, ViewModelTypeLocking, sizeof(HidYTShortsModel)); + view_set_draw_callback(hid_ytshorts->view, hid_ytshorts_draw_callback); + view_set_input_callback(hid_ytshorts->view, hid_ytshorts_input_callback); + + with_view_model( + hid_ytshorts->view, + HidYTShortsModel * model, + { model->transport = bt_hid->transport; }, + true); + + return hid_ytshorts; +} + +void hid_ytshorts_free(HidYTShorts* hid_ytshorts) { + furi_assert(hid_ytshorts); + view_free(hid_ytshorts->view); + free(hid_ytshorts); +} + +View* hid_ytshorts_get_view(HidYTShorts* hid_ytshorts) { + furi_assert(hid_ytshorts); + return hid_ytshorts->view; +} + +void hid_ytshorts_set_connected_status(HidYTShorts* hid_ytshorts, bool connected) { + furi_assert(hid_ytshorts); + with_view_model( + hid_ytshorts->view, + HidYTShortsModel * model, + { + model->connected = connected; + model->is_cursor_set = false; + }, + true); +} diff --git a/applications/external/hid_app/views/hid_ytshorts.h b/applications/external/hid_app/views/hid_ytshorts.h new file mode 100644 index 000000000..03264dd36 --- /dev/null +++ b/applications/external/hid_app/views/hid_ytshorts.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +typedef struct Hid Hid; +typedef struct HidYTShorts HidYTShorts; + +HidYTShorts* hid_ytshorts_alloc(Hid* bt_hid); + +void hid_ytshorts_free(HidYTShorts* hid_ytshorts); + +View* hid_ytshorts_get_view(HidYTShorts* hid_ytshorts); + +void hid_ytshorts_set_connected_status(HidYTShorts* hid_ytshorts, bool connected); From 731c752e94ae12fadcfeef0e39e226d056aa4f72 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Apr 2023 03:41:58 +0300 Subject: [PATCH 21/22] Update changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21134f6a1..2544677e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,13 @@ * SubGHz: (Bug that I decided to keep as a feature) You can change default button (Ok) for remote by holding custom button and pressing back at same time (same can be used to restore your button if you changed it accidentally) - Be careful, it might be unstable, I will make proper option to change button in next releases * SubGHz: Fixes for custom button bugs in SubGHz Remote app * SubGHz: Add alutech table to enviroment alloc and free +* Docs: Fix and update docs - thanks to @lesterrry +* Plugins: Bluetooth Remote - implemented YouTube Shorts Remote (may be unstable) +* Plugins: Bluetooth Remote - improvements and fixes for TikTok remote (by @krolchonok | PR #420) +* Plugins: Implement an array for baudrates on GPS UART app (+ add 19200 baud) (by @p0ns | PR #416) * Plugins: Update **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) * Plugins: Update **UART Terminal** [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main) -* OFW: Deep Sleep Idle - **Improves battery usage!!!** +* OFW: Deep Sleep Idle - **Improves battery usage!!!** -> **Breaking API change, api was changed from 21.x to 22.x** * OFW: FuriHal: pwr pulls for some pins * OFW: Bugfix: ISP Programmer and SubGhz * OFW: AVR_ISP: fix NULL pointer dereference From 0f6c2bff069d9429c93952ae026863d05c2b75f8 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 14 Apr 2023 04:04:43 +0300 Subject: [PATCH 22/22] Update changelog, disable old app --- CHANGELOG.md | 1 + applications/debug/uart_echo/application.fam | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2544677e3..f84b0985b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Plugins: Bluetooth Remote - implemented YouTube Shorts Remote (may be unstable) * Plugins: Bluetooth Remote - improvements and fixes for TikTok remote (by @krolchonok | PR #420) * Plugins: Implement an array for baudrates on GPS UART app (+ add 19200 baud) (by @p0ns | PR #416) +* Plugins: Remove UART Echo from releases since it is locked on 115200 baud, and we have **UART Terminal** with ability to set baudrate * Plugins: Update **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) * Plugins: Update **UART Terminal** [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main) * OFW: Deep Sleep Idle - **Improves battery usage!!!** -> **Breaking API change, api was changed from 21.x to 22.x** diff --git a/applications/debug/uart_echo/application.fam b/applications/debug/uart_echo/application.fam index 4ad14e6c3..fce9ac809 100644 --- a/applications/debug/uart_echo/application.fam +++ b/applications/debug/uart_echo/application.fam @@ -1,12 +1,12 @@ App( appid="UART_Echo", name="UART Echo", - apptype=FlipperAppType.EXTERNAL, + apptype=FlipperAppType.DEBUG, entry_point="uart_echo_app", cdefines=["APP_UART_ECHO"], requires=["gui"], stack_size=2 * 1024, order=70, fap_icon="uart_10px.png", - fap_category="GPIO", + fap_category="Debug", )