From 4f0d2012691c3f9e8e3baf23cf730301c208547c Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 12 Jun 2023 05:40:00 +0300 Subject: [PATCH 01/10] Fix changelog updater links --- .drone.yml | 16 ++++++++-------- CHANGELOG.md | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.drone.yml b/.drone.yml index f7c6d07dee..b626de5c47 100644 --- a/.drone.yml +++ b/.drone.yml @@ -26,14 +26,6 @@ steps: - mv dist/f7-C/* artifacts-default/ - ls -laS artifacts-default - ls -laS artifacts-default/f7-update-${DRONE_TAG} - - sed -i 's/(version)/'${DRONE_TAG}'/g' CHANGELOG.md - - echo '# [Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw/${DRONE_TAG}/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=release-cfw&version='${DRONE_TAG}')' >> CHANGELOG.md - - echo '' >> CHANGELOG.md - - echo '### [Version without custom animations - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)' >> CHANGELOG.md - - echo '' >> CHANGELOG.md - - echo '### [Version with RGB patch - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz&channel=release-cfw&version='${DRONE_TAG}'r)' >> CHANGELOG.md - - echo '' >> CHANGELOG.md - - echo '## [Version with Extra apps - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)' >> CHANGELOG.md environment: FBT_TOOLS_CUSTOM_LINK: from_secret: fbt_link @@ -94,6 +86,14 @@ steps: - mv dist/f7-C/* artifacts-ofw-anims/ - ls -laS artifacts-ofw-anims - ls -laS artifacts-ofw-anims/f7-update-${DRONE_TAG}n + - sed -i 's/(version)/'${DRONE_TAG}'/g' CHANGELOG.md + - echo '# [Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw/${DRONE_TAG}/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=release-cfw&version='${DRONE_TAG}')' >> CHANGELOG.md + - echo '' >> CHANGELOG.md + - echo '### [Version without custom animations - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)' >> CHANGELOG.md + - echo '' >> CHANGELOG.md + - echo '### [Version with RGB patch - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz&channel=release-cfw&version='${DRONE_TAG}'r)' >> CHANGELOG.md + - echo '' >> CHANGELOG.md + - echo '## [Version with Extra apps - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)' >> CHANGELOG.md environment: FBT_TOOLS_CUSTOM_LINK: from_secret: fbt_link diff --git a/CHANGELOG.md b/CHANGELOG.md index f77894a48a..3dbc1db79b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,8 +67,8 @@ and all other great people who supported our project and me (xMasterX), thanks t **Recommended option - Web Updater** -### What `n`, `e`, `r` means? What I need to download if I don't want to use Web updater? -What means `n` or `e` in - `flipper-z-f7-update-(version)(n / e).tgz` ? - `n` means this build comes without our custom animations, only official flipper animations, +### What `n`, `r`, `e` means? What I need to download if I don't want to use Web updater? +What means `n` or `e` in - `flipper-z-f7-update-(version)(n / r / e).tgz` ? - `n` means this build comes without our custom animations, only official flipper animations, `e` means build has extra apps pack preinstalled, `r` means RGB patch (+ extra apps) for flippers with rgb backlight mod (this is hardware mod!) (Works only on modded flippers!) From 6aed650bcc933b1eb85f5b79ebcab1c720cb777c Mon Sep 17 00:00:00 2001 From: Sil333033 <94360907+Sil333033@users.noreply.github.com> Date: Mon, 12 Jun 2023 14:15:22 +0200 Subject: [PATCH 02/10] added external cc1101 module at cli --- applications/main/subghz/subghz_cli.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index 526567e608..22a3ed3c70 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -779,6 +779,20 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) { static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { FuriString* cmd = furi_string_alloc(); + if(!furi_hal_power_is_otg_enabled()) { + furi_hal_power_enable_otg(); + } + + furi_delay_ms(15); + + furi_hal_subghz_select_radio_type(SubGhzRadioExternal); + furi_hal_subghz_init_radio_type(SubGhzRadioExternal); + + if(!furi_hal_subghz_check_radio()) { + furi_hal_subghz_select_radio_type(SubGhzRadioInternal); + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); + } + do { if(!args_read_string_and_trim(args, cmd)) { subghz_cli_command_print_usage(); From d1c970b0194f02087a8a977165124174a813ccd2 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 12 Jun 2023 23:20:56 +0300 Subject: [PATCH 03/10] Fix protoview patable adding in custom modulations --- applications/external/protoview/signal_file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/applications/external/protoview/signal_file.c b/applications/external/protoview/signal_file.c index 886573a063..e7934d04bf 100644 --- a/applications/external/protoview/signal_file.c +++ b/applications/external/protoview/signal_file.c @@ -48,6 +48,8 @@ bool save_signal(ProtoViewApp* app, const char* filename) { for(int j = 0; regs[j]; j += 2) { furi_string_cat_printf(custom, "%02X %02X ", (int)regs[j], (int)regs[j + 1]); } + // Add patable + furi_string_cat(custom, "00 00 C0 00 00 00 00 00 00 00 "); //size_t len = furi_string_size(file_content); //furi_string_set_char(custom, len - 1, '\n'); furi_string_cat(custom, "\n"); From 392bd3cde09e17ab40fb55616d556ea3f77e9dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 13 Jun 2023 21:02:12 +0900 Subject: [PATCH 04/10] FuriHal: remove clock startup time tracking from clean builds (#2764) --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 770b74296c..736ad9f7c0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -143,7 +142,10 @@ void furi_hal_clock_switch_to_hsi() { } void furi_hal_clock_switch_to_pll() { +#ifdef FURI_HAL_CLOCK_TRACK_STARTUP uint32_t clock_start_time = DWT->CYCCNT; +#endif + LL_RCC_HSE_Enable(); LL_RCC_PLL_Enable(); LL_RCC_PLLSAI1_Enable(); @@ -166,11 +168,12 @@ void furi_hal_clock_switch_to_pll() { while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) ; +#ifdef FURI_HAL_CLOCK_TRACK_STARTUP uint32_t total = DWT->CYCCNT - clock_start_time; if(total > (20 * 0x148)) { - furi_hal_rtc_set_flag(FuriHalRtcFlagLegacySleep); furi_crash("Slow HSE/PLL startup"); } +#endif } void furi_hal_clock_suspend_tick() { From f22624399c1288638ec4df9bd00046db5ca27550 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 14 Jun 2023 01:07:07 +0300 Subject: [PATCH 05/10] remove unneeded global var --- .../main/subghz/scenes/subghz_scene_radio_settings.c | 3 +-- applications/main/subghz/scenes/subghz_scene_save_name.c | 2 +- applications/main/subghz/subghz_last_settings.c | 2 -- firmware/targets/f7/api_symbols.csv | 2 -- firmware/targets/f7/furi_hal/furi_hal_subghz.c | 9 --------- firmware/targets/f7/furi_hal/furi_hal_subghz.h | 8 -------- 6 files changed, 2 insertions(+), 24 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_radio_settings.c b/applications/main/subghz/scenes/subghz_scene_radio_settings.c index b60ea0b2dc..3020c1b23a 100644 --- a/applications/main/subghz/scenes/subghz_scene_radio_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_radio_settings.c @@ -111,7 +111,6 @@ static void subghz_scene_receiver_config_set_timestamp_file_names(VariableItem* variable_item_set_current_value_text(item, timestamp_names_text[index]); - furi_hal_subghz_set_timestamp_file_names((index == 1)); subghz->last_settings->timestamp_file_names = (index == 1); subghz_last_settings_save(subghz->last_settings); } @@ -148,7 +147,7 @@ void subghz_scene_radio_settings_on_enter(void* context) { TIMESTAMP_NAMES_COUNT, subghz_scene_receiver_config_set_timestamp_file_names, subghz); - value_index = furi_hal_subghz_get_timestamp_file_names(); + value_index = subghz->last_settings->timestamp_file_names; variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, timestamp_names_text[value_index]); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index c05d0d9627..5c52ed9577 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -56,7 +56,7 @@ void subghz_scene_save_name_on_enter(void* context) { if(!subghz_path_is_file(subghz->file_path)) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; - if(furi_hal_subghz_get_timestamp_file_names()) { + if(subghz->last_settings->timestamp_file_names) { SubGhzProtocolDecoderBase* decoder_result = subghz_txrx_get_decoder(subghz->txrx); if(decoder_result != 0x0) { if(decoder_result != NULL) { diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 7ee2554b0d..8cf0f063a3 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -120,8 +120,6 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count instance->timestamp_file_names = temp_timestamp_file_names; // Set globally - furi_hal_subghz_set_timestamp_file_names(instance->timestamp_file_names); - if(instance->external_module_power_5v_disable) { furi_hal_subghz_set_external_power_disable(true); furi_hal_subghz_disable_ext_power(); diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 8a7f947e6f..26e4c0b3e5 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1405,7 +1405,6 @@ Function,+,furi_hal_subghz_get_lqi,uint8_t, Function,+,furi_hal_subghz_get_radio_type,SubGhzRadioType, Function,+,furi_hal_subghz_get_rolling_counter_mult,uint8_t, Function,+,furi_hal_subghz_get_rssi,float, -Function,+,furi_hal_subghz_get_timestamp_file_names,_Bool, Function,+,furi_hal_subghz_idle,void, Function,-,furi_hal_subghz_init,void, Function,-,furi_hal_subghz_init_check,_Bool, @@ -1429,7 +1428,6 @@ Function,+,furi_hal_subghz_set_frequency,uint32_t,uint32_t Function,+,furi_hal_subghz_set_frequency_and_path,uint32_t,uint32_t Function,+,furi_hal_subghz_set_path,void,FuriHalSubGhzPath Function,-,furi_hal_subghz_set_rolling_counter_mult,void,uint8_t -Function,-,furi_hal_subghz_set_timestamp_file_names,void,_Bool Function,-,furi_hal_subghz_shutdown,void, Function,+,furi_hal_subghz_sleep,void, Function,+,furi_hal_subghz_start_async_rx,void,"FuriHalSubGhzCaptureCallback, void*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 8125971e96..aa7438b0b8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -41,7 +41,6 @@ volatile FuriHalSubGhz furi_hal_subghz = { .cc1101_g0_pin = &gpio_cc1101_g0, .rolling_counter_mult = 1, .ext_module_power_disabled = false, - .timestamp_file_names = false, .dangerous_frequency_i = false, }; @@ -90,14 +89,6 @@ bool furi_hal_subghz_get_external_power_disable(void) { return furi_hal_subghz.ext_module_power_disabled; } -void furi_hal_subghz_set_timestamp_file_names(bool state) { - furi_hal_subghz.timestamp_file_names = state; -} - -bool furi_hal_subghz_get_timestamp_file_names(void) { - return furi_hal_subghz.timestamp_file_names; -} - void furi_hal_subghz_set_dangerous_frequency(bool state_i) { furi_hal_subghz.dangerous_frequency_i = state_i; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.h b/firmware/targets/f7/furi_hal/furi_hal_subghz.h index 0ef7bd90a6..ae6876d456 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.h +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.h @@ -332,14 +332,6 @@ void furi_hal_subghz_set_external_power_disable(bool state); */ bool furi_hal_subghz_get_external_power_disable(void); -/** If true - disable generation of random name and add timestamp to filenames instead - */ -void furi_hal_subghz_set_timestamp_file_names(bool state); - -/** Get the current state of the timestamp instead of random name flag - */ -bool furi_hal_subghz_get_timestamp_file_names(void); - /** Set what radio module we will be using */ void furi_hal_subghz_select_radio_type(SubGhzRadioType state); From 8bb30920028930c364b968909fe1c1047d3e5b98 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 14 Jun 2023 03:18:24 +0300 Subject: [PATCH 06/10] Revert BLE gatt characteristics refactoring temporarily --- applications/services/bt/bt_service/bt.c | 2 +- firmware/targets/f7/ble_glue/app_debug.c | 4 +- .../ble_glue/{services => }/battery_service.c | 118 ++--- .../ble_glue/{services => }/battery_service.h | 0 firmware/targets/f7/ble_glue/ble_app.c | 91 ++-- .../targets/f7/ble_glue/dev_info_service.c | 220 +++++++++ .../{services => }/dev_info_service.h | 0 firmware/targets/f7/ble_glue/hid_service.c | 416 ++++++++++++++++++ .../f7/ble_glue/{services => }/hid_service.h | 3 +- .../ble_glue/{services => }/serial_service.c | 195 ++++---- .../ble_glue/{services => }/serial_service.h | 0 .../f7/ble_glue/services/dev_info_service.c | 176 -------- .../services/dev_info_service_uuid.inc | 3 - .../targets/f7/ble_glue/services/gatt_char.c | 123 ------ .../targets/f7/ble_glue/services/gatt_char.h | 96 ---- .../f7/ble_glue/services/hid_service.c | 365 --------------- .../ble_glue/services/serial_service_uuid.inc | 12 - firmware/targets/f7/furi_hal/furi_hal_bt.c | 3 +- .../targets/f7/furi_hal/furi_hal_bt_hid.c | 10 +- .../targets/f7/furi_hal/furi_hal_bt_serial.c | 6 +- .../targets/furi_hal_include/furi_hal_bt.h | 2 +- .../furi_hal_include/furi_hal_bt_serial.h | 2 +- 22 files changed, 877 insertions(+), 970 deletions(-) rename firmware/targets/f7/ble_glue/{services => }/battery_service.c (53%) rename firmware/targets/f7/ble_glue/{services => }/battery_service.h (100%) create mode 100644 firmware/targets/f7/ble_glue/dev_info_service.c rename firmware/targets/f7/ble_glue/{services => }/dev_info_service.h (100%) create mode 100644 firmware/targets/f7/ble_glue/hid_service.c rename firmware/targets/f7/ble_glue/{services => }/hid_service.h (89%) rename firmware/targets/f7/ble_glue/{services => }/serial_service.c (57%) rename firmware/targets/f7/ble_glue/{services => }/serial_service.h (100%) delete mode 100644 firmware/targets/f7/ble_glue/services/dev_info_service.c delete mode 100644 firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc delete mode 100644 firmware/targets/f7/ble_glue/services/gatt_char.c delete mode 100644 firmware/targets/f7/ble_glue/services/gatt_char.h delete mode 100644 firmware/targets/f7/ble_glue/services/hid_service.c delete mode 100644 firmware/targets/f7/ble_glue/services/serial_service_uuid.inc diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index 191324c9ee..a842aea45a 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -1,7 +1,7 @@ #include "bt_i.h" +#include "battery_service.h" #include "bt_keys_storage.h" -#include #include #include #include diff --git a/firmware/targets/f7/ble_glue/app_debug.c b/firmware/targets/f7/ble_glue/app_debug.c index d288528223..b443bee21f 100644 --- a/firmware/targets/f7/ble_glue/app_debug.c +++ b/firmware/targets/f7/ble_glue/app_debug.c @@ -196,14 +196,14 @@ static void APPD_SetCPU2GpioConfig(void) { gpio_config.Pin = gpiob_pin_list; LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOB); LL_GPIO_Init(GPIOB, &gpio_config); - LL_GPIO_ResetOutputPin(GPIOB, gpiob_pin_list); + LL_GPIO_ResetOutputPin(GPIOB, gpioa_pin_list); } if(gpioc_pin_list != 0) { gpio_config.Pin = gpioc_pin_list; LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOC); LL_GPIO_Init(GPIOC, &gpio_config); - LL_GPIO_ResetOutputPin(GPIOC, gpioc_pin_list); + LL_GPIO_ResetOutputPin(GPIOC, gpioa_pin_list); } } diff --git a/firmware/targets/f7/ble_glue/services/battery_service.c b/firmware/targets/f7/ble_glue/battery_service.c similarity index 53% rename from firmware/targets/f7/ble_glue/services/battery_service.c rename to firmware/targets/f7/ble_glue/battery_service.c index 63f736b3b7..8c371efadb 100644 --- a/firmware/targets/f7/ble_glue/services/battery_service.c +++ b/firmware/targets/f7/ble_glue/battery_service.c @@ -1,7 +1,5 @@ #include "battery_service.h" #include "app_common.h" -#include "gatt_char.h" - #include #include @@ -9,6 +7,12 @@ #define TAG "BtBatterySvc" +typedef struct { + uint16_t svc_handle; + uint16_t battery_level_char_handle; + uint16_t power_state_char_handle; +} BatterySvc; + enum { // Common states BatterySvcPowerStateUnknown = 0b00, @@ -36,44 +40,13 @@ typedef struct { _Static_assert(sizeof(BattrySvcPowerState) == 1, "Incorrect structure size"); +static BatterySvc* battery_svc = NULL; + #define BATTERY_POWER_STATE (0x2A1A) static const uint16_t service_uuid = BATTERY_SERVICE_UUID; - -typedef enum { - BatterySvcGattCharacteristicBatteryLevel = 0, - BatterySvcGattCharacteristicPowerState, - BatterySvcGattCharacteristicCount, -} BatterySvcGattCharacteristicId; - -static const FlipperGattCharacteristicParams battery_svc_chars[BatterySvcGattCharacteristicCount] = - {[BatterySvcGattCharacteristicBatteryLevel] = - {.name = "Battery Level", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = 1, - .uuid.Char_UUID_16 = BATTERY_LEVEL_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [BatterySvcGattCharacteristicPowerState] = { - .name = "Power State", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = 1, - .uuid.Char_UUID_16 = BATTERY_POWER_STATE, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}}; - -typedef struct { - uint16_t svc_handle; - FlipperGattCharacteristicInstance chars[BatterySvcGattCharacteristicCount]; -} BatterySvc; - -static BatterySvc* battery_svc = NULL; +static const uint16_t battery_level_char_uuid = BATTERY_LEVEL_CHAR_UUID; +static const uint16_t power_state_char_uuid = BATTERY_POWER_STATE; void battery_svc_start() { battery_svc = malloc(sizeof(BatterySvc)); @@ -85,19 +58,53 @@ void battery_svc_start() { if(status) { FURI_LOG_E(TAG, "Failed to add Battery service: %d", status); } - for(size_t i = 0; i < BatterySvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_init( - battery_svc->svc_handle, &battery_svc_chars[i], &battery_svc->chars[i]); + // Add Battery level characteristic + status = aci_gatt_add_char( + battery_svc->svc_handle, + UUID_TYPE_16, + (Char_UUID_t*)&battery_level_char_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &battery_svc->battery_level_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add Battery level characteristic: %d", status); } - + // Add Power state characteristic + status = aci_gatt_add_char( + battery_svc->svc_handle, + UUID_TYPE_16, + (Char_UUID_t*)&power_state_char_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &battery_svc->power_state_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add Battery level characteristic: %d", status); + } + // Update power state charachteristic battery_svc_update_power_state(); } void battery_svc_stop() { tBleStatus status; if(battery_svc) { - for(size_t i = 0; i < BatterySvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_delete(battery_svc->svc_handle, &battery_svc->chars[i]); + // Delete Battery level characteristic + status = + aci_gatt_del_char(battery_svc->svc_handle, battery_svc->battery_level_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Battery level characteristic: %d", status); + } + // Delete Power state characteristic + status = aci_gatt_del_char(battery_svc->svc_handle, battery_svc->power_state_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Battery level characteristic: %d", status); } // Delete Battery service status = aci_gatt_del_service(battery_svc->svc_handle); @@ -119,10 +126,13 @@ bool battery_svc_update_level(uint8_t battery_charge) { return false; } // Update battery level characteristic - return flipper_gatt_characteristic_update( - battery_svc->svc_handle, - &battery_svc->chars[BatterySvcGattCharacteristicBatteryLevel], - &battery_charge); + FURI_LOG_D(TAG, "Updating battery level characteristic"); + tBleStatus result = aci_gatt_update_char_value( + battery_svc->svc_handle, battery_svc->battery_level_char_handle, 0, 1, &battery_charge); + if(result) { + FURI_LOG_E(TAG, "Failed updating RX characteristic: %d", result); + } + return result != BLE_STATUS_SUCCESS; } bool battery_svc_update_power_state() { @@ -142,9 +152,15 @@ bool battery_svc_update_power_state() { power_state.charging = BatterySvcPowerStateNotCharging; power_state.discharging = BatterySvcPowerStateDischarging; } - - return flipper_gatt_characteristic_update( + FURI_LOG_D(TAG, "Updating power state characteristic"); + tBleStatus result = aci_gatt_update_char_value( battery_svc->svc_handle, - &battery_svc->chars[BatterySvcGattCharacteristicPowerState], - &power_state); + battery_svc->power_state_char_handle, + 0, + 1, + (uint8_t*)&power_state); + if(result) { + FURI_LOG_E(TAG, "Failed updating Power state characteristic: %d", result); + } + return result != BLE_STATUS_SUCCESS; } diff --git a/firmware/targets/f7/ble_glue/services/battery_service.h b/firmware/targets/f7/ble_glue/battery_service.h similarity index 100% rename from firmware/targets/f7/ble_glue/services/battery_service.h rename to firmware/targets/f7/ble_glue/battery_service.h diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index c0418d9fe8..37d8f7cd04 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -33,51 +33,6 @@ static int32_t ble_app_hci_thread(void* context); static void ble_app_hci_event_handler(void* pPayload); static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status); -static const HCI_TL_HciInitConf_t hci_tl_config = { - .p_cmdbuffer = (uint8_t*)&ble_app_cmd_buffer, - .StatusNotCallBack = ble_app_hci_status_not_handler, -}; - -static const SHCI_C2_CONFIG_Cmd_Param_t config_param = { - .PayloadCmdSize = SHCI_C2_CONFIG_PAYLOAD_CMD_SIZE, - .Config1 = SHCI_C2_CONFIG_CONFIG1_BIT0_BLE_NVM_DATA_TO_SRAM, - .BleNvmRamAddress = (uint32_t)ble_app_nvm, - .EvtMask1 = SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE, -}; - -static const SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { - .Header = {{0, 0, 0}}, // Header unused - .Param = { - .pBleBufferAddress = 0, // pBleBufferAddress not used - .BleBufferSize = 0, // BleBufferSize not used - .NumAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES, - .NumAttrServ = CFG_BLE_NUM_GATT_SERVICES, - .AttrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE, - .NumOfLinks = CFG_BLE_NUM_LINK, - .ExtendedPacketLengthEnable = CFG_BLE_DATA_LENGTH_EXTENSION, - .PrWriteListSize = CFG_BLE_PREPARE_WRITE_LIST_SIZE, - .MblockCount = CFG_BLE_MBLOCK_COUNT, - .AttMtu = CFG_BLE_MAX_ATT_MTU, - .SlaveSca = CFG_BLE_SLAVE_SCA, - .MasterSca = CFG_BLE_MASTER_SCA, - .LsSource = CFG_BLE_LSE_SOURCE, - .MaxConnEventLength = CFG_BLE_MAX_CONN_EVENT_LENGTH, - .HsStartupTime = CFG_BLE_HSE_STARTUP_TIME, - .ViterbiEnable = CFG_BLE_VITERBI_MODE, - .Options = CFG_BLE_OPTIONS, - .HwVersion = 0, - .max_coc_initiator_nbr = 32, - .min_tx_power = 0, - .max_tx_power = 0, - .rx_model_config = 1, - /* New stack (13.3->15.0) */ - .max_adv_set_nbr = 1, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set - .max_adv_data_len = 31, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set - .tx_path_compens = 0, // RF TX Path Compensation, * 0.1 dB - .rx_path_compens = 0, // RF RX Path Compensation, * 0.1 dB - .ble_core_version = 11, // BLE Core Version: 11(5.2), 12(5.3) - }}; - bool ble_app_init() { SHCI_CmdStatus_t status; ble_app = malloc(sizeof(BleApp)); @@ -89,16 +44,58 @@ bool ble_app_init() { furi_thread_start(ble_app->thread); // Initialize Ble Transport Layer + HCI_TL_HciInitConf_t hci_tl_config = { + .p_cmdbuffer = (uint8_t*)&ble_app_cmd_buffer, + .StatusNotCallBack = ble_app_hci_status_not_handler, + }; hci_init(ble_app_hci_event_handler, (void*)&hci_tl_config); // Configure NVM store for pairing data - status = SHCI_C2_Config((SHCI_C2_CONFIG_Cmd_Param_t*)&config_param); + SHCI_C2_CONFIG_Cmd_Param_t config_param = { + .PayloadCmdSize = SHCI_C2_CONFIG_PAYLOAD_CMD_SIZE, + .Config1 = SHCI_C2_CONFIG_CONFIG1_BIT0_BLE_NVM_DATA_TO_SRAM, + .BleNvmRamAddress = (uint32_t)ble_app_nvm, + .EvtMask1 = SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE, + }; + status = SHCI_C2_Config(&config_param); if(status) { FURI_LOG_E(TAG, "Failed to configure 2nd core: %d", status); } // Start ble stack on 2nd core - status = SHCI_C2_BLE_Init((SHCI_C2_Ble_Init_Cmd_Packet_t*)&ble_init_cmd_packet); + SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { + .Header = {{0, 0, 0}}, // Header unused + .Param = { + .pBleBufferAddress = 0, // pBleBufferAddress not used + .BleBufferSize = 0, // BleBufferSize not used + .NumAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES, + .NumAttrServ = CFG_BLE_NUM_GATT_SERVICES, + .AttrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE, + .NumOfLinks = CFG_BLE_NUM_LINK, + .ExtendedPacketLengthEnable = CFG_BLE_DATA_LENGTH_EXTENSION, + .PrWriteListSize = CFG_BLE_PREPARE_WRITE_LIST_SIZE, + .MblockCount = CFG_BLE_MBLOCK_COUNT, + .AttMtu = CFG_BLE_MAX_ATT_MTU, + .SlaveSca = CFG_BLE_SLAVE_SCA, + .MasterSca = CFG_BLE_MASTER_SCA, + .LsSource = CFG_BLE_LSE_SOURCE, + .MaxConnEventLength = CFG_BLE_MAX_CONN_EVENT_LENGTH, + .HsStartupTime = CFG_BLE_HSE_STARTUP_TIME, + .ViterbiEnable = CFG_BLE_VITERBI_MODE, + .Options = CFG_BLE_OPTIONS, + .HwVersion = 0, + .max_coc_initiator_nbr = 32, + .min_tx_power = 0, + .max_tx_power = 0, + .rx_model_config = 1, + /* New stack (13.3->15.0) */ + .max_adv_set_nbr = 1, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set + .max_adv_data_len = 31, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set + .tx_path_compens = 0, // RF TX Path Compensation, * 0.1 dB + .rx_path_compens = 0, // RF RX Path Compensation, * 0.1 dB + .ble_core_version = 11, // BLE Core Version: 11(5.2), 12(5.3) + }}; + status = SHCI_C2_BLE_Init(&ble_init_cmd_packet); if(status) { FURI_LOG_E(TAG, "Failed to start ble stack: %d", status); } diff --git a/firmware/targets/f7/ble_glue/dev_info_service.c b/firmware/targets/f7/ble_glue/dev_info_service.c new file mode 100644 index 0000000000..d24058632f --- /dev/null +++ b/firmware/targets/f7/ble_glue/dev_info_service.c @@ -0,0 +1,220 @@ +#include "dev_info_service.h" +#include "app_common.h" +#include + +#include +#include +#include + +#define TAG "BtDevInfoSvc" + +typedef struct { + uint16_t service_handle; + uint16_t man_name_char_handle; + uint16_t serial_num_char_handle; + uint16_t firmware_rev_char_handle; + uint16_t software_rev_char_handle; + uint16_t rpc_version_char_handle; + FuriString* version_string; + char hardware_revision[4]; +} DevInfoSvc; + +static DevInfoSvc* dev_info_svc = NULL; + +static const char dev_info_man_name[] = "Flipper Devices Inc."; +static const char dev_info_serial_num[] = "1.0"; +static const char dev_info_rpc_version[] = TOSTRING(PROTOBUF_MAJOR_VERSION.PROTOBUF_MINOR_VERSION); + +static const uint8_t dev_info_rpc_version_uuid[] = + {0x33, 0xa9, 0xb5, 0x3e, 0x87, 0x5d, 0x1a, 0x8e, 0xc8, 0x47, 0x5e, 0xae, 0x6d, 0x66, 0xf6, 0x03}; + +void dev_info_svc_start() { + dev_info_svc = malloc(sizeof(DevInfoSvc)); + dev_info_svc->version_string = furi_string_alloc_printf( + "%s %s %s %s", + version_get_githash(NULL), + version_get_version(NULL), + version_get_gitbranchnum(NULL), + version_get_builddate(NULL)); + snprintf( + dev_info_svc->hardware_revision, + sizeof(dev_info_svc->hardware_revision), + "%d", + version_get_target(NULL)); + tBleStatus status; + + // Add Device Information Service + uint16_t uuid = DEVICE_INFORMATION_SERVICE_UUID; + status = aci_gatt_add_service( + UUID_TYPE_16, (Service_UUID_t*)&uuid, PRIMARY_SERVICE, 11, &dev_info_svc->service_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add Device Information Service: %d", status); + } + + // Add characteristics + uuid = MANUFACTURER_NAME_UUID; + status = aci_gatt_add_char( + dev_info_svc->service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(dev_info_man_name), + CHAR_PROP_READ, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc->man_name_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add manufacturer name char: %d", status); + } + uuid = SERIAL_NUMBER_UUID; + status = aci_gatt_add_char( + dev_info_svc->service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(dev_info_serial_num), + CHAR_PROP_READ, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc->serial_num_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add serial number char: %d", status); + } + uuid = FIRMWARE_REVISION_UUID; + status = aci_gatt_add_char( + dev_info_svc->service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + strlen(dev_info_svc->hardware_revision), + CHAR_PROP_READ, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc->firmware_rev_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add firmware revision char: %d", status); + } + uuid = SOFTWARE_REVISION_UUID; + status = aci_gatt_add_char( + dev_info_svc->service_handle, + UUID_TYPE_16, + (Char_UUID_t*)&uuid, + furi_string_size(dev_info_svc->version_string), + CHAR_PROP_READ, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc->software_rev_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add software revision char: %d", status); + } + status = aci_gatt_add_char( + dev_info_svc->service_handle, + UUID_TYPE_128, + (const Char_UUID_t*)dev_info_rpc_version_uuid, + strlen(dev_info_rpc_version), + CHAR_PROP_READ, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &dev_info_svc->rpc_version_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add rpc version characteristic: %d", status); + } + + // Update characteristics + status = aci_gatt_update_char_value( + dev_info_svc->service_handle, + dev_info_svc->man_name_char_handle, + 0, + strlen(dev_info_man_name), + (uint8_t*)dev_info_man_name); + if(status) { + FURI_LOG_E(TAG, "Failed to update manufacturer name char: %d", status); + } + status = aci_gatt_update_char_value( + dev_info_svc->service_handle, + dev_info_svc->serial_num_char_handle, + 0, + strlen(dev_info_serial_num), + (uint8_t*)dev_info_serial_num); + if(status) { + FURI_LOG_E(TAG, "Failed to update serial number char: %d", status); + } + status = aci_gatt_update_char_value( + dev_info_svc->service_handle, + dev_info_svc->firmware_rev_char_handle, + 0, + strlen(dev_info_svc->hardware_revision), + (uint8_t*)dev_info_svc->hardware_revision); + if(status) { + FURI_LOG_E(TAG, "Failed to update firmware revision char: %d", status); + } + status = aci_gatt_update_char_value( + dev_info_svc->service_handle, + dev_info_svc->software_rev_char_handle, + 0, + furi_string_size(dev_info_svc->version_string), + (uint8_t*)furi_string_get_cstr(dev_info_svc->version_string)); + if(status) { + FURI_LOG_E(TAG, "Failed to update software revision char: %d", status); + } + status = aci_gatt_update_char_value( + dev_info_svc->service_handle, + dev_info_svc->rpc_version_char_handle, + 0, + strlen(dev_info_rpc_version), + (uint8_t*)dev_info_rpc_version); + if(status) { + FURI_LOG_E(TAG, "Failed to update rpc version char: %d", status); + } +} + +void dev_info_svc_stop() { + tBleStatus status; + if(dev_info_svc) { + furi_string_free(dev_info_svc->version_string); + // Delete service characteristics + status = + aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->man_name_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete manufacturer name char: %d", status); + } + status = + aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->serial_num_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete serial number char: %d", status); + } + status = aci_gatt_del_char( + dev_info_svc->service_handle, dev_info_svc->firmware_rev_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete firmware revision char: %d", status); + } + status = aci_gatt_del_char( + dev_info_svc->service_handle, dev_info_svc->software_rev_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete software revision char: %d", status); + } + status = + aci_gatt_del_char(dev_info_svc->service_handle, dev_info_svc->rpc_version_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete rpc version char: %d", status); + } + // Delete service + status = aci_gatt_del_service(dev_info_svc->service_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete device info service: %d", status); + } + free(dev_info_svc); + dev_info_svc = NULL; + } +} + +bool dev_info_svc_is_started() { + return dev_info_svc != NULL; +} diff --git a/firmware/targets/f7/ble_glue/services/dev_info_service.h b/firmware/targets/f7/ble_glue/dev_info_service.h similarity index 100% rename from firmware/targets/f7/ble_glue/services/dev_info_service.h rename to firmware/targets/f7/ble_glue/dev_info_service.h diff --git a/firmware/targets/f7/ble_glue/hid_service.c b/firmware/targets/f7/ble_glue/hid_service.c new file mode 100644 index 0000000000..a31d6015f5 --- /dev/null +++ b/firmware/targets/f7/ble_glue/hid_service.c @@ -0,0 +1,416 @@ +#include "hid_service.h" +#include "app_common.h" +#include + +#include + +#define TAG "BtHid" + +typedef struct { + uint16_t svc_handle; + uint16_t protocol_mode_char_handle; + uint16_t report_char_handle[HID_SVC_REPORT_COUNT]; + uint16_t report_ref_desc_handle[HID_SVC_REPORT_COUNT]; + uint16_t report_map_char_handle; + uint16_t info_char_handle; + uint16_t ctrl_point_char_handle; + // led state + uint16_t led_state_char_handle; + uint16_t led_state_desc_handle; + HidLedStateEventCallback led_state_event_callback; + void* led_state_ctx; +} HIDSvc; + +static HIDSvc* hid_svc = NULL; + +static SVCCTL_EvtAckStatus_t hid_svc_event_handler(void* event) { + SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; + hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data); + evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data; + // aci_gatt_attribute_modified_event_rp0* attribute_modified; + if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { + if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { + // Process modification events + ret = SVCCTL_EvtAckFlowEnable; + } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { + // Process notification confirmation + ret = SVCCTL_EvtAckFlowEnable; + } else if(blecore_evt->ecode == ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE) { + // Process write request + aci_gatt_write_permit_req_event_rp0* req = + (aci_gatt_write_permit_req_event_rp0*)blecore_evt->data; + + furi_check(hid_svc->led_state_event_callback && hid_svc->led_state_ctx); + + // this check is likely to be incorrect, it will actually work in our case + // but we need to investigate gatt api to see what is the rules + // that specify attibute handle value from char handle (or the reverse) + if(req->Attribute_Handle == (hid_svc->led_state_char_handle + 1)) { + hid_svc->led_state_event_callback(req->Data[0], hid_svc->led_state_ctx); + aci_gatt_write_resp( + req->Connection_Handle, + req->Attribute_Handle, + 0x00, /* write_status = 0 (no error))*/ + 0x00, /* err_code */ + req->Data_Length, + req->Data); + aci_gatt_write_char_value( + req->Connection_Handle, + hid_svc->led_state_char_handle, + req->Data_Length, + req->Data); + ret = SVCCTL_EvtAckFlowEnable; + } + } + } + return ret; +} + +void hid_svc_start() { + tBleStatus status; + hid_svc = malloc(sizeof(HIDSvc)); + Service_UUID_t svc_uuid = {}; + Char_Desc_Uuid_t desc_uuid = {}; + Char_UUID_t char_uuid = {}; + + // Register event handler + SVCCTL_RegisterSvcHandler(hid_svc_event_handler); + // Add service + svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID; + /** + * Add Human Interface Device Service + */ + status = aci_gatt_add_service( + UUID_TYPE_16, + &svc_uuid, + PRIMARY_SERVICE, + 2 + /* protocol mode */ + (4 * HID_SVC_INPUT_REPORT_COUNT) + (3 * HID_SVC_OUTPUT_REPORT_COUNT) + + (3 * HID_SVC_FEATURE_REPORT_COUNT) + 1 + 2 + 2 + 2 + + 4, /* Service + Report Map + HID Information + HID Control Point + LED state */ + &hid_svc->svc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add HID service: %d", status); + } + // Add Protocol mode characteristics + char_uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->protocol_mode_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add protocol mode characteristic: %d", status); + } + // Update Protocol mode characteristic + uint8_t protocol_mode = 1; + status = aci_gatt_update_char_value( + hid_svc->svc_handle, hid_svc->protocol_mode_char_handle, 0, 1, &protocol_mode); + if(status) { + FURI_LOG_E(TAG, "Failed to update protocol mode characteristic: %d", status); + } + +#if(HID_SVC_REPORT_COUNT != 0) + for(uint8_t i = 0; i < HID_SVC_REPORT_COUNT; i++) { + if(i < HID_SVC_INPUT_REPORT_COUNT) { //-V547 + uint8_t buf[2] = {i + 1, 1}; // 1 input + char_uuid.Char_UUID_16 = REPORT_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &(hid_svc->report_char_handle[i])); + if(status) { + FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status); + } + + desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID; + status = aci_gatt_add_char_desc( + hid_svc->svc_handle, + hid_svc->report_char_handle[i], + UUID_TYPE_16, + &desc_uuid, + HID_SVC_REPORT_REF_LEN, + HID_SVC_REPORT_REF_LEN, + buf, + ATTR_PERMISSION_NONE, + ATTR_ACCESS_READ_WRITE, + GATT_DONT_NOTIFY_EVENTS, + MIN_ENCRY_KEY_SIZE, + CHAR_VALUE_LEN_CONSTANT, + &(hid_svc->report_ref_desc_handle[i])); + if(status) { + FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status); + } + } else if((i - HID_SVC_INPUT_REPORT_COUNT) < HID_SVC_OUTPUT_REPORT_COUNT) { + uint8_t buf[2] = {i + 1, 2}; // 2 output + char_uuid.Char_UUID_16 = REPORT_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &(hid_svc->report_char_handle[i])); + if(status) { + FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status); + } + + desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID; + status = aci_gatt_add_char_desc( + hid_svc->svc_handle, + hid_svc->report_char_handle[i], + UUID_TYPE_16, + &desc_uuid, + HID_SVC_REPORT_REF_LEN, + HID_SVC_REPORT_REF_LEN, + buf, + ATTR_PERMISSION_NONE, + ATTR_ACCESS_READ_WRITE, + GATT_DONT_NOTIFY_EVENTS, + MIN_ENCRY_KEY_SIZE, + CHAR_VALUE_LEN_CONSTANT, + &(hid_svc->report_ref_desc_handle[i])); + if(status) { + FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status); + } + } else { + uint8_t buf[2] = {i + 1, 3}; // 3 feature + char_uuid.Char_UUID_16 = REPORT_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &(hid_svc->report_char_handle[i])); + if(status) { + FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status); + } + + desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID; + status = aci_gatt_add_char_desc( + hid_svc->svc_handle, + hid_svc->report_char_handle[i], + UUID_TYPE_16, + &desc_uuid, + HID_SVC_REPORT_REF_LEN, + HID_SVC_REPORT_REF_LEN, + buf, + ATTR_PERMISSION_NONE, + ATTR_ACCESS_READ_WRITE, + GATT_DONT_NOTIFY_EVENTS, + MIN_ENCRY_KEY_SIZE, + CHAR_VALUE_LEN_CONSTANT, + &(hid_svc->report_ref_desc_handle[i])); + if(status) { + FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status); + } + } + } +#endif + // Add led state output report + char_uuid.Char_UUID_16 = REPORT_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP, + 10, + CHAR_VALUE_LEN_CONSTANT, + &(hid_svc->led_state_char_handle)); + if(status) { + FURI_LOG_E(TAG, "Failed to add led state characteristic: %d", status); + } + + // Add led state char descriptor specifying it is an output report + uint8_t buf[2] = {HID_SVC_REPORT_COUNT + 1, 2}; + desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID; + status = aci_gatt_add_char_desc( + hid_svc->svc_handle, + hid_svc->led_state_char_handle, + UUID_TYPE_16, + &desc_uuid, + HID_SVC_REPORT_REF_LEN, + HID_SVC_REPORT_REF_LEN, + buf, + ATTR_PERMISSION_NONE, + ATTR_ACCESS_READ_WRITE, + GATT_DONT_NOTIFY_EVENTS, + MIN_ENCRY_KEY_SIZE, + CHAR_VALUE_LEN_CONSTANT, + &(hid_svc->led_state_desc_handle)); + if(status) { + FURI_LOG_E(TAG, "Failed to add led state descriptor: %d", status); + } + // Add Report Map characteristic + char_uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAP_MAX_LEN, + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->report_map_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status); + } + + // Add Information characteristic + char_uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_INFO_LEN, + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->info_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add information characteristic: %d", status); + } + // Add Control Point characteristic + char_uuid.Char_UUID_16 = HID_CONTROL_POINT_CHAR_UUID; + status = aci_gatt_add_char( + hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_CONTROL_POINT_LEN, + CHAR_PROP_WRITE_WITHOUT_RESP, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->ctrl_point_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add control point characteristic: %d", status); + } + + hid_svc->led_state_event_callback = NULL; + hid_svc->led_state_ctx = NULL; +} + +bool hid_svc_update_report_map(const uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value( + hid_svc->svc_handle, hid_svc->report_map_char_handle, 0, len, data); + if(status) { + FURI_LOG_E(TAG, "Failed updating report map characteristic: %d", status); + return false; + } + return true; +} + +bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value( + hid_svc->svc_handle, hid_svc->report_char_handle[input_report_num], 0, len, data); + if(status) { + FURI_LOG_E(TAG, "Failed updating report characteristic: %d", status); + return false; + } + return true; +} + +bool hid_svc_update_info(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = + aci_gatt_update_char_value(hid_svc->svc_handle, hid_svc->info_char_handle, 0, len, data); + if(status) { + FURI_LOG_E(TAG, "Failed updating info characteristic: %d", status); + return false; + } + return true; +} + +void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context) { + furi_assert(hid_svc); + furi_assert(callback); + furi_assert(context); + + hid_svc->led_state_event_callback = callback; + hid_svc->led_state_ctx = context; +} + +bool hid_svc_is_started() { + return hid_svc != NULL; +} + +void hid_svc_stop() { + tBleStatus status; + if(hid_svc) { + // Delete characteristics + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_map_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Report Map characteristic: %d", status); + } +#if(HID_SVC_INPUT_REPORT_COUNT != 0) + for(uint8_t i = 0; i < HID_SVC_REPORT_COUNT; i++) { + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_char_handle[i]); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Report characteristic: %d", status); + } + } +#endif + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->protocol_mode_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Protocol Mode characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->info_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Information characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->ctrl_point_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Control Point characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->led_state_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete led state characteristic: %d", status); + } + // Delete service + status = aci_gatt_del_service(hid_svc->svc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete HID service: %d", status); + } + // Delete buffer size mutex + free(hid_svc); + hid_svc = NULL; + } +} diff --git a/firmware/targets/f7/ble_glue/services/hid_service.h b/firmware/targets/f7/ble_glue/hid_service.h similarity index 89% rename from firmware/targets/f7/ble_glue/services/hid_service.h rename to firmware/targets/f7/ble_glue/hid_service.h index 4d0ed4c4f9..b8f6b244d2 100644 --- a/firmware/targets/f7/ble_glue/services/hid_service.h +++ b/firmware/targets/f7/ble_glue/hid_service.h @@ -27,7 +27,6 @@ bool hid_svc_update_report_map(const uint8_t* data, uint16_t len); bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len); -// Expects data to be of length HID_SVC_INFO_LEN (4 bytes) -bool hid_svc_update_info(uint8_t* data); +bool hid_svc_update_info(uint8_t* data, uint16_t len); void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context); diff --git a/firmware/targets/f7/ble_glue/services/serial_service.c b/firmware/targets/f7/ble_glue/serial_service.c similarity index 57% rename from firmware/targets/f7/ble_glue/services/serial_service.c rename to firmware/targets/f7/ble_glue/serial_service.c index ab009bbfcb..c6421dc28f 100644 --- a/firmware/targets/f7/ble_glue/services/serial_service.c +++ b/firmware/targets/f7/ble_glue/serial_service.c @@ -1,67 +1,17 @@ #include "serial_service.h" #include "app_common.h" #include -#include "gatt_char.h" #include -#include "serial_service_uuid.inc" - #define TAG "BtSerialSvc" -typedef enum { - SerialSvcGattCharacteristicTx = 0, - SerialSvcGattCharacteristicRx, - SerialSvcGattCharacteristicFlowCtrl, - SerialSvcGattCharacteristicStatus, - SerialSvcGattCharacteristicCount, -} SerialSvcGattCharacteristicId; - -static const FlipperGattCharacteristicParams serial_svc_chars[SerialSvcGattCharacteristicCount] = { - [SerialSvcGattCharacteristicTx] = - {.name = "TX", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = SERIAL_SVC_DATA_LEN_MAX, - .uuid.Char_UUID_128 = SERIAL_SVC_TX_CHAR_UUID, - .uuid_type = UUID_TYPE_128, - .char_properties = CHAR_PROP_READ | CHAR_PROP_INDICATE, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_VARIABLE}, - [SerialSvcGattCharacteristicRx] = - {.name = "RX", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = SERIAL_SVC_DATA_LEN_MAX, - .uuid.Char_UUID_128 = SERIAL_SVC_RX_CHAR_UUID, - .uuid_type = UUID_TYPE_128, - .char_properties = CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, - .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE, - .is_variable = CHAR_VALUE_LEN_VARIABLE}, - [SerialSvcGattCharacteristicFlowCtrl] = - {.name = "Flow control", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = sizeof(uint32_t), - .uuid.Char_UUID_128 = SERIAL_SVC_FLOW_CONTROL_UUID, - .uuid_type = UUID_TYPE_128, - .char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [SerialSvcGattCharacteristicStatus] = { - .name = "RPC status", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = sizeof(SerialServiceRpcStatus), - .uuid.Char_UUID_128 = SERIAL_SVC_RPC_STATUS_UUID, - .uuid_type = UUID_TYPE_128, - .char_properties = CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_NOTIFY, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, - .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE, - .is_variable = CHAR_VALUE_LEN_CONSTANT}}; - typedef struct { uint16_t svc_handle; - FlipperGattCharacteristicInstance chars[SerialSvcGattCharacteristicCount]; + uint16_t rx_char_handle; + uint16_t tx_char_handle; + uint16_t flow_ctrl_char_handle; + uint16_t rpc_status_char_handle; FuriMutex* buff_size_mtx; uint32_t buff_size; uint16_t bytes_ready_to_receive; @@ -71,6 +21,17 @@ typedef struct { static SerialSvc* serial_svc = NULL; +static const uint8_t service_uuid[] = + {0x00, 0x00, 0xfe, 0x60, 0xcc, 0x7a, 0x48, 0x2a, 0x98, 0x4a, 0x7f, 0x2e, 0xd5, 0xb3, 0xe5, 0x8f}; +static const uint8_t char_tx_uuid[] = + {0x00, 0x00, 0xfe, 0x61, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; +static const uint8_t char_rx_uuid[] = + {0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; +static const uint8_t flow_ctrl_uuid[] = + {0x00, 0x00, 0xfe, 0x63, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; +static const uint8_t rpc_status_uuid[] = + {0x00, 0x00, 0xfe, 0x64, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19}; + static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data); @@ -79,14 +40,11 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { attribute_modified = (aci_gatt_attribute_modified_event_rp0*)blecore_evt->data; - if(attribute_modified->Attr_Handle == - serial_svc->chars[SerialSvcGattCharacteristicRx].handle + 2) { + if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 2) { // Descriptor handle ret = SVCCTL_EvtAckFlowEnable; FURI_LOG_D(TAG, "RX descriptor event"); - } else if( - attribute_modified->Attr_Handle == - serial_svc->chars[SerialSvcGattCharacteristicRx].handle + 1) { + } else if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 1) { FURI_LOG_D(TAG, "Received %d bytes", attribute_modified->Attr_Data_Length); if(serial_svc->callback) { furi_check( @@ -112,9 +70,7 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } ret = SVCCTL_EvtAckFlowEnable; - } else if( - attribute_modified->Attr_Handle == - serial_svc->chars[SerialSvcGattCharacteristicStatus].handle + 1) { + } else if(attribute_modified->Attr_Handle == serial_svc->rpc_status_char_handle + 1) { SerialServiceRpcStatus* rpc_status = (SerialServiceRpcStatus*)attribute_modified->Attr_Data; if(*rpc_status == SerialServiceRpcStatusNotActive) { @@ -141,12 +97,18 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void* event) { } static void serial_svc_update_rpc_char(SerialServiceRpcStatus status) { - flipper_gatt_characteristic_update( - serial_svc->svc_handle, &serial_svc->chars[SerialSvcGattCharacteristicStatus], &status); + tBleStatus ble_status = aci_gatt_update_char_value( + serial_svc->svc_handle, + serial_svc->rpc_status_char_handle, + 0, + sizeof(SerialServiceRpcStatus), + (uint8_t*)&status); + if(ble_status) { + FURI_LOG_E(TAG, "Failed to update RPC status char: %d", ble_status); + } } void serial_svc_start() { - UNUSED(serial_svc_chars); tBleStatus status; serial_svc = malloc(sizeof(SerialSvc)); // Register event handler @@ -154,17 +116,72 @@ void serial_svc_start() { // Add service status = aci_gatt_add_service( - UUID_TYPE_128, &service_uuid, PRIMARY_SERVICE, 12, &serial_svc->svc_handle); + UUID_TYPE_128, (Service_UUID_t*)service_uuid, PRIMARY_SERVICE, 12, &serial_svc->svc_handle); if(status) { FURI_LOG_E(TAG, "Failed to add Serial service: %d", status); } - // Add characteristics - for(uint8_t i = 0; i < SerialSvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_init( - serial_svc->svc_handle, &serial_svc_chars[i], &serial_svc->chars[i]); + // Add RX characteristics + status = aci_gatt_add_char( + serial_svc->svc_handle, + UUID_TYPE_128, + (const Char_UUID_t*)char_rx_uuid, + SERIAL_SVC_DATA_LEN_MAX, + CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE | CHAR_PROP_READ, + ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_VARIABLE, + &serial_svc->rx_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add RX characteristic: %d", status); } + // Add TX characteristic + status = aci_gatt_add_char( + serial_svc->svc_handle, + UUID_TYPE_128, + (const Char_UUID_t*)char_tx_uuid, + SERIAL_SVC_DATA_LEN_MAX, + CHAR_PROP_READ | CHAR_PROP_INDICATE, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &serial_svc->tx_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add TX characteristic: %d", status); + } + // Add Flow Control characteristic + status = aci_gatt_add_char( + serial_svc->svc_handle, + UUID_TYPE_128, + (const Char_UUID_t*)flow_ctrl_uuid, + sizeof(uint32_t), + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_AUTHEN_READ, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &serial_svc->flow_ctrl_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add Flow Control characteristic: %d", status); + } + // Add RPC status characteristic + status = aci_gatt_add_char( + serial_svc->svc_handle, + UUID_TYPE_128, + (const Char_UUID_t*)rpc_status_uuid, + sizeof(SerialServiceRpcStatus), + CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &serial_svc->rpc_status_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add RPC status characteristic: %d", status); + } serial_svc_update_rpc_char(SerialServiceRpcStatusNotActive); // Allocate buffer size mutex serial_svc->buff_size_mtx = furi_mutex_alloc(FuriMutexTypeNormal); @@ -179,12 +196,13 @@ void serial_svc_set_callbacks( serial_svc->context = context; serial_svc->buff_size = buff_size; serial_svc->bytes_ready_to_receive = buff_size; - uint32_t buff_size_reversed = REVERSE_BYTES_U32(serial_svc->buff_size); - flipper_gatt_characteristic_update( + aci_gatt_update_char_value( serial_svc->svc_handle, - &serial_svc->chars[SerialSvcGattCharacteristicFlowCtrl], - &buff_size_reversed); + serial_svc->flow_ctrl_char_handle, + 0, + sizeof(uint32_t), + (uint8_t*)&buff_size_reversed); } void serial_svc_notify_buffer_is_empty() { @@ -195,12 +213,13 @@ void serial_svc_notify_buffer_is_empty() { if(serial_svc->bytes_ready_to_receive == 0) { FURI_LOG_D(TAG, "Buffer is empty. Notifying client"); serial_svc->bytes_ready_to_receive = serial_svc->buff_size; - uint32_t buff_size_reversed = REVERSE_BYTES_U32(serial_svc->buff_size); - flipper_gatt_characteristic_update( + aci_gatt_update_char_value( serial_svc->svc_handle, - &serial_svc->chars[SerialSvcGattCharacteristicFlowCtrl], - &buff_size_reversed); + serial_svc->flow_ctrl_char_handle, + 0, + sizeof(uint32_t), + (uint8_t*)&buff_size_reversed); } furi_check(furi_mutex_release(serial_svc->buff_size_mtx) == FuriStatusOk); } @@ -208,8 +227,22 @@ void serial_svc_notify_buffer_is_empty() { void serial_svc_stop() { tBleStatus status; if(serial_svc) { - for(uint8_t i = 0; i < SerialSvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_delete(serial_svc->svc_handle, &serial_svc->chars[i]); + // Delete characteristics + status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->tx_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete TX characteristic: %d", status); + } + status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->rx_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete RX characteristic: %d", status); + } + status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->flow_ctrl_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Flow Control characteristic: %d", status); + } + status = aci_gatt_del_char(serial_svc->svc_handle, serial_svc->rpc_status_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete RPC Status characteristic: %d", status); } // Delete service status = aci_gatt_del_service(serial_svc->svc_handle); @@ -240,7 +273,7 @@ bool serial_svc_update_tx(uint8_t* data, uint16_t data_len) { tBleStatus result = aci_gatt_update_char_value_ext( 0, serial_svc->svc_handle, - serial_svc->chars[SerialSvcGattCharacteristicTx].handle, + serial_svc->tx_char_handle, remained ? 0x00 : 0x02, data_len, value_offset, diff --git a/firmware/targets/f7/ble_glue/services/serial_service.h b/firmware/targets/f7/ble_glue/serial_service.h similarity index 100% rename from firmware/targets/f7/ble_glue/services/serial_service.h rename to firmware/targets/f7/ble_glue/serial_service.h diff --git a/firmware/targets/f7/ble_glue/services/dev_info_service.c b/firmware/targets/f7/ble_glue/services/dev_info_service.c deleted file mode 100644 index 5bee97b416..0000000000 --- a/firmware/targets/f7/ble_glue/services/dev_info_service.c +++ /dev/null @@ -1,176 +0,0 @@ -#include "dev_info_service.h" -#include "app_common.h" -#include "gatt_char.h" -#include - -#include -#include -#include - -#include "dev_info_service_uuid.inc" - -#define TAG "BtDevInfoSvc" - -typedef enum { - DevInfoSvcGattCharacteristicMfgName = 0, - DevInfoSvcGattCharacteristicSerial, - DevInfoSvcGattCharacteristicFirmwareRev, - DevInfoSvcGattCharacteristicSoftwareRev, - DevInfoSvcGattCharacteristicRpcVersion, - DevInfoSvcGattCharacteristicCount, -} DevInfoSvcGattCharacteristicId; - -#define DEVICE_INFO_HARDWARE_REV_SIZE 4 -typedef struct { - uint16_t service_handle; - FlipperGattCharacteristicInstance characteristics[DevInfoSvcGattCharacteristicCount]; - FuriString* version_string; - char hardware_revision[DEVICE_INFO_HARDWARE_REV_SIZE]; -} DevInfoSvc; - -static DevInfoSvc* dev_info_svc = NULL; - -static const char dev_info_man_name[] = "Flipper Devices Inc."; -static const char dev_info_serial_num[] = "1.0"; -static const char dev_info_rpc_version[] = TOSTRING(PROTOBUF_MAJOR_VERSION.PROTOBUF_MINOR_VERSION); - -static bool dev_info_char_firmware_rev_callback( - const void* context, - const uint8_t** data, - uint16_t* data_len) { - const DevInfoSvc* dev_info_svc = *(DevInfoSvc**)context; - *data_len = sizeof(dev_info_svc->hardware_revision); - if(data) { - *data = (const uint8_t*)&dev_info_svc->hardware_revision; - } - return false; -} - -static bool dev_info_char_software_rev_callback( - const void* context, - const uint8_t** data, - uint16_t* data_len) { - const DevInfoSvc* dev_info_svc = *(DevInfoSvc**)context; - *data_len = furi_string_size(dev_info_svc->version_string); - if(data) { - *data = (const uint8_t*)furi_string_get_cstr(dev_info_svc->version_string); - } - return false; -} - -static const FlipperGattCharacteristicParams dev_info_svc_chars[DevInfoSvcGattCharacteristicCount] = - {[DevInfoSvcGattCharacteristicMfgName] = - {.name = "Manufacturer Name", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = sizeof(dev_info_man_name) - 1, - .data.fixed.ptr = (const uint8_t*)&dev_info_man_name, - .uuid.Char_UUID_16 = MANUFACTURER_NAME_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [DevInfoSvcGattCharacteristicSerial] = - {.name = "Serial Number", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = sizeof(dev_info_serial_num) - 1, - .data.fixed.ptr = (const uint8_t*)&dev_info_serial_num, - .uuid.Char_UUID_16 = SERIAL_NUMBER_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [DevInfoSvcGattCharacteristicFirmwareRev] = - {.name = "Firmware Revision", - .data_prop_type = FlipperGattCharacteristicDataCallback, - .data.callback.context = &dev_info_svc, - .data.callback.fn = dev_info_char_firmware_rev_callback, - .uuid.Char_UUID_16 = FIRMWARE_REVISION_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [DevInfoSvcGattCharacteristicSoftwareRev] = - {.name = "Software Revision", - .data_prop_type = FlipperGattCharacteristicDataCallback, - .data.callback.context = &dev_info_svc, - .data.callback.fn = dev_info_char_software_rev_callback, - .uuid.Char_UUID_16 = SOFTWARE_REVISION_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [DevInfoSvcGattCharacteristicRpcVersion] = { - .name = "RPC Version", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = sizeof(dev_info_rpc_version) - 1, - .data.fixed.ptr = (const uint8_t*)&dev_info_rpc_version, - .uuid.Char_UUID_128 = DEV_INVO_RPC_VERSION_UID, - .uuid_type = UUID_TYPE_128, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_AUTHEN_READ, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}}; - -void dev_info_svc_start() { - dev_info_svc = malloc(sizeof(DevInfoSvc)); - dev_info_svc->version_string = furi_string_alloc_printf( - "%s %s %s %s", - version_get_githash(NULL), - version_get_version(NULL), - version_get_gitbranchnum(NULL), - version_get_builddate(NULL)); - snprintf( - dev_info_svc->hardware_revision, - sizeof(dev_info_svc->hardware_revision), - "%d", - version_get_target(NULL)); - tBleStatus status; - - // Add Device Information Service - uint16_t uuid = DEVICE_INFORMATION_SERVICE_UUID; - status = aci_gatt_add_service( - UUID_TYPE_16, - (Service_UUID_t*)&uuid, - PRIMARY_SERVICE, - 1 + 2 * DevInfoSvcGattCharacteristicCount, - &dev_info_svc->service_handle); - if(status) { - FURI_LOG_E(TAG, "Failed to add Device Information Service: %d", status); - } - - for(size_t i = 0; i < DevInfoSvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_init( - dev_info_svc->service_handle, - &dev_info_svc_chars[i], - &dev_info_svc->characteristics[i]); - flipper_gatt_characteristic_update( - dev_info_svc->service_handle, &dev_info_svc->characteristics[i], NULL); - } -} - -void dev_info_svc_stop() { - tBleStatus status; - if(dev_info_svc) { - furi_string_free(dev_info_svc->version_string); - // Delete service characteristics - for(size_t i = 0; i < DevInfoSvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_delete( - dev_info_svc->service_handle, &dev_info_svc->characteristics[i]); - } - // Delete service - status = aci_gatt_del_service(dev_info_svc->service_handle); - if(status) { - FURI_LOG_E(TAG, "Failed to delete device info service: %d", status); - } - free(dev_info_svc); - dev_info_svc = NULL; - } -} - -bool dev_info_svc_is_started() { - return dev_info_svc != NULL; -} diff --git a/firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc b/firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc deleted file mode 100644 index ad520f62e5..0000000000 --- a/firmware/targets/f7/ble_glue/services/dev_info_service_uuid.inc +++ /dev/null @@ -1,3 +0,0 @@ -#define DEV_INVO_RPC_VERSION_UID \ - { 0x33, 0xa9, 0xb5, 0x3e, 0x87, 0x5d, 0x1a, 0x8e, 0xc8, 0x47, 0x5e, 0xae, 0x6d, 0x66, 0xf6, 0x03 } - diff --git a/firmware/targets/f7/ble_glue/services/gatt_char.c b/firmware/targets/f7/ble_glue/services/gatt_char.c deleted file mode 100644 index 9b6a44f61b..0000000000 --- a/firmware/targets/f7/ble_glue/services/gatt_char.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "gatt_char.h" - -#include - -#define TAG "GattChar" - -#define GATT_MIN_READ_KEY_SIZE (10) - -void flipper_gatt_characteristic_init( - uint16_t svc_handle, - const FlipperGattCharacteristicParams* char_descriptor, - FlipperGattCharacteristicInstance* char_instance) { - furi_assert(char_descriptor); - furi_assert(char_instance); - - // Copy the descriptor to the instance, since it may point to stack memory - // TODO: only copy if really comes from stack - char_instance->characteristic = malloc(sizeof(FlipperGattCharacteristicParams)); - memcpy( - (void*)char_instance->characteristic, - char_descriptor, - sizeof(FlipperGattCharacteristicParams)); - - uint16_t char_data_size = 0; - if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataFixed) { - char_data_size = char_descriptor->data.fixed.length; - } else if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataCallback) { - char_descriptor->data.callback.fn( - char_descriptor->data.callback.context, NULL, &char_data_size); - } - - tBleStatus status = aci_gatt_add_char( - svc_handle, - char_descriptor->uuid_type, - &char_descriptor->uuid, - char_data_size, - char_descriptor->char_properties, - char_descriptor->security_permissions, - char_descriptor->gatt_evt_mask, - GATT_MIN_READ_KEY_SIZE, - char_descriptor->is_variable, - &char_instance->handle); - if(status) { - FURI_LOG_E(TAG, "Failed to add %s char: %d", char_descriptor->name, status); - } - - char_instance->descriptor_handle = 0; - if((status == 0) && char_descriptor->descriptor_params) { - uint8_t const* char_data = NULL; - const FlipperGattCharacteristicDescriptorParams* char_data_descriptor = - char_descriptor->descriptor_params; - bool release_data = char_data_descriptor->data_callback.fn( - char_data_descriptor->data_callback.context, &char_data, &char_data_size); - - status = aci_gatt_add_char_desc( - svc_handle, - char_instance->handle, - char_data_descriptor->uuid_type, - &char_data_descriptor->uuid, - char_data_descriptor->max_length, - char_data_size, - char_data, - char_data_descriptor->security_permissions, - char_data_descriptor->access_permissions, - char_data_descriptor->gatt_evt_mask, - GATT_MIN_READ_KEY_SIZE, - char_data_descriptor->is_variable, - &char_instance->descriptor_handle); - if(status) { - FURI_LOG_E(TAG, "Failed to add %s char descriptor: %d", char_descriptor->name, status); - } - if(release_data) { - free((void*)char_data); - } - } -} - -void flipper_gatt_characteristic_delete( - uint16_t svc_handle, - FlipperGattCharacteristicInstance* char_instance) { - tBleStatus status = aci_gatt_del_char(svc_handle, char_instance->handle); - if(status) { - FURI_LOG_E( - TAG, "Failed to delete %s char: %d", char_instance->characteristic->name, status); - } - free((void*)char_instance->characteristic); -} - -bool flipper_gatt_characteristic_update( - uint16_t svc_handle, - FlipperGattCharacteristicInstance* char_instance, - const void* source) { - furi_assert(char_instance); - const FlipperGattCharacteristicParams* char_descriptor = char_instance->characteristic; - FURI_LOG_D(TAG, "Updating %s char", char_descriptor->name); - - const uint8_t* char_data = NULL; - uint16_t char_data_size = 0; - bool release_data = false; - if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataFixed) { - char_data = char_descriptor->data.fixed.ptr; - if(source) { - char_data = (uint8_t*)source; - } - char_data_size = char_descriptor->data.fixed.length; - } else if(char_descriptor->data_prop_type == FlipperGattCharacteristicDataCallback) { - const void* context = char_descriptor->data.callback.context; - if(source) { - context = source; - } - release_data = char_descriptor->data.callback.fn(context, &char_data, &char_data_size); - } - - tBleStatus result = aci_gatt_update_char_value( - svc_handle, char_instance->handle, 0, char_data_size, char_data); - if(result) { - FURI_LOG_E(TAG, "Failed updating %s characteristic: %d", char_descriptor->name, result); - } - if(release_data) { - free((void*)char_data); - } - return result != BLE_STATUS_SUCCESS; -} \ No newline at end of file diff --git a/firmware/targets/f7/ble_glue/services/gatt_char.h b/firmware/targets/f7/ble_glue/services/gatt_char.h deleted file mode 100644 index 959ab67a49..0000000000 --- a/firmware/targets/f7/ble_glue/services/gatt_char.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Callback signature for getting characteristic data -// Is called when characteristic is created to get max data length. Data ptr is NULL in this case -// The result is passed to aci_gatt_add_char as "Char_Value_Length" -// For updates, called with a context - see flipper_gatt_characteristic_update -// Returns true if *data ownership is transferred to the caller and will be freed -typedef bool (*cbFlipperGattCharacteristicData)( - const void* context, - const uint8_t** data, - uint16_t* data_len); - -typedef enum { - FlipperGattCharacteristicDataFixed, - FlipperGattCharacteristicDataCallback, -} FlipperGattCharacteristicDataType; - -typedef struct { - Char_Desc_Uuid_t uuid; - struct { - cbFlipperGattCharacteristicData fn; - const void* context; - } data_callback; - uint8_t uuid_type; - uint8_t max_length; - uint8_t security_permissions; - uint8_t access_permissions; - uint8_t gatt_evt_mask; - uint8_t is_variable; -} FlipperGattCharacteristicDescriptorParams; - -typedef struct { - const char* name; - FlipperGattCharacteristicDescriptorParams* descriptor_params; - union { - struct { - const uint8_t* ptr; - uint16_t length; - } fixed; - struct { - cbFlipperGattCharacteristicData fn; - const void* context; - } callback; - } data; - Char_UUID_t uuid; - // Some packed bitfields to save space - FlipperGattCharacteristicDataType data_prop_type : 2; - uint8_t is_variable : 2; - uint8_t uuid_type : 2; - uint8_t char_properties; - uint8_t security_permissions; - uint8_t gatt_evt_mask; -} FlipperGattCharacteristicParams; - -_Static_assert( - sizeof(FlipperGattCharacteristicParams) == 36, - "FlipperGattCharacteristicParams size must be 36 bytes"); - -typedef struct { - const FlipperGattCharacteristicParams* characteristic; - uint16_t handle; - uint16_t descriptor_handle; -} FlipperGattCharacteristicInstance; - -// Initialize a characteristic instance; copies the characteristic descriptor into the instance -void flipper_gatt_characteristic_init( - uint16_t svc_handle, - const FlipperGattCharacteristicParams* char_descriptor, - FlipperGattCharacteristicInstance* char_instance); - -// Delete a characteristic instance; frees the copied characteristic descriptor from the instance -void flipper_gatt_characteristic_delete( - uint16_t svc_handle, - FlipperGattCharacteristicInstance* char_instance); - -// Update a characteristic instance; if source==NULL, uses the data from the characteristic -// - For fixed data, fixed.ptr is used as the source if source==NULL -// - For callback-based data, collback.context is passed as the context if source==NULL -bool flipper_gatt_characteristic_update( - uint16_t svc_handle, - FlipperGattCharacteristicInstance* char_instance, - const void* source); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/firmware/targets/f7/ble_glue/services/hid_service.c b/firmware/targets/f7/ble_glue/services/hid_service.c deleted file mode 100644 index 11f10b7b38..0000000000 --- a/firmware/targets/f7/ble_glue/services/hid_service.c +++ /dev/null @@ -1,365 +0,0 @@ -#include "hid_service.h" -#include "app_common.h" -#include -#include "gatt_char.h" - -#include - -#define TAG "BtHid" - -typedef enum { - HidSvcGattCharacteristicProtocolMode = 0, - HidSvcGattCharacteristicReportMap, - HidSvcGattCharacteristicInfo, - HidSvcGattCharacteristicCtrlPoint, - HidSvcGattCharacteristicLed, - HidSvcGattCharacteristicCount, -} HidSvcGattCharacteristicId; - -typedef struct { - uint8_t report_idx; - uint8_t report_type; -} HidSvcReportId; - -static_assert(sizeof(HidSvcReportId) == sizeof(uint16_t), "HidSvcReportId must be 2 bytes"); - -static bool - hid_svc_char_desc_data_callback(const void* context, const uint8_t** data, uint16_t* data_len) { - const HidSvcReportId* report_id = context; - *data_len = sizeof(HidSvcReportId); - if(data) { - *data = (const uint8_t*)report_id; - } - return false; -} - -typedef struct { - const void* data_ptr; - uint16_t data_len; -} HidSvcDataWrapper; - -static bool - hid_svc_report_data_callback(const void* context, const uint8_t** data, uint16_t* data_len) { - const HidSvcDataWrapper* report_data = context; - if(data) { - *data = report_data->data_ptr; - *data_len = report_data->data_len; - } else { - *data_len = HID_SVC_REPORT_MAP_MAX_LEN; - } - return false; -} - -// LED Descriptor params for BadBT - -static uint8_t led_desc_context_buf[2] = {HID_SVC_REPORT_COUNT + 1, 2}; - -static FlipperGattCharacteristicDescriptorParams hid_svc_char_descr_led = { - .uuid_type = UUID_TYPE_16, - .uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID, - .max_length = HID_SVC_REPORT_REF_LEN, - .data_callback.fn = hid_svc_char_desc_data_callback, - .data_callback.context = led_desc_context_buf, - .security_permissions = ATTR_PERMISSION_NONE, - .access_permissions = ATTR_ACCESS_READ_WRITE, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT, -}; - -static const FlipperGattCharacteristicParams hid_svc_chars[HidSvcGattCharacteristicCount] = { - [HidSvcGattCharacteristicProtocolMode] = - {.name = "Protocol Mode", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = 1, - .uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP, - .security_permissions = ATTR_PERMISSION_NONE, - .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [HidSvcGattCharacteristicReportMap] = - {.name = "Report Map", - .data_prop_type = FlipperGattCharacteristicDataCallback, - .data.callback.fn = hid_svc_report_data_callback, - .data.callback.context = NULL, - .uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_NONE, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_VARIABLE}, - [HidSvcGattCharacteristicInfo] = - {.name = "HID Information", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = HID_SVC_INFO_LEN, - .data.fixed.ptr = NULL, - .uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ, - .security_permissions = ATTR_PERMISSION_NONE, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [HidSvcGattCharacteristicCtrlPoint] = - {.name = "HID Control Point", - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = HID_SVC_CONTROL_POINT_LEN, - .uuid.Char_UUID_16 = HID_CONTROL_POINT_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_WRITE_WITHOUT_RESP, - .security_permissions = ATTR_PERMISSION_NONE, - .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE, - .is_variable = CHAR_VALUE_LEN_CONSTANT}, - [HidSvcGattCharacteristicLed] = - { - .name = - "HID LED State", // LED Characteristic and descriptor for BadBT to get numlock state for altchars - .data_prop_type = FlipperGattCharacteristicDataFixed, - .data.fixed.length = 1, - .uuid.Char_UUID_16 = REPORT_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP | CHAR_PROP_WRITE, - .security_permissions = ATTR_PERMISSION_NONE, - .gatt_evt_mask = GATT_NOTIFY_ATTRIBUTE_WRITE | - GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP, - .is_variable = CHAR_VALUE_LEN_CONSTANT, - .descriptor_params = &hid_svc_char_descr_led, - }, -}; - -static const FlipperGattCharacteristicDescriptorParams hid_svc_char_descr_template = { - .uuid_type = UUID_TYPE_16, - .uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID, - .max_length = HID_SVC_REPORT_REF_LEN, - .data_callback.fn = hid_svc_char_desc_data_callback, - .security_permissions = ATTR_PERMISSION_NONE, - .access_permissions = ATTR_ACCESS_READ_WRITE, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_CONSTANT, -}; - -static const FlipperGattCharacteristicParams hid_svc_report_template = { - .name = "Report", - .data_prop_type = FlipperGattCharacteristicDataCallback, - .data.callback.fn = hid_svc_report_data_callback, - .data.callback.context = NULL, - .uuid.Char_UUID_16 = REPORT_CHAR_UUID, - .uuid_type = UUID_TYPE_16, - .char_properties = CHAR_PROP_READ | CHAR_PROP_NOTIFY, - .security_permissions = ATTR_PERMISSION_NONE, - .gatt_evt_mask = GATT_DONT_NOTIFY_EVENTS, - .is_variable = CHAR_VALUE_LEN_VARIABLE, -}; - -typedef struct { - uint16_t svc_handle; - FlipperGattCharacteristicInstance chars[HidSvcGattCharacteristicCount]; - FlipperGattCharacteristicInstance input_report_chars[HID_SVC_INPUT_REPORT_COUNT]; - FlipperGattCharacteristicInstance output_report_chars[HID_SVC_OUTPUT_REPORT_COUNT]; - FlipperGattCharacteristicInstance feature_report_chars[HID_SVC_FEATURE_REPORT_COUNT]; - // led state - HidLedStateEventCallback led_state_event_callback; - void* led_state_ctx; -} HIDSvc; - -static HIDSvc* hid_svc = NULL; - -static SVCCTL_EvtAckStatus_t hid_svc_event_handler(void* event) { - SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; - hci_event_pckt* event_pckt = (hci_event_pckt*)(((hci_uart_pckt*)event)->data); - evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data; - // aci_gatt_attribute_modified_event_rp0* attribute_modified; - if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { - if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { - // Process modification events - ret = SVCCTL_EvtAckFlowEnable; - } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { - // Process notification confirmation - ret = SVCCTL_EvtAckFlowEnable; - } else if(blecore_evt->ecode == ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE) { - // LED Characteristic and descriptor for BadBT to get numlock state for altchars - // - // Process write request - aci_gatt_write_permit_req_event_rp0* req = - (aci_gatt_write_permit_req_event_rp0*)blecore_evt->data; - - furi_check(hid_svc->led_state_event_callback && hid_svc->led_state_ctx); - - // this check is likely to be incorrect, it will actually work in our case - // but we need to investigate gatt api to see what is the rules - // that specify attibute handle value from char handle (or the reverse) - if(req->Attribute_Handle == (hid_svc->chars[HidSvcGattCharacteristicLed].handle + 1)) { - hid_svc->led_state_event_callback(req->Data[0], hid_svc->led_state_ctx); - aci_gatt_write_resp( - req->Connection_Handle, - req->Attribute_Handle, - 0x00, /* write_status = 0 (no error))*/ - 0x00, /* err_code */ - req->Data_Length, - req->Data); - aci_gatt_write_char_value( - req->Connection_Handle, - hid_svc->chars[HidSvcGattCharacteristicLed].handle, - req->Data_Length, - req->Data); - ret = SVCCTL_EvtAckFlowEnable; - } - } - } - return ret; -} - -void hid_svc_start() { - tBleStatus status; - hid_svc = malloc(sizeof(HIDSvc)); - Service_UUID_t svc_uuid = {}; - - // Register event handler - SVCCTL_RegisterSvcHandler(hid_svc_event_handler); - // Add service - svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID; - /** - * Add Human Interface Device Service - */ - status = aci_gatt_add_service( - UUID_TYPE_16, - &svc_uuid, - PRIMARY_SERVICE, - 2 + /* protocol mode */ - (4 * HID_SVC_INPUT_REPORT_COUNT) + (3 * HID_SVC_OUTPUT_REPORT_COUNT) + - (3 * HID_SVC_FEATURE_REPORT_COUNT) + 1 + 2 + 2 + 2 + - 4, /* Service + Report Map + HID Information + HID Control Point + LED state */ - &hid_svc->svc_handle); - if(status) { - FURI_LOG_E(TAG, "Failed to add HID service: %d", status); - } - - for(size_t i = 0; i < HidSvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_init( - hid_svc->svc_handle, &hid_svc_chars[i], &hid_svc->chars[i]); - } - uint8_t protocol_mode = 1; - flipper_gatt_characteristic_update( - hid_svc->svc_handle, - &hid_svc->chars[HidSvcGattCharacteristicProtocolMode], - &protocol_mode); - - // reports - FlipperGattCharacteristicDescriptorParams hid_svc_char_descr; - FlipperGattCharacteristicParams report_char; - HidSvcReportId report_id; - - memcpy(&hid_svc_char_descr, &hid_svc_char_descr_template, sizeof(hid_svc_char_descr)); - memcpy(&report_char, &hid_svc_report_template, sizeof(report_char)); - - hid_svc_char_descr.data_callback.context = &report_id; - report_char.descriptor_params = &hid_svc_char_descr; - - typedef struct { - uint8_t report_type; - uint8_t report_count; - FlipperGattCharacteristicInstance* chars; - } HidSvcReportCharProps; - - HidSvcReportCharProps hid_report_chars[] = { - {0x01, HID_SVC_INPUT_REPORT_COUNT, hid_svc->input_report_chars}, - {0x02, HID_SVC_OUTPUT_REPORT_COUNT, hid_svc->output_report_chars}, - {0x03, HID_SVC_FEATURE_REPORT_COUNT, hid_svc->feature_report_chars}, - }; - - for(size_t report_type_idx = 0; report_type_idx < COUNT_OF(hid_report_chars); - report_type_idx++) { - report_id.report_type = hid_report_chars[report_type_idx].report_type; - for(size_t report_idx = 0; report_idx < hid_report_chars[report_type_idx].report_count; - report_idx++) { - report_id.report_idx = report_idx + 1; - flipper_gatt_characteristic_init( - hid_svc->svc_handle, - &report_char, - &hid_report_chars[report_type_idx].chars[report_idx]); - } - } -} - -bool hid_svc_update_report_map(const uint8_t* data, uint16_t len) { - furi_assert(data); - furi_assert(hid_svc); - - HidSvcDataWrapper report_data = { - .data_ptr = data, - .data_len = len, - }; - return flipper_gatt_characteristic_update( - hid_svc->svc_handle, &hid_svc->chars[HidSvcGattCharacteristicReportMap], &report_data); -} - -bool hid_svc_update_input_report(uint8_t input_report_num, uint8_t* data, uint16_t len) { - furi_assert(data); - furi_assert(hid_svc); - furi_assert(input_report_num < HID_SVC_INPUT_REPORT_COUNT); - - HidSvcDataWrapper report_data = { - .data_ptr = data, - .data_len = len, - }; - return flipper_gatt_characteristic_update( - hid_svc->svc_handle, &hid_svc->input_report_chars[input_report_num], &report_data); -} - -bool hid_svc_update_info(uint8_t* data) { - furi_assert(data); - furi_assert(hid_svc); - - return flipper_gatt_characteristic_update( - hid_svc->svc_handle, &hid_svc->chars[HidSvcGattCharacteristicInfo], &data); -} - -void hid_svc_register_led_state_callback(HidLedStateEventCallback callback, void* context) { - furi_assert(hid_svc); - furi_assert(callback); - furi_assert(context); - - hid_svc->led_state_event_callback = callback; - hid_svc->led_state_ctx = context; -} - -bool hid_svc_is_started() { - return hid_svc != NULL; -} - -void hid_svc_stop() { - tBleStatus status; - if(hid_svc) { - // Delete characteristics - for(size_t i = 0; i < HidSvcGattCharacteristicCount; i++) { - flipper_gatt_characteristic_delete(hid_svc->svc_handle, &hid_svc->chars[i]); - } - - typedef struct { - uint8_t report_count; - FlipperGattCharacteristicInstance* chars; - } HidSvcReportCharProps; - - HidSvcReportCharProps hid_report_chars[] = { - {HID_SVC_INPUT_REPORT_COUNT, hid_svc->input_report_chars}, - {HID_SVC_OUTPUT_REPORT_COUNT, hid_svc->output_report_chars}, - {HID_SVC_FEATURE_REPORT_COUNT, hid_svc->feature_report_chars}, - }; - - for(size_t report_type_idx = 0; report_type_idx < COUNT_OF(hid_report_chars); - report_type_idx++) { - for(size_t report_idx = 0; report_idx < hid_report_chars[report_type_idx].report_count; - report_idx++) { - flipper_gatt_characteristic_delete( - hid_svc->svc_handle, &hid_report_chars[report_type_idx].chars[report_idx]); - } - } - - // Delete service - status = aci_gatt_del_service(hid_svc->svc_handle); - if(status) { - FURI_LOG_E(TAG, "Failed to delete HID service: %d", status); - } - free(hid_svc); - hid_svc = NULL; - } -} diff --git a/firmware/targets/f7/ble_glue/services/serial_service_uuid.inc b/firmware/targets/f7/ble_glue/services/serial_service_uuid.inc deleted file mode 100644 index a297d9ad60..0000000000 --- a/firmware/targets/f7/ble_glue/services/serial_service_uuid.inc +++ /dev/null @@ -1,12 +0,0 @@ - -static const Service_UUID_t service_uuid = { .Service_UUID_128 = \ - { 0x00, 0x00, 0xfe, 0x60, 0xcc, 0x7a, 0x48, 0x2a, 0x98, 0x4a, 0x7f, 0x2e, 0xd5, 0xb3, 0xe5, 0x8f }}; - -#define SERIAL_SVC_TX_CHAR_UUID \ - { 0x00, 0x00, 0xfe, 0x61, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 } -#define SERIAL_SVC_RX_CHAR_UUID \ - { 0x00, 0x00, 0xfe, 0x62, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 } -#define SERIAL_SVC_FLOW_CONTROL_UUID \ - { 0x00, 0x00, 0xfe, 0x63, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 } -#define SERIAL_SVC_RPC_STATUS_UUID \ - { 0x00, 0x00, 0xfe, 0x64, 0x8e, 0x22, 0x45, 0x41, 0x9d, 0x4c, 0x21, 0xed, 0xae, 0x82, 0xed, 0x19 } diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index b5fa5cb05b..1139add6cb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -8,7 +8,8 @@ #include #include #include -#include +#include "battery_service.h" + #include #define TAG "FuriHalBt" diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c b/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c index 43b2785784..860edfcd40 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt_hid.c @@ -1,11 +1,11 @@ #include #include -#include -#include -#include +#include "usb_hid.h" +#include "dev_info_service.h" +#include "battery_service.h" +#include "hid_service.h" #include -#include #define FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION (0x0101) #define FURI_HAL_BT_INFO_COUNTRY_CODE (0x00) @@ -220,7 +220,7 @@ void furi_hal_bt_hid_start() { FURI_HAL_BT_HID_INFO_FLAG_REMOTE_WAKE_MSK | FURI_HAL_BT_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK, }; - hid_svc_update_info(hid_info_val); + hid_svc_update_info(hid_info_val, sizeof(hid_info_val)); } void furi_hal_bt_hid_stop() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c b/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c index 2927d946f9..2539e6bd0e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt_serial.c @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include "dev_info_service.h" +#include "battery_service.h" +#include "serial_service.h" #include diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index a04b70ecd5..f128b1064a 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/firmware/targets/furi_hal_include/furi_hal_bt_serial.h b/firmware/targets/furi_hal_include/furi_hal_bt_serial.h index 0472d31d18..1b6e79ab07 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt_serial.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt_serial.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "serial_service.h" #ifdef __cplusplus extern "C" { From b6dbf25f85b55d4058e471b50433bdc87fd5f1f4 Mon Sep 17 00:00:00 2001 From: Leopold Date: Wed, 14 Jun 2023 18:49:26 +0800 Subject: [PATCH 07/10] furi_hal_nfc: fix rfalTransceiveBitsBlockingTx's 4th argument to bits count rather than bytes count (#2773) --- firmware/targets/f7/furi_hal/furi_hal_nfc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index 8910d887bc..c4e7ad9f98 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -467,7 +467,7 @@ bool furi_hal_nfc_emulate_nfca( buff_tx, buff_tx_len, buff_rx, - sizeof(buff_rx), + rfalConvBytesToBits(buff_rx_size), &buff_rx_len, data_type, RFAL_FWT_NONE); @@ -491,7 +491,7 @@ bool furi_hal_nfc_emulate_nfca( buff_tx, buff_tx_len, buff_rx, - sizeof(buff_rx), + rfalConvBytesToBits(buff_rx_size), &buff_rx_len, data_type, RFAL_FWT_NONE); From 8088c525518351d1e931c7e8456d8f4c37847c95 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 14 Jun 2023 18:00:24 +0300 Subject: [PATCH 08/10] fix --- scripts/version.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/version.py b/scripts/version.py index 3b2502af7b..be1c51ce7a 100644 --- a/scripts/version.py +++ b/scripts/version.py @@ -62,9 +62,11 @@ def get_version_info(self): "GIT_BRANCH": branch, "VERSION": version, "BUILD_DIRTY": dirty and 1 or 0, - "GIT_ORIGIN": ",".join(self._get_git_origins()), + "GIT_ORIGIN": "https://github.com/DarkFlippers/unleashed-firmware.git", "GIT_COMMIT_DATE": commit_date, } + + # "GIT_ORIGIN": ",".join(self._get_git_origins()), def _get_git_origins(self): try: From ee8bbdcfe057e019367b151a6271059e526e2502 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 14 Jun 2023 18:05:05 +0300 Subject: [PATCH 09/10] remake just a bit, disable external on command end --- applications/main/subghz/subghz_cli.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index 22a3ed3c70..1e50dfc256 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -779,15 +779,10 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) { static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { FuriString* cmd = furi_string_alloc(); - if(!furi_hal_power_is_otg_enabled()) { - furi_hal_power_enable_otg(); - } - + // Enable power for External CC1101 if it is connected + furi_hal_subghz_enable_ext_power(); + // Auto switch to internal radio if external radio is not available furi_delay_ms(15); - - furi_hal_subghz_select_radio_type(SubGhzRadioExternal); - furi_hal_subghz_init_radio_type(SubGhzRadioExternal); - if(!furi_hal_subghz_check_radio()) { furi_hal_subghz_select_radio_type(SubGhzRadioInternal); furi_hal_subghz_init_radio_type(SubGhzRadioInternal); @@ -849,6 +844,11 @@ static void subghz_cli_command(Cli* cli, FuriString* args, void* context) { subghz_cli_command_print_usage(); } while(false); + // Disable power for External CC1101 if it was enabled and module is connected + furi_hal_subghz_disable_ext_power(); + // Reinit SPI handles for internal radio / nfc + furi_hal_subghz_init_radio_type(SubGhzRadioInternal); + furi_string_free(cmd); } From 5d9f4b13338e67f2829311e8d725b77a2ef0f9f1 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Wed, 14 Jun 2023 18:29:59 +0300 Subject: [PATCH 10/10] Changelog & more rgb patch info --- .drone.yml | 14 +++++++------- CHANGELOG.md | 46 ++++++---------------------------------------- 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/.drone.yml b/.drone.yml index b626de5c47..d1659b756d 100644 --- a/.drone.yml +++ b/.drone.yml @@ -91,7 +91,7 @@ steps: - echo '' >> CHANGELOG.md - echo '### [Version without custom animations - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)' >> CHANGELOG.md - echo '' >> CHANGELOG.md - - echo '### [Version with RGB patch - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz&channel=release-cfw&version='${DRONE_TAG}'r)' >> CHANGELOG.md + - echo '### [Version with RGB patch - only for hardware mod! - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz&channel=release-cfw&version='${DRONE_TAG}'r)' >> CHANGELOG.md - echo '' >> CHANGELOG.md - echo '## [Version with Extra apps - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)' >> CHANGELOG.md environment: @@ -252,10 +252,10 @@ steps: [-Version without custom animations - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-${DRONE_TAG}n.tgz&channel=release-cfw&version=${DRONE_TAG}n) - [-Version with RGB patch - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_TAG}r.tgz&channel=release-cfw&version=${DRONE_TAG}r) + [-Version with RGB patch - only for hardware mod! - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_TAG}r.tgz&channel=release-cfw&version=${DRONE_TAG}r) - [-Version with RGB patch - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_TAG}r.tgz) + [-Version with RGB patch - only for hardware mod! - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_TAG}r.tgz) [-Version with Extra apps - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_TAG}e.tgz&channel=release-cfw&version=${DRONE_TAG}e)" @@ -271,7 +271,7 @@ steps: commands: - wget "https://raw.githubusercontent.com/fieu/discord.sh/e1dc1a7595efad2cad8f072f0b3531c470f5b7c8/discord.sh" - chmod +x ./discord.sh - - ./discord.sh --text 'New Unleashed firmware released!\n\nVersion - '${DRONE_TAG}'\n\n[-> Sponsor our project](https://boosty.to/mmxdev)\n\n[[Github - Changelog]](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/'${DRONE_TAG}')\n\n[-How to install firmware-](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)\n\n[-Download latest extra apps pack-](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip)\n\n[-Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/'${DRONE_TAG}'/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=release-cfw&version='${DRONE_TAG}')\n\n[-Version without custom animations - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)\n\n[-Version with RGB patch - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz&channel=release-cfw&version='${DRONE_TAG}'r)\n\n[-Version with RGB patch - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz)\n\n[-Version with Extra apps - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)' + - ./discord.sh --text 'New Unleashed firmware released!\n\nVersion - '${DRONE_TAG}'\n\n[-> Sponsor our project](https://boosty.to/mmxdev)\n\n[[Github - Changelog]](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/'${DRONE_TAG}')\n\n[-How to install firmware-](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)\n\n[-Download latest extra apps pack-](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip)\n\n[-Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/'${DRONE_TAG}'/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=release-cfw&version='${DRONE_TAG}')\n\n[-Version without custom animations - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)\n\n[-Version with RGB patch - only for hardware mod! - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz&channel=release-cfw&version='${DRONE_TAG}'r)\n\n[-Version with RGB patch - only for hardware mod! - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'r.tgz)\n\n[-Version with Extra apps - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)' - name: "Send extra pack build to telegram" image: appleboy/drone-telegram @@ -474,10 +474,10 @@ steps: [-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/dev/flipper-z-f7-update-${DRONE_BUILD_NUMBER}.tgz&channel=dev-cfw&version=${DRONE_BUILD_NUMBER}) - [-Version with RGB patch - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}r.tgz&channel=dev-cfw&version=${DRONE_BUILD_NUMBER}r) + [-Version with RGB patch - only for hardware mod! - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}r.tgz&channel=dev-cfw&version=${DRONE_BUILD_NUMBER}r) - [-Version with RGB patch - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}r.tgz) + [-Version with RGB patch - only for hardware mod! - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}r.tgz) [-Version with Extra apps - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}e.tgz&channel=dev-cfw&version=${DRONE_BUILD_NUMBER}e)" @@ -515,7 +515,7 @@ steps: commands: - wget "https://raw.githubusercontent.com/fieu/discord.sh/e1dc1a7595efad2cad8f072f0b3531c470f5b7c8/discord.sh" - chmod +x ./discord.sh - - ./discord.sh --text 'Unleashed firmware dev build successful!\n\nBuild - '${DRONE_BUILD_NUMBER}'\n\nCommit - https://github.com/DarkFlippers/unleashed-firmware/commit/'${DRONE_COMMIT_SHA}'\n\n[-> Sponsor our project](https://boosty.to/mmxdev)\n\n[-Version with Extra apps - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'e.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}'e)\n\n[-Version with RGB patch - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'r.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}'r)\n\n[-Version with RGB patch - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'r.tgz)\n\n[-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/dev/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}')' + - ./discord.sh --text 'Unleashed firmware dev build successful!\n\nBuild - '${DRONE_BUILD_NUMBER}'\n\nCommit - https://github.com/DarkFlippers/unleashed-firmware/commit/'${DRONE_COMMIT_SHA}'\n\n[-> Sponsor our project](https://boosty.to/mmxdev)\n\n[-Version with Extra apps - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'e.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}'e)\n\n[-Version with RGB patch - only for hardware mod! - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'r.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}'r)\n\n[-Version with RGB patch - only for hardware mod! - Direct download-](https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'r.tgz)\n\n[-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/dev/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}')' trigger: branch: diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dbc1db79b..a03f11808f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,44 +1,10 @@ ### New changes -* If you have copied any apps manually into `apps` folder - remove `apps` folder or that specific apps you copied on your microSD before installing this release to avoid issues due to OFW API version update! If you using regular builds or extra pack builds (e) without your manually added apps, all included apps will be installed automatically, no extra actions needed! -* Settings->LCD and Notifications will be resetted to default due to new Contrast setting from OFW -* Core2 (Crash in idle) issues was reduced to current possible minimum, you can try using DeepSleep again (Sleep Method = Default) (+ more checks was added, if you get `Slow HSE/PLL startup` message more than one time, create issue with steps what to do to reproduce it again) ------ -* Plugins: **New RFID 125KHz and iButton Fuzzers (remake from scratch + new features)** (by @gid9798 | PR #507) -* Plugins: SubGHz Bruteforcer -> Time delay (between signals) setting (hold Up in main screen(says Up to Save)) + allow more repeats (by @gid9798 & @xMasterX) -* Plugins: Update TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator) -* Plugins: Unitemp SCD30 support (PR in unitemp repo by @divinebird / fixed by @xMasterX) -* Plugins: Fix ProtoView issue #503 -> (Broken saved files with custom modulation) -* SubGHz: Added 430, 431 MHz to default list -* SubGHz: Remove broken modulation that was causing buffer overrun (fixes issue #506) -* SubGHz: Notifications fixes (by @wosk | PR #464) -* GUI: `Byte input` new feature: editor without keyboard (press Up until you get into new input, then use up/down to input values) (by @gid9798 | PR #509) -* CI/CD: Provide builds with RGB patch for modded flippers (with special led board installed) -* Infrared: `RCA` protocol support -* Infrared: Update universal remote assets - add new ACs and TCL TV -* API: Add furi_hal_version_uid_default (+ Fix TOTP) (by @ClaraCrazy | PR #502) -* OFW PR 2760: NFC: Improvements to NFC Magic app (by AloneLiberty) -* OFW PR 2756: fix: make dialog_file_browser_set_basic_options initialize all fields (by JarvisCraft) -* OFW: Fix reading Mifare Classic cards with unusual access conditions and fix emulation of unknown keys -* OFW: fbt: stable build dates -* OFW: weather_station: add oregon3 with THGR221 -* OFW: Services: simplify api (DOLPHIN_DEED->dolphin_deed - function instead of macros + remake all apps in extra pack and main fw to use new API) -> **Breaking API change, API version was changed from 29.x to 30.x** -* OFW: Core2, SRAM2: provide safety gap -* OFW: FuriHal: always clock SMPS from HSI -* OFW: ble: refactored bt gatt characteristics setup (+ remake of BT HID Led descriptor in new way to work with this changes) -* OFW: Scripts: WiFi board updater -* OFW: github: re-enabled f18 build -* OFW: added ISO15693 (NfcV) (was already added before, so we just updated it with latest changes) -* OFW: fbt: added Flipper selection when multiple are connected over USB -* OFW: fbt, ufbt: added checks for appid in app manifests -* OFW: Fix core2 permisions -* OFW: SubGhz: add subghz_protocol_registry external API (was already in our API but in different way) -* OFW: Furi: smaller critical enter and critical exit macro -* OFW: Serial_CLI: Fixing serial cli logger error so it sounds more concise -* OFW: Remove unused resources -* OFW: Dolphin: new animation -* OFW: f7: add PB9 to debug pins -* OFW: Settings: add contrast adjustment -> **Settings->LCD and Notifications will be resetted to default values one time after installing** -* OFW: FuriHal: add system setting to device info, bump device info version +* BLE: Revert BLE gatt characteristics refactoring temporarily -> **Should fix HID issues on older iOS, and maybe some issues with android app** +* SubGHz: Added external cc1101 module at CLI (by @Sil333033 & @xMasterX | PR #513) +* SubGHz: Remove unused global var +* Plugins: Fix ProtoView issue #503 again -> (Broken saved files with custom modulation) +* OFW: furi_hal_nfc: fix rfalTransceiveBitsBlockingTx's 4th argument to bits count rather than bytes count +* OFW: FuriHal: remove clock startup time tracking from clean builds #### [🎲 Download latest extra apps pack](https://github.com/xMasterX/all-the-plugins/archive/refs/heads/main.zip)