Merge branch 'DarkFlippers:dev' into dev

This commit is contained in:
Dmitry422
2026-01-26 10:42:00 +07:00
committed by GitHub
8 changed files with 46 additions and 15 deletions

View File

@@ -1,7 +1,7 @@
## Main changes
- Current API: 87.4
* SubGHz: **Cardin S449 protocol full support** (64bit keeloq) (with Add manually, and all button codes) (**use FSK12K modulation to read the remote**) (closes issues #735 #908) (by @xMasterX and @zero-mega (thanks!))
* SubGHz: **Beninca ARC AES128 protocol full support** (128bit dynamic) (with Add manually, and 2 button codes) (resolves issue #596) (by @xMasterX and @zero-mega)
* SubGHz: **Beninca ARC AES128 protocol full support** (128bit dynamic) (with Add manually, and 3 button codes) (resolves issue #596) (by @xMasterX and @zero-mega)
* SubGHz: **Treadmill37 protocol support** (37bit static) (by @xMasterX)
* SubGHz: **New modulation FSK with 12KHz deviation**
* SubGHz: **KingGates Stylo 4k - Add manually and button switch support** + refactoring of encoder
@@ -13,10 +13,12 @@
* SubGHz: Add 390MHz, 430.5MHz to default hopper list (6 elements like in OFW) (works well with Hopper RSSI level set for your enviroment)
* SubGHz: Fixed button mapping for **FAAC RC/XT**
* NFC: Handle PPS request in ISO14443-4 layer (by @WillyJL)
* NFC: Fixes to `READ_MULTI` and `GET_BLOCK_SECURITY` commands in ISO 15693-3 emulation (by @WillyJL & @aaronjamt)
* Archive: Allow folders to be pinned (by @WillyJL)
* Apps: Build tag (**22jan2026**) - **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev)
* Apps: Build tag (**26jan2026**) - **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev)
## Other changes
* UI: Various small changes
* OFW PR 4333: NFC: Fix sending 32+ byte ISO 15693-3 commands (by @WillyJL)
* NFC: Fix LED not blinking at SLIX unlock (closes issue #945)
* SubGHz: Replaced Cars ignore option with Revers RB2 protocol ignore option
* SubGHz: Moved Starline, ScherKhan, Kia decoders into external app

View File

@@ -121,7 +121,7 @@ The following manufacturers have KeeLoq support in Unleashed firmware:
- Nice Smilo - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning)
- Normstahl - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- Novoferm - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- Sommer `434.42MHz, 868.80MHz` `FSK12K (or FSK476)` (KeeLoq, 64 bits) (normal learning) (TX03-868-4, Pearl, and maybe other models are supported (SOMloq2))
- Sommer `434.42MHz, 868.80MHz` `FSK12K (or FSK476)` (KeeLoq, 64 bits) (normal learning) (TX03-868-4, Pearl, and maybe other models are supported (SOMloq))
- Steelmate - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
- Stilmatic - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning)

View File

@@ -2,8 +2,12 @@
#include <digital_signal/digital_sequence.h>
#include <nfc/protocols/iso15693_3/iso15693_3_listener_i.h>
#define BITS_IN_BYTE (8U)
#define ISO15693_SIGNAL_BUFFER_SIZE (ISO15693_3_LISTENER_BUFFER_SIZE * BITS_IN_BYTE + 2)
#define ISO15693_SIGNAL_COEFF_HI (1U)
#define ISO15693_SIGNAL_COEFF_LO (4U)
@@ -151,7 +155,7 @@ Iso15693Signal* iso15693_signal_alloc(const GpioPin* pin) {
Iso15693Signal* instance = malloc(sizeof(Iso15693Signal));
instance->tx_sequence = digital_sequence_alloc(BITS_IN_BYTE * 255 + 2, pin);
instance->tx_sequence = digital_sequence_alloc(ISO15693_SIGNAL_BUFFER_SIZE, pin);
for(uint32_t i = 0; i < Iso15693SignalDataRateNum; ++i) {
iso15693_signal_bank_fill(instance, i);

View File

@@ -8,8 +8,6 @@
#define TAG "Iso15693_3Listener"
#define ISO15693_3_LISTENER_BUFFER_SIZE (256U)
Iso15693_3Listener* iso15693_3_listener_alloc(Nfc* nfc, Iso15693_3Data* data) {
furi_assert(nfc);

View File

@@ -263,8 +263,9 @@ static Iso15693_3Error iso15693_3_listener_read_multi_blocks_handler(
const uint32_t block_index_start = request->first_block_num;
const uint32_t block_index_end =
MIN((block_index_start + request->block_count + 1),
MIN((block_index_start + request->block_count),
((uint32_t)instance->data->system_info.block_count - 1));
const uint32_t block_count = block_index_end - block_index_start + 1;
error = iso15693_3_listener_extension_handler(
instance,
@@ -273,8 +274,21 @@ static Iso15693_3Error iso15693_3_listener_read_multi_blocks_handler(
(uint32_t)block_index_end);
if(error != Iso15693_3ErrorNone) break;
const bool include_block_security = (flags & ISO15693_3_REQ_FLAG_T4_OPTION) != 0;
const uint8_t bytes_per_block =
(include_block_security ? 1 : 0) + instance->data->system_info.block_size;
const uint32_t response_data_max =
bit_buffer_get_capacity_bytes(instance->tx_buffer) - 1 - 2; // Flags and CRC
const uint32_t response_blocks_max = response_data_max / bytes_per_block;
if(block_count > response_blocks_max) {
// Tested on SLIX2, if asked for more blocks than supported at once there is no reply
// Let's do the same
error = Iso15693_3ErrorIgnore;
break;
}
for(uint32_t i = block_index_start; i <= block_index_end; ++i) {
if(flags & ISO15693_3_REQ_FLAG_T4_OPTION) {
if(include_block_security) {
iso15693_3_append_block_security(
instance->data, i, instance->tx_buffer); // Block security (optional)
}
@@ -341,7 +355,7 @@ static Iso15693_3Error iso15693_3_listener_write_multi_blocks_handler(
if(error != Iso15693_3ErrorNone) break;
for(uint32_t i = block_index_start; i < block_count + request->first_block_num; ++i) {
for(uint32_t i = block_index_start; i <= block_index_end; ++i) {
const uint8_t* block_data = &request->block_data[block_size * i];
iso15693_3_set_block_data(instance->data, i, block_data, block_size);
}

View File

@@ -10,6 +10,18 @@
extern "C" {
#endif
// Based on GET_BLOCKS_SECURITY, one of the commands with lengthier responses:
// - 1 byte flags
// - 1 byte security status * 256 max block count
// - 2 byte crc
// for a response size of 259 bytes.
// There is also READ_MULTI_BLOCKS which has no explicit limit on requested block count
// and ISO 15693-3 also does not specify a maximum overall response length, so this command could
// theoretically result in a 8195 byte response (1 byte flags + 32 byte block * 256 blocks + 2 byte crc);
// for practicality we use a sufficient buffer for a full GET_BLOCKS_SECURITY and
// limit READ_MULTI_BLOCKS to how many blocks we can fit into that buffer size.
#define ISO15693_3_LISTENER_BUFFER_SIZE (259U)
typedef enum {
Iso15693_3ListenerStateReady,
Iso15693_3ListenerStateSelected,

View File

@@ -96,7 +96,7 @@ static uint8_t subghz_protocol_beninca_arc_get_btn_code(void) {
case 0x04:
btn = 0x02;
break;
case 0xFF:
case 0x00:
btn = 0x04;
break;
@@ -106,12 +106,12 @@ static uint8_t subghz_protocol_beninca_arc_get_btn_code(void) {
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
switch(original_btn_code) {
case 0x02:
btn = 0xFF;
btn = 0x00;
break;
case 0x04:
btn = 0xFF;
btn = 0x00;
break;
case 0xFF:
case 0x00:
btn = 0x02;
break;

View File

@@ -8,6 +8,7 @@
#define FURI_HAL_NFC_ISO15693_MAX_FRAME_SIZE (1024U)
#define FURI_HAL_NFC_ISO15693_POLLER_MAX_BUFFER_SIZE (64)
#define FURI_HAL_NFC_ISO15693_BIT_LEN (4)
#define FURI_HAL_NFC_ISO15693_RESP_SOF_SIZE (5)
#define FURI_HAL_NFC_ISO15693_RESP_EOF_SIZE (5)
@@ -34,9 +35,9 @@ typedef struct {
typedef struct {
// 4 bits per data bit on transmit
uint8_t fifo_buf[FURI_HAL_NFC_ISO15693_POLLER_MAX_BUFFER_SIZE * 4];
uint8_t fifo_buf[FURI_HAL_NFC_ISO15693_POLLER_MAX_BUFFER_SIZE * FURI_HAL_NFC_ISO15693_BIT_LEN];
size_t fifo_buf_bits;
uint8_t frame_buf[FURI_HAL_NFC_ISO15693_POLLER_MAX_BUFFER_SIZE * 2];
uint8_t frame_buf[FURI_HAL_NFC_ISO15693_POLLER_MAX_BUFFER_SIZE * FURI_HAL_NFC_ISO15693_BIT_LEN];
size_t frame_buf_bits;
} FuriHalNfcIso15693Poller;