mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
Merge remote-tracking branch 'OFW/dev' into dev
This commit is contained in:
@@ -38,7 +38,7 @@ extern "C" {
|
||||
#define FELICA_FDT_POLL_FC (10000U)
|
||||
#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_TIME_SLOT_1 (0x00U)
|
||||
@@ -58,6 +58,7 @@ typedef enum {
|
||||
FelicaErrorWrongCrc,
|
||||
FelicaErrorProtocol,
|
||||
FelicaErrorTimeout,
|
||||
FelicaErrorFeatureUnsupported,
|
||||
} FelicaError;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -5,9 +5,20 @@
|
||||
#include <furi_hal_nfc.h>
|
||||
|
||||
#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_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"
|
||||
|
||||
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) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.protocol == NfcProtocolInvalid);
|
||||
@@ -187,7 +262,23 @@ NfcCommand felica_listener_run(NfcGenericEvent event, void* context) {
|
||||
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");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,19 +7,6 @@
|
||||
#define FELICA_WCNT_MC2_00_WARNING_BEGIN_VALUE (0x00001027U)
|
||||
#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_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)
|
||||
|
||||
@@ -7,15 +7,50 @@
|
||||
#define FELICA_LISTENER_WRITE_BLOCK_COUNT_MAX (2U)
|
||||
#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 {
|
||||
Felica_ListenerStateIdle,
|
||||
Felica_ListenerStateActivated,
|
||||
} 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. */
|
||||
typedef struct {
|
||||
uint8_t length;
|
||||
FelicaCommandHeader header;
|
||||
union {
|
||||
FelicaCommandHeader header;
|
||||
FelicaListenerPollingHeader polling;
|
||||
};
|
||||
} FelicaListenerGenericRequest;
|
||||
|
||||
/** Generic request but with list of requested elements. */
|
||||
|
||||
Reference in New Issue
Block a user