mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-23 05:24:46 -07:00
ofw pr 4293 NFC FeliCa Improvement: Dump All Systems
by zinongli
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
ARRAY_DEF(felica_service_array, FelicaService, M_POD_OPLIST); // -V658
|
||||
ARRAY_DEF(felica_area_array, FelicaArea, M_POD_OPLIST); // -V658
|
||||
ARRAY_DEF(felica_public_block_array, FelicaPublicBlock, M_POD_OPLIST); // -V658
|
||||
ARRAY_DEF(felica_system_array, FelicaSystem, M_POD_OPLIST); // -V658
|
||||
|
||||
typedef NfcCommand (*FelicaPollerReadHandler)(FelicaPoller* instance);
|
||||
|
||||
@@ -43,6 +44,9 @@ static FelicaPoller* felica_poller_alloc(Nfc* nfc) {
|
||||
instance->general_event.event_data = &instance->felica_event;
|
||||
instance->general_event.instance = instance;
|
||||
|
||||
instance->systems_read = 0;
|
||||
instance->systems_total = 0;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -94,7 +98,7 @@ NfcCommand felica_poller_state_handler_activate(FelicaPoller* instance) {
|
||||
|
||||
switch(instance->data->workflow_type) {
|
||||
case FelicaStandard:
|
||||
instance->state = FelicaPollerStateTraverseStandardSystem;
|
||||
instance->state = FelicaPollerStateListSystem;
|
||||
break;
|
||||
case FelicaLite:
|
||||
instance->state = FelicaPollerStateReadLiteBlocks;
|
||||
@@ -117,6 +121,44 @@ NfcCommand felica_poller_state_handler_activate(FelicaPoller* instance) {
|
||||
return command;
|
||||
}
|
||||
|
||||
NfcCommand felica_poller_state_handler_list_system(FelicaPoller* instance) {
|
||||
FURI_LOG_D(TAG, "List System");
|
||||
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
FelicaListSystemCodeCommandResponse* response_system_code;
|
||||
FelicaError error = felica_poller_list_system_code(instance, &response_system_code);
|
||||
|
||||
instance->systems_total = response_system_code->system_count;
|
||||
simple_array_init(instance->data->systems, instance->systems_total);
|
||||
uint8_t* system_codes = response_system_code->system_code;
|
||||
|
||||
for(uint8_t i = 0; i < instance->systems_total; i++) {
|
||||
FelicaSystem* system = simple_array_get(instance->data->systems, i);
|
||||
system->system_code = system_codes[i * 2] << 8 | system_codes[i * 2 + 1];
|
||||
system->system_code_idx = i;
|
||||
}
|
||||
|
||||
if(error == FelicaErrorNone) {
|
||||
instance->state = FelicaPollerStateSelectSystemIndex;
|
||||
} else if(error != FelicaErrorTimeout) {
|
||||
instance->felica_event.type = FelicaPollerEventTypeError;
|
||||
instance->felica_event_data.error = error;
|
||||
instance->state = FelicaPollerStateReadFailed;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
NfcCommand felica_poller_state_handler_select_system_idx(FelicaPoller* instance) {
|
||||
FURI_LOG_D(TAG, "Select System Index %d", instance->systems_read);
|
||||
uint8_t system_index_mask = instance->systems_read << 4;
|
||||
instance->data->idm.data[0] &= 0x0F;
|
||||
instance->data->idm.data[0] |= system_index_mask;
|
||||
instance->state = FelicaPollerStateTraverseStandardSystem;
|
||||
|
||||
return NfcCommandContinue;
|
||||
}
|
||||
|
||||
NfcCommand felica_poller_state_handler_auth_internal(FelicaPoller* instance) {
|
||||
FURI_LOG_D(TAG, "Auth Internal");
|
||||
|
||||
@@ -274,6 +316,8 @@ NfcCommand felica_poller_state_handler_traverse_standard_system(FelicaPoller* in
|
||||
service->code = code_begin;
|
||||
service->attr = (uint8_t)(code_begin & 0x3F);
|
||||
|
||||
FURI_LOG_D(TAG, "Service %04X", service->code);
|
||||
|
||||
if(felica_area_array_size(area_buffer)) {
|
||||
FelicaArea* current_area = felica_area_array_back(area_buffer);
|
||||
current_area->last_idx = (uint16_t)(felica_service_array_size(service_buffer) - 1);
|
||||
@@ -284,31 +328,30 @@ NfcCommand felica_poller_state_handler_traverse_standard_system(FelicaPoller* in
|
||||
const size_t service_num = felica_service_array_size(service_buffer);
|
||||
const size_t area_num = felica_area_array_size(area_buffer);
|
||||
|
||||
FelicaSystem* system = simple_array_get(instance->data->systems, instance->systems_read);
|
||||
if(service_num) {
|
||||
simple_array_init(instance->data->services, (uint32_t)service_num);
|
||||
simple_array_init(system->services, (uint32_t)service_num);
|
||||
memcpy(
|
||||
simple_array_get(instance->data->services, 0),
|
||||
simple_array_get(system->services, 0),
|
||||
service_buffer->ptr,
|
||||
service_num * sizeof(FelicaService));
|
||||
} else {
|
||||
simple_array_reset(instance->data->services);
|
||||
simple_array_reset(system->services);
|
||||
}
|
||||
|
||||
if(area_num) {
|
||||
simple_array_init(instance->data->areas, (uint32_t)area_num);
|
||||
simple_array_init(system->areas, (uint32_t)area_num);
|
||||
memcpy(
|
||||
simple_array_get(instance->data->areas, 0),
|
||||
area_buffer->ptr,
|
||||
area_num * sizeof(FelicaArea));
|
||||
simple_array_get(system->areas, 0), area_buffer->ptr, area_num * sizeof(FelicaArea));
|
||||
} else {
|
||||
simple_array_reset(instance->data->areas);
|
||||
simple_array_reset(system->areas);
|
||||
}
|
||||
|
||||
FURI_LOG_I(
|
||||
TAG,
|
||||
"Services found: %lu, Areas found: %lu",
|
||||
simple_array_get_count(instance->data->services),
|
||||
simple_array_get_count(instance->data->areas));
|
||||
simple_array_get_count(system->services),
|
||||
simple_array_get_count(system->areas));
|
||||
|
||||
felica_service_array_clear(service_buffer);
|
||||
felica_area_array_clear(area_buffer);
|
||||
@@ -320,22 +363,22 @@ NfcCommand felica_poller_state_handler_traverse_standard_system(FelicaPoller* in
|
||||
NfcCommand felica_poller_state_handler_read_standard_blocks(FelicaPoller* instance) {
|
||||
FURI_LOG_D(TAG, "Read Standard Blocks");
|
||||
|
||||
const uint32_t service_count = simple_array_get_count(instance->data->services);
|
||||
FelicaSystem* system = simple_array_get(instance->data->systems, instance->systems_read);
|
||||
const uint32_t service_count = simple_array_get_count(system->services);
|
||||
|
||||
felica_public_block_array_t public_block_buffer;
|
||||
felica_public_block_array_init(public_block_buffer);
|
||||
|
||||
instance->state = FelicaPollerStateReadSuccess;
|
||||
bool have_read_anything = false;
|
||||
FelicaError error = FelicaErrorNone;
|
||||
|
||||
for(uint32_t i = 0; i < service_count; i++) {
|
||||
const FelicaService* service = simple_array_get(instance->data->services, i);
|
||||
const FelicaService* service = simple_array_get(system->services, i);
|
||||
|
||||
if((service->attr & FELICA_SERVICE_ATTRIBUTE_UNAUTH_READ) == 0) continue;
|
||||
|
||||
uint8_t block_count = 1;
|
||||
uint8_t block_list[1] = {0};
|
||||
FelicaError error = FelicaErrorNone;
|
||||
FelicaPollerReadCommandResponse* response;
|
||||
do {
|
||||
error = felica_poller_read_blocks(
|
||||
@@ -369,11 +412,20 @@ NfcCommand felica_poller_state_handler_read_standard_blocks(FelicaPoller* instan
|
||||
}
|
||||
}
|
||||
|
||||
if(error == FelicaErrorNone) {
|
||||
instance->systems_read++;
|
||||
if(instance->systems_read == instance->systems_total) {
|
||||
instance->state = FelicaPollerStateReadSuccess;
|
||||
} else {
|
||||
instance->state = FelicaPollerStateSelectSystemIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if(have_read_anything) {
|
||||
const size_t n = felica_public_block_array_size(public_block_buffer);
|
||||
simple_array_init(instance->data->public_blocks, (uint32_t)n);
|
||||
simple_array_init(system->public_blocks, (uint32_t)n);
|
||||
memcpy(
|
||||
simple_array_get(instance->data->public_blocks, 0),
|
||||
simple_array_get(system->public_blocks, 0),
|
||||
public_block_buffer->ptr,
|
||||
n * sizeof(FelicaPublicBlock));
|
||||
}
|
||||
@@ -446,6 +498,8 @@ NfcCommand felica_poller_state_handler_read_success(FelicaPoller* instance) {
|
||||
instance->felica_event.type = FelicaPollerEventTypeReady;
|
||||
}
|
||||
|
||||
instance->data->idm.data[0] &= 0x0F;
|
||||
|
||||
instance->felica_event_data.error = FelicaErrorNone;
|
||||
return instance->callback(instance->general_event, instance->context);
|
||||
}
|
||||
@@ -453,6 +507,7 @@ NfcCommand felica_poller_state_handler_read_success(FelicaPoller* instance) {
|
||||
NfcCommand felica_poller_state_handler_read_failed(FelicaPoller* instance) {
|
||||
FURI_LOG_D(TAG, "Read Fail");
|
||||
instance->callback(instance->general_event, instance->context);
|
||||
instance->data->idm.data[0] &= 0x0F;
|
||||
|
||||
return NfcCommandStop;
|
||||
}
|
||||
@@ -460,6 +515,8 @@ NfcCommand felica_poller_state_handler_read_failed(FelicaPoller* instance) {
|
||||
static const FelicaPollerReadHandler felica_poller_handler[FelicaPollerStateNum] = {
|
||||
[FelicaPollerStateIdle] = felica_poller_state_handler_idle,
|
||||
[FelicaPollerStateActivated] = felica_poller_state_handler_activate,
|
||||
[FelicaPollerStateListSystem] = felica_poller_state_handler_list_system,
|
||||
[FelicaPollerStateSelectSystemIndex] = felica_poller_state_handler_select_system_idx,
|
||||
[FelicaPollerStateAuthenticateInternal] = felica_poller_state_handler_auth_internal,
|
||||
[FelicaPollerStateAuthenticateExternal] = felica_poller_state_handler_auth_external,
|
||||
[FelicaPollerStateTraverseStandardSystem] =
|
||||
|
||||
Reference in New Issue
Block a user