1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 12:42:30 +04:00

Merge remote-tracking branch 'OFW/dev' into dev

This commit is contained in:
MX
2025-09-24 17:58:32 +03:00
11 changed files with 237 additions and 23 deletions

View File

@@ -17,7 +17,7 @@
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s") #define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
#define ALUTECH_AT_4N_DIR_NAME EXT_PATH("subghz/assets/alutech_at_4n") #define ALUTECH_AT_4N_DIR_NAME EXT_PATH("subghz/assets/alutech_at_4n")
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub") #define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
#define TEST_RANDOM_COUNT_PARSE 329 #define TEST_RANDOM_COUNT_PARSE 331
#define TEST_TIMEOUT 10000 #define TEST_TIMEOUT 10000
static SubGhzEnvironment* environment_handler; static SubGhzEnvironment* environment_handler;

View File

@@ -19,6 +19,7 @@ typedef struct {
bool connected; bool connected;
bool running; bool running;
int rate; int rate;
enum HidMouseButtons btn;
} HidMouseClickerModel; } HidMouseClickerModel;
static void hid_mouse_clicker_start_or_restart_timer(void* context) { static void hid_mouse_clicker_start_or_restart_timer(void* context) {
@@ -61,6 +62,26 @@ static void hid_mouse_clicker_draw_callback(Canvas* canvas, void* context) {
// Ok // Ok
canvas_draw_icon(canvas, 58, 25, &I_Space_65x18); canvas_draw_icon(canvas, 58, 25, &I_Space_65x18);
canvas_draw_icon(canvas, 61, 50, &I_ButtonLeft_4x7);
canvas_draw_icon(canvas, 117, 50, &I_ButtonRight_4x7);
const char* btn_label;
switch(model->btn) {
case HID_MOUSE_BTN_LEFT:
btn_label = "Left";
break;
case HID_MOUSE_BTN_WHEEL:
btn_label = "Middle";
break;
case HID_MOUSE_BTN_RIGHT:
btn_label = "Right";
break;
default:
furi_crash();
}
elements_multiline_text_aligned(canvas, 89, 57, AlignCenter, AlignBottom, btn_label);
if(model->running) { if(model->running) {
elements_slightly_rounded_box(canvas, 61, 27, 60, 13); elements_slightly_rounded_box(canvas, 61, 27, 60, 13);
canvas_set_color(canvas, ColorWhite); canvas_set_color(canvas, ColorWhite);
@@ -100,8 +121,8 @@ static void hid_mouse_clicker_timer_callback(void* context) {
HidMouseClickerModel * model, HidMouseClickerModel * model,
{ {
if(model->running) { if(model->running) {
hid_hal_mouse_press(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT); hid_hal_mouse_press(hid_mouse_clicker->hid, model->btn);
hid_hal_mouse_release(hid_mouse_clicker->hid, HID_MOUSE_BTN_LEFT); hid_hal_mouse_release(hid_mouse_clicker->hid, model->btn);
} }
}, },
false); false);
@@ -154,6 +175,34 @@ static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) {
case InputKeyBack: case InputKeyBack:
model->running = false; model->running = false;
break; break;
case InputKeyLeft:
switch(model->btn) {
case HID_MOUSE_BTN_LEFT:
model->btn = HID_MOUSE_BTN_RIGHT;
break;
case HID_MOUSE_BTN_WHEEL:
model->btn = HID_MOUSE_BTN_LEFT;
break;
case HID_MOUSE_BTN_RIGHT:
model->btn = HID_MOUSE_BTN_WHEEL;
break;
}
consumed = true;
break;
case InputKeyRight:
switch(model->btn) {
case HID_MOUSE_BTN_LEFT:
model->btn = HID_MOUSE_BTN_WHEEL;
break;
case HID_MOUSE_BTN_WHEEL:
model->btn = HID_MOUSE_BTN_RIGHT;
break;
case HID_MOUSE_BTN_RIGHT:
model->btn = HID_MOUSE_BTN_LEFT;
break;
}
consumed = true;
break;
default: default:
consumed = true; consumed = true;
break; break;
@@ -188,7 +237,10 @@ HidMouseClicker* hid_mouse_clicker_alloc(Hid* hid) {
with_view_model( with_view_model(
hid_mouse_clicker->view, hid_mouse_clicker->view,
HidMouseClickerModel * model, HidMouseClickerModel * model,
{ model->rate = DEFAULT_CLICK_RATE; }, {
model->rate = DEFAULT_CLICK_RATE;
model->btn = HID_MOUSE_BTN_LEFT;
},
true); true);
return hid_mouse_clicker; return hid_mouse_clicker;

View File

@@ -9,6 +9,9 @@
#define NFC_MAX_BUFFER_SIZE (256) #define NFC_MAX_BUFFER_SIZE (256)
#define NFC_FELICA_LISTENER_RESPONSE_TIME_A_FC (512 * 64)
#define NFC_FELICA_LISTENER_RESPONSE_TIME_B_FC (256 * 64)
typedef enum { typedef enum {
NfcStateIdle, NfcStateIdle,
NfcStateRunning, NfcStateRunning,
@@ -661,4 +664,20 @@ NfcError nfc_felica_listener_set_sensf_res_data(
return nfc_process_hal_error(error); return nfc_process_hal_error(error);
} }
void nfc_felica_listener_timer_anticol_start(Nfc* instance, uint8_t target_time_slot) {
furi_check(instance);
furi_hal_nfc_timer_block_tx_start(
NFC_FELICA_LISTENER_RESPONSE_TIME_A_FC +
target_time_slot * NFC_FELICA_LISTENER_RESPONSE_TIME_B_FC);
}
void nfc_felica_listener_timer_anticol_stop(Nfc* instance) {
furi_check(instance);
if(furi_hal_nfc_timer_block_tx_is_running()) {
furi_hal_nfc_timer_block_tx_stop();
}
}
#endif // FW_CFG_unit_tests #endif // FW_CFG_unit_tests

View File

@@ -380,6 +380,24 @@ NfcError nfc_felica_listener_set_sensf_res_data(
*/ */
NfcError nfc_iso15693_listener_tx_sof(Nfc* instance); NfcError nfc_iso15693_listener_tx_sof(Nfc* instance);
/**
* @brief Start the timer used for manual FeliCa collision resolution in listener mode.
*
* This blocks TX until the desired Time Slot, and should be called as soon as the listener
* determines that a collision resolution needs to be handled manually.
*
* @param[in, out] instance instance pointer to the instance to be configured.
* @param[in] target_time_slot Target Time Slot number. Should be a value within the range of 0-15 (double-inclusive).
*/
void nfc_felica_listener_timer_anticol_start(Nfc* instance, uint8_t target_time_slot);
/**
* @brief Cancel the timer used for manual FeliCa collision resolution in listener mode.
*
* @param[in, out] instance instance pointer to the instance to be configured.
*/
void nfc_felica_listener_timer_anticol_stop(Nfc* instance);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -518,4 +518,14 @@ NfcError nfc_felica_listener_set_sensf_res_data(
return NfcErrorNone; return NfcErrorNone;
} }
void nfc_felica_listener_timer_anticol_start(Nfc* instance, uint8_t target_time_slot) {
furi_check(instance);
UNUSED(target_time_slot);
}
void nfc_felica_listener_timer_anticol_stop(Nfc* instance) {
furi_check(instance);
}
#endif #endif

View File

@@ -38,7 +38,7 @@ extern "C" {
#define FELICA_FDT_POLL_FC (10000U) #define FELICA_FDT_POLL_FC (10000U)
#define FELICA_POLL_POLL_MIN_US (1280U) #define FELICA_POLL_POLL_MIN_US (1280U)
#define FELICA_FDT_LISTEN_FC (1172) #define FELICA_FDT_LISTEN_FC (0)
#define FELICA_SYSTEM_CODE_CODE (0xFFFFU) #define FELICA_SYSTEM_CODE_CODE (0xFFFFU)
#define FELICA_TIME_SLOT_1 (0x00U) #define FELICA_TIME_SLOT_1 (0x00U)
@@ -58,6 +58,7 @@ typedef enum {
FelicaErrorWrongCrc, FelicaErrorWrongCrc,
FelicaErrorProtocol, FelicaErrorProtocol,
FelicaErrorTimeout, FelicaErrorTimeout,
FelicaErrorFeatureUnsupported,
} FelicaError; } FelicaError;
typedef struct { typedef struct {

View File

@@ -5,9 +5,20 @@
#include <furi_hal_nfc.h> #include <furi_hal_nfc.h>
#define FELICA_LISTENER_MAX_BUFFER_SIZE (128) #define FELICA_LISTENER_MAX_BUFFER_SIZE (128)
#define FELICA_LISTENER_CMD_POLLING (0x00U)
#define FELICA_LISTENER_RESPONSE_POLLING (0x01U)
#define FELICA_LISTENER_RESPONSE_CODE_READ (0x07) #define FELICA_LISTENER_RESPONSE_CODE_READ (0x07)
#define FELICA_LISTENER_RESPONSE_CODE_WRITE (0x09) #define FELICA_LISTENER_RESPONSE_CODE_WRITE (0x09)
#define FELICA_LISTENER_REQUEST_NONE (0x00U)
#define FELICA_LISTENER_REQUEST_SYSTEM_CODE (0x01U)
#define FELICA_LISTENER_REQUEST_PERFORMANCE (0x02U)
#define FELICA_LISTENER_SYSTEM_CODE_NDEF (__builtin_bswap16(0x12FCU))
#define FELICA_LISTENER_SYSTEM_CODE_LITES (__builtin_bswap16(0x88B4U))
#define FELICA_LISTENER_PERFORMANCE_VALUE (__builtin_bswap16(0x0083U))
#define TAG "FelicaListener" #define TAG "FelicaListener"
FelicaListener* felica_listener_alloc(Nfc* nfc, FelicaData* data) { FelicaListener* felica_listener_alloc(Nfc* nfc, FelicaData* data) {
@@ -151,6 +162,70 @@ static FelicaError felica_listener_process_request(
} }
} }
static void felica_listener_populate_polling_response_header(
FelicaListener* instance,
FelicaListenerPollingResponseHeader* resp) {
resp->idm = instance->data->idm;
resp->pmm = instance->data->pmm;
resp->response_code = FELICA_LISTENER_RESPONSE_POLLING;
}
static bool felica_listener_check_system_code(
const FelicaListenerGenericRequest* const generic_request,
uint16_t code) {
return (
generic_request->polling.system_code == code ||
generic_request->polling.system_code == (code | 0x00FFU) ||
generic_request->polling.system_code == (code | 0xFF00U));
}
static uint16_t felica_listener_get_response_system_code(
FelicaListener* instance,
const FelicaListenerGenericRequest* const generic_request) {
uint16_t resp_system_code = FELICA_SYSTEM_CODE_CODE;
if(felica_listener_check_system_code(generic_request, FELICA_LISTENER_SYSTEM_CODE_NDEF) &&
instance->data->data.fs.mc.data[FELICA_MC_SYS_OP] == 1) {
// NDEF
resp_system_code = FELICA_LISTENER_SYSTEM_CODE_NDEF;
} else if(felica_listener_check_system_code(
generic_request, FELICA_LISTENER_SYSTEM_CODE_LITES)) {
// Lite-S
resp_system_code = FELICA_LISTENER_SYSTEM_CODE_LITES;
}
return resp_system_code;
}
static FelicaError felica_listener_process_system_code(
FelicaListener* instance,
const FelicaListenerGenericRequest* const generic_request) {
FelicaError result = FelicaErrorFeatureUnsupported;
do {
uint16_t resp_system_code =
felica_listener_get_response_system_code(instance, generic_request);
if(resp_system_code == FELICA_SYSTEM_CODE_CODE) break;
FelicaListenerPollingResponse* resp = malloc(sizeof(FelicaListenerPollingResponse));
felica_listener_populate_polling_response_header(instance, &resp->header);
resp->header.length = sizeof(FelicaListenerPollingResponse);
if(generic_request->polling.request_code == FELICA_LISTENER_REQUEST_SYSTEM_CODE) {
resp->optional_request_data = resp_system_code;
} else if(generic_request->polling.request_code == FELICA_LISTENER_REQUEST_PERFORMANCE) {
resp->optional_request_data = FELICA_LISTENER_PERFORMANCE_VALUE;
} else {
resp->header.length = sizeof(FelicaListenerPollingResponseHeader);
}
bit_buffer_reset(instance->tx_buffer);
bit_buffer_append_bytes(instance->tx_buffer, (uint8_t*)resp, resp->header.length);
free(resp);
result = felica_listener_frame_exchange(instance, instance->tx_buffer);
} while(false);
return result;
}
NfcCommand felica_listener_run(NfcGenericEvent event, void* context) { NfcCommand felica_listener_run(NfcGenericEvent event, void* context) {
furi_assert(context); furi_assert(context);
furi_assert(event.protocol == NfcProtocolInvalid); furi_assert(event.protocol == NfcProtocolInvalid);
@@ -187,7 +262,23 @@ NfcCommand felica_listener_run(NfcGenericEvent event, void* context) {
break; break;
} }
if(!felica_listener_check_idm(instance, &request->header.idm)) { if(request->header.code == FELICA_LISTENER_CMD_POLLING) {
// Will always respond at Time Slot 0 for now.
nfc_felica_listener_timer_anticol_start(instance->nfc, 0);
if(request->polling.system_code != FELICA_SYSTEM_CODE_CODE) {
FelicaError error = felica_listener_process_system_code(instance, request);
if(error == FelicaErrorFeatureUnsupported) {
command = NfcCommandReset;
} else if(error != FelicaErrorNone) {
FURI_LOG_E(
TAG, "Error when handling Polling with System Code: %2X", error);
}
break;
} else {
FURI_LOG_E(TAG, "Hardware Polling command leaking through");
break;
}
} else if(!felica_listener_check_idm(instance, &request->header.idm)) {
FURI_LOG_E(TAG, "Wrong IDm"); FURI_LOG_E(TAG, "Wrong IDm");
break; break;
} }

View File

@@ -7,19 +7,6 @@
#define FELICA_WCNT_MC2_00_WARNING_BEGIN_VALUE (0x00001027U) #define FELICA_WCNT_MC2_00_WARNING_BEGIN_VALUE (0x00001027U)
#define FELICA_WCNT_MC2_00_WARNING_END_VALUE (0x00FFFDFFU) #define FELICA_WCNT_MC2_00_WARNING_END_VALUE (0x00FFFDFFU)
#define FELICA_MC_SP_REG_ALL_RW_BYTES_0_1 (0U)
#define FELICA_MC_ALL_BYTE (2U)
#define FELICA_MC_SYS_OP (3U)
#define FELICA_MC_RF_PRM (4U)
#define FELICA_MC_CKCKV_W_MAC_A (5U)
#define FELICA_MC_SP_REG_R_RESTR_BYTES_6_7 (6U)
#define FELICA_MC_SP_REG_W_RESTR_BYTES_8_9 (8U)
#define FELICA_MC_SP_REG_W_MAC_A_BYTES_10_11 (10U)
#define FELICA_MC_STATE_W_MAC_A (12U)
#define FELICA_MC_RESERVED_13 (13U)
#define FELICA_MC_RESERVED_14 (14U)
#define FELICA_MC_RESERVED_15 (15U)
#define FELICA_MC_BYTE_GET(data, byte) (data->data.fs.mc.data[byte]) #define FELICA_MC_BYTE_GET(data, byte) (data->data.fs.mc.data[byte])
#define FELICA_SYSTEM_BLOCK_RO_ACCESS(data) (FELICA_MC_BYTE_GET(data, FELICA_MC_ALL_BYTE) == 0x00) #define FELICA_SYSTEM_BLOCK_RO_ACCESS(data) (FELICA_MC_BYTE_GET(data, FELICA_MC_ALL_BYTE) == 0x00)
#define FELICA_SYSTEM_BLOCK_RW_ACCESS(data) (FELICA_MC_BYTE_GET(data, FELICA_MC_ALL_BYTE) == 0xFF) #define FELICA_SYSTEM_BLOCK_RW_ACCESS(data) (FELICA_MC_BYTE_GET(data, FELICA_MC_ALL_BYTE) == 0xFF)

View File

@@ -7,15 +7,50 @@
#define FELICA_LISTENER_WRITE_BLOCK_COUNT_MAX (2U) #define FELICA_LISTENER_WRITE_BLOCK_COUNT_MAX (2U)
#define FELICA_LISTENER_WRITE_BLOCK_COUNT_MIN (1U) #define FELICA_LISTENER_WRITE_BLOCK_COUNT_MIN (1U)
#define FELICA_MC_SP_REG_ALL_RW_BYTES_0_1 (0U)
#define FELICA_MC_ALL_BYTE (2U)
#define FELICA_MC_SYS_OP (3U)
#define FELICA_MC_RF_PRM (4U)
#define FELICA_MC_CKCKV_W_MAC_A (5U)
#define FELICA_MC_SP_REG_R_RESTR_BYTES_6_7 (6U)
#define FELICA_MC_SP_REG_W_RESTR_BYTES_8_9 (8U)
#define FELICA_MC_SP_REG_W_MAC_A_BYTES_10_11 (10U)
#define FELICA_MC_STATE_W_MAC_A (12U)
#define FELICA_MC_RESERVED_13 (13U)
#define FELICA_MC_RESERVED_14 (14U)
#define FELICA_MC_RESERVED_15 (15U)
typedef enum { typedef enum {
Felica_ListenerStateIdle, Felica_ListenerStateIdle,
Felica_ListenerStateActivated, Felica_ListenerStateActivated,
} FelicaListenerState; } FelicaListenerState;
typedef struct FURI_PACKED {
uint8_t code;
uint16_t system_code;
uint8_t request_code;
uint8_t time_slot;
} FelicaListenerPollingHeader;
typedef struct {
uint8_t length;
uint8_t response_code;
FelicaIDm idm;
FelicaPMm pmm;
} FelicaListenerPollingResponseHeader;
typedef struct FURI_PACKED {
FelicaListenerPollingResponseHeader header;
uint16_t optional_request_data;
} FelicaListenerPollingResponse;
/** Generic Felica request same for both read and write operations. */ /** Generic Felica request same for both read and write operations. */
typedef struct { typedef struct {
uint8_t length; uint8_t length;
FelicaCommandHeader header; union {
FelicaCommandHeader header;
FelicaListenerPollingHeader polling;
};
} FelicaListenerGenericRequest; } FelicaListenerGenericRequest;
/** Generic request but with list of requested elements. */ /** Generic request but with list of requested elements. */

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,86.0,, Version,+,86.1,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@@ -2931,6 +2931,8 @@ Function,+,nfc_device_set_data,void,"NfcDevice*, NfcProtocol, const NfcDeviceDat
Function,+,nfc_device_set_loading_callback,void,"NfcDevice*, NfcLoadingCallback, void*" Function,+,nfc_device_set_loading_callback,void,"NfcDevice*, NfcLoadingCallback, void*"
Function,+,nfc_device_set_uid,_Bool,"NfcDevice*, const uint8_t*, size_t" Function,+,nfc_device_set_uid,_Bool,"NfcDevice*, const uint8_t*, size_t"
Function,+,nfc_felica_listener_set_sensf_res_data,NfcError,"Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t, const uint16_t" Function,+,nfc_felica_listener_set_sensf_res_data,NfcError,"Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t, const uint16_t"
Function,+,nfc_felica_listener_timer_anticol_start,void,"Nfc*, uint8_t"
Function,+,nfc_felica_listener_timer_anticol_stop,void,Nfc*
Function,+,nfc_free,void,Nfc* Function,+,nfc_free,void,Nfc*
Function,+,nfc_iso14443a_listener_set_col_res_data,NfcError,"Nfc*, uint8_t*, uint8_t, uint8_t*, uint8_t" Function,+,nfc_iso14443a_listener_set_col_res_data,NfcError,"Nfc*, uint8_t*, uint8_t, uint8_t*, uint8_t"
Function,+,nfc_iso14443a_listener_tx_custom_parity,NfcError,"Nfc*, const BitBuffer*" Function,+,nfc_iso14443a_listener_tx_custom_parity,NfcError,"Nfc*, const BitBuffer*"
1 entry status name type params
2 Version + 86.0 86.1
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h
2931 Function + nfc_device_set_loading_callback void NfcDevice*, NfcLoadingCallback, void*
2932 Function + nfc_device_set_uid _Bool NfcDevice*, const uint8_t*, size_t
2933 Function + nfc_felica_listener_set_sensf_res_data NfcError Nfc*, const uint8_t*, const uint8_t, const uint8_t*, const uint8_t, const uint16_t
2934 Function + nfc_felica_listener_timer_anticol_start void Nfc*, uint8_t
2935 Function + nfc_felica_listener_timer_anticol_stop void Nfc*
2936 Function + nfc_free void Nfc*
2937 Function + nfc_iso14443a_listener_set_col_res_data NfcError Nfc*, uint8_t*, uint8_t, uint8_t*, uint8_t
2938 Function + nfc_iso14443a_listener_tx_custom_parity NfcError Nfc*, const BitBuffer*

View File

@@ -1,8 +1,7 @@
#include "furi_hal_nfc_i.h" #include "furi_hal_nfc_i.h"
#include "furi_hal_nfc_tech_i.h" #include "furi_hal_nfc_tech_i.h"
// Prevent FDT timer from starting #define FURI_HAL_NFC_FELICA_LISTENER_FDT_COMP_FC (0)
#define FURI_HAL_NFC_FELICA_LISTENER_FDT_COMP_FC (INT32_MAX)
#define FURI_HAL_FELICA_COMMUNICATION_PERFORMANCE (0x0083U) #define FURI_HAL_FELICA_COMMUNICATION_PERFORMANCE (0x0083U)
#define FURI_HAL_FELICA_RESPONSE_CODE (0x01) #define FURI_HAL_FELICA_RESPONSE_CODE (0x01)