1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00
Files
unleashed-firmware/lib/nfc/protocols/felica/felica_poller_i.c

297 lines
9.5 KiB
C
Raw Normal View History

#include "felica_poller_i.h"
#include <nfc/helpers/felica_crc.h>
#define TAG "FelicaPoller"
static FelicaError felica_poller_process_error(NfcError error) {
switch(error) {
case NfcErrorNone:
return FelicaErrorNone;
case NfcErrorTimeout:
return FelicaErrorTimeout;
default:
return FelicaErrorNotPresent;
}
}
[FL-3772] Felica poller (#3570) * New types for felica poller * New functions for felica data transmissions * Felica memory map extended with new fields * Init/deinit of mbedtls context added for felica encryption * Functions for session key and mac calculations added * Raw felica_poller implementation added * Removed MAC type parameter from check_mac function * Replaced all data fields needed for auth with context structure * Clean up felica_poller.c * Now RC block is filled with random numbers * New parameter for counting well-read blocks * Some cleanups * Felica file save and load logic added * Now we use card key from context for session key calculation * Copying card key to card block from auth context when both authentications succeeded, otherwise decrement blocks count by 1 * New felica poller event added * Moved some data structions to public namespace * FelicaAuthenticationContext struct moved to felica.h * Field type and name changed for better ones * Helper functions for felica_auth added to the app * New scene for felica card key input added * Logic for felica key input added * Auth context request processing added * Added block index definitions and replaced all index numbers with them * More macro defines * Replace nesting with do while block * New function for write operations mac calculation added * Replace nesting with do while block * Make functions static for now because they are used internally * Wrote some comments * Raw felica render implementation * New felica scenes * Adjusted felica dump rendering according design requirements * New felica scene added * Helper for switching scene during unlock added * Added warning scene and transfer to it * Moved unlock scene logic to separate files * Magic number changed * New felica render logic * Felica scenes adjusted according to design requirements * Felica poller cleanups * Some asserts added and some fixed * Replcaed asserts to checks in public api * Fixed pvs warnings in felica_poller * New event for felica_poller added for incomplete read actions * Handling of new poller event added * Update SConscript with felica files * Update api_symbols.csv with felica functions * Sync API versions Co-authored-by: あく <alleteam@gmail.com>
2024-04-10 12:51:36 +03:00
FelicaError felica_poller_frame_exchange(
const FelicaPoller* instance,
const BitBuffer* tx_buffer,
BitBuffer* rx_buffer,
uint32_t fwt) {
furi_assert(instance);
const size_t tx_bytes = bit_buffer_get_size_bytes(tx_buffer);
furi_assert(tx_bytes <= bit_buffer_get_capacity_bytes(instance->tx_buffer) - FELICA_CRC_SIZE);
felica_crc_append(instance->tx_buffer);
FelicaError ret = FelicaErrorNone;
do {
NfcError error =
nfc_poller_trx(instance->nfc, instance->tx_buffer, instance->rx_buffer, fwt);
if(error != NfcErrorNone) {
ret = felica_poller_process_error(error);
break;
}
bit_buffer_copy(rx_buffer, instance->rx_buffer);
if(!felica_crc_check(instance->rx_buffer)) {
ret = FelicaErrorWrongCrc;
break;
}
felica_crc_trim(rx_buffer);
} while(false);
return ret;
}
FelicaError felica_poller_polling(
FelicaPoller* instance,
const FelicaPollerPollingCommand* cmd,
FelicaPollerPollingResponse* resp) {
furi_assert(instance);
furi_assert(cmd);
furi_assert(resp);
FelicaError error = FelicaErrorNone;
do {
bit_buffer_set_size_bytes(instance->tx_buffer, 2);
// Set frame len
bit_buffer_set_byte(
instance->tx_buffer, 0, sizeof(FelicaPollerPollingCommand) + FELICA_CRC_SIZE);
// Set command code
bit_buffer_set_byte(instance->tx_buffer, 1, FELICA_POLLER_CMD_POLLING_REQ_CODE);
// Set other data
bit_buffer_append_bytes(
instance->tx_buffer, (uint8_t*)cmd, sizeof(FelicaPollerPollingCommand));
error = felica_poller_frame_exchange(
instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT);
if(error != FelicaErrorNone) break;
if(bit_buffer_get_byte(instance->rx_buffer, 1) != FELICA_POLLER_CMD_POLLING_RESP_CODE) {
error = FelicaErrorProtocol;
break;
}
if(bit_buffer_get_size_bytes(instance->rx_buffer) <
sizeof(FelicaIDm) + sizeof(FelicaPMm) + 1) {
error = FelicaErrorProtocol;
break;
}
bit_buffer_write_bytes_mid(instance->rx_buffer, resp->idm.data, 2, sizeof(FelicaIDm));
bit_buffer_write_bytes_mid(
instance->rx_buffer, resp->pmm.data, sizeof(FelicaIDm) + 2, sizeof(FelicaPMm));
} while(false);
return error;
}
NFC FeliCa: Service Directory Traverse + Dump All Unencrypted-Readable Services' Blocks (#4254) * SimpleArray attached to FelicaData * tx rx done. response parsing done (in log) * dynamic vector as buffer. rendering begin * On screen render for directory tree * flags in render to indicate is_public_readable * beautify render flags * format * offload dynamic vector into individual files * saving. exposed dir tree writing for double use * save: additional formatting * save: clean up and some additional notes * load done * delete unnecessary debug log * Load: safer way to handle backward compatibility `parsed` being true is only contingent on whether the header (device type, UID, etc) are correctly read. The detailed data can be absent if saved from previous versions. Side effects: 1. The data format version number must not increment. 2. Newer sections of dumps must be appended in the end of the file. * format * handle block reading according to IC type Old version was aimed for FeliCa Lite dumping, which doesn't apply to FeliCa standard. Thus they need to be diverged in the poller run workflow. * read block content works. rendering begin * Render Refactor: dir & dump view from submenu * Render: show IC type name * IC parsing function cleanup * Revert "IC parsing function cleanup" This reverts commit ee3f7bf125b54b10d238b0aeb657ba15f27f93ba. * Load: Standard dump. Fully backward compatible * format * sync API version * format saved file * delete unused variable * clean ups * IC type addition * correction * beautify attribute parsing * correction * Lite save: delete extra line * correction: FeliCa link in Lite-S mode * format * Save: simplify printing * update IC type parsing * conform to api standard: const resp ptr to ptr also slightly faster and more readable block dump loop * disambiguate workflow type vs ic type It was too confusing to have the ic name string telling you one thing and ic_type enum saying the other. Might as well use better naming to indicate the use case for the two things * beautify on device render * reject dynamic_vector, embrace m-array * lint * use full variable name * partial fix: poller context's data proper init * edit unit test dump IC code and a small bug fix for the Lite auth workflow * unit test felica dump PMm correction * Fixes for static analysis warnings --------- Co-authored-by: hedger <hedger@nanode.su> Co-authored-by: hedger <hedger@users.noreply.github.com>
2025-10-01 18:54:08 +04:00
// This is in fact a buffer preparer for a specified service. It should be have the _ex suffix. The prepare_tx_buffer_raw should have this name.
[FL-3772] Felica poller (#3570) * New types for felica poller * New functions for felica data transmissions * Felica memory map extended with new fields * Init/deinit of mbedtls context added for felica encryption * Functions for session key and mac calculations added * Raw felica_poller implementation added * Removed MAC type parameter from check_mac function * Replaced all data fields needed for auth with context structure * Clean up felica_poller.c * Now RC block is filled with random numbers * New parameter for counting well-read blocks * Some cleanups * Felica file save and load logic added * Now we use card key from context for session key calculation * Copying card key to card block from auth context when both authentications succeeded, otherwise decrement blocks count by 1 * New felica poller event added * Moved some data structions to public namespace * FelicaAuthenticationContext struct moved to felica.h * Field type and name changed for better ones * Helper functions for felica_auth added to the app * New scene for felica card key input added * Logic for felica key input added * Auth context request processing added * Added block index definitions and replaced all index numbers with them * More macro defines * Replace nesting with do while block * New function for write operations mac calculation added * Replace nesting with do while block * Make functions static for now because they are used internally * Wrote some comments * Raw felica render implementation * New felica scenes * Adjusted felica dump rendering according design requirements * New felica scene added * Helper for switching scene during unlock added * Added warning scene and transfer to it * Moved unlock scene logic to separate files * Magic number changed * New felica render logic * Felica scenes adjusted according to design requirements * Felica poller cleanups * Some asserts added and some fixed * Replcaed asserts to checks in public api * Fixed pvs warnings in felica_poller * New event for felica_poller added for incomplete read actions * Handling of new poller event added * Update SConscript with felica files * Update api_symbols.csv with felica functions * Sync API versions Co-authored-by: あく <alleteam@gmail.com>
2024-04-10 12:51:36 +03:00
static void felica_poller_prepare_tx_buffer(
const FelicaPoller* instance,
const uint8_t command,
const uint16_t service_code,
const uint8_t block_count,
const uint8_t* const blocks,
const uint8_t data_block_count,
const uint8_t* data) {
FelicaCommandHeader cmd = {
.code = command,
.idm = instance->data->idm,
.service_num = 1,
.service_code = service_code,
.block_count = block_count,
};
FelicaBlockListElement block_list[4] = {{0}, {0}, {0}, {0}};
for(uint8_t i = 0; i < block_count; i++) {
block_list[i].length = 1;
block_list[i].block_number = blocks[i];
}
uint8_t block_list_count = block_count;
uint8_t block_list_size = block_list_count * sizeof(FelicaBlockListElement);
uint8_t total_size = sizeof(FelicaCommandHeader) + 1 + block_list_size +
data_block_count * FELICA_DATA_BLOCK_SIZE;
bit_buffer_reset(instance->tx_buffer);
bit_buffer_append_byte(instance->tx_buffer, total_size);
bit_buffer_append_bytes(instance->tx_buffer, (uint8_t*)&cmd, sizeof(FelicaCommandHeader));
bit_buffer_append_bytes(instance->tx_buffer, (uint8_t*)&block_list, block_list_size);
if(data_block_count != 0) {
bit_buffer_append_bytes(
instance->tx_buffer, data, data_block_count * FELICA_DATA_BLOCK_SIZE);
}
}
FelicaError felica_poller_read_blocks(
FelicaPoller* instance,
const uint8_t block_count,
const uint8_t* const block_numbers,
uint16_t service_code,
[FL-3772] Felica poller (#3570) * New types for felica poller * New functions for felica data transmissions * Felica memory map extended with new fields * Init/deinit of mbedtls context added for felica encryption * Functions for session key and mac calculations added * Raw felica_poller implementation added * Removed MAC type parameter from check_mac function * Replaced all data fields needed for auth with context structure * Clean up felica_poller.c * Now RC block is filled with random numbers * New parameter for counting well-read blocks * Some cleanups * Felica file save and load logic added * Now we use card key from context for session key calculation * Copying card key to card block from auth context when both authentications succeeded, otherwise decrement blocks count by 1 * New felica poller event added * Moved some data structions to public namespace * FelicaAuthenticationContext struct moved to felica.h * Field type and name changed for better ones * Helper functions for felica_auth added to the app * New scene for felica card key input added * Logic for felica key input added * Auth context request processing added * Added block index definitions and replaced all index numbers with them * More macro defines * Replace nesting with do while block * New function for write operations mac calculation added * Replace nesting with do while block * Make functions static for now because they are used internally * Wrote some comments * Raw felica render implementation * New felica scenes * Adjusted felica dump rendering according design requirements * New felica scene added * Helper for switching scene during unlock added * Added warning scene and transfer to it * Moved unlock scene logic to separate files * Magic number changed * New felica render logic * Felica scenes adjusted according to design requirements * Felica poller cleanups * Some asserts added and some fixed * Replcaed asserts to checks in public api * Fixed pvs warnings in felica_poller * New event for felica_poller added for incomplete read actions * Handling of new poller event added * Update SConscript with felica files * Update api_symbols.csv with felica functions * Sync API versions Co-authored-by: あく <alleteam@gmail.com>
2024-04-10 12:51:36 +03:00
FelicaPollerReadCommandResponse** const response_ptr) {
furi_assert(instance);
[FL-3772] Felica poller (#3570) * New types for felica poller * New functions for felica data transmissions * Felica memory map extended with new fields * Init/deinit of mbedtls context added for felica encryption * Functions for session key and mac calculations added * Raw felica_poller implementation added * Removed MAC type parameter from check_mac function * Replaced all data fields needed for auth with context structure * Clean up felica_poller.c * Now RC block is filled with random numbers * New parameter for counting well-read blocks * Some cleanups * Felica file save and load logic added * Now we use card key from context for session key calculation * Copying card key to card block from auth context when both authentications succeeded, otherwise decrement blocks count by 1 * New felica poller event added * Moved some data structions to public namespace * FelicaAuthenticationContext struct moved to felica.h * Field type and name changed for better ones * Helper functions for felica_auth added to the app * New scene for felica card key input added * Logic for felica key input added * Auth context request processing added * Added block index definitions and replaced all index numbers with them * More macro defines * Replace nesting with do while block * New function for write operations mac calculation added * Replace nesting with do while block * Make functions static for now because they are used internally * Wrote some comments * Raw felica render implementation * New felica scenes * Adjusted felica dump rendering according design requirements * New felica scene added * Helper for switching scene during unlock added * Added warning scene and transfer to it * Moved unlock scene logic to separate files * Magic number changed * New felica render logic * Felica scenes adjusted according to design requirements * Felica poller cleanups * Some asserts added and some fixed * Replcaed asserts to checks in public api * Fixed pvs warnings in felica_poller * New event for felica_poller added for incomplete read actions * Handling of new poller event added * Update SConscript with felica files * Update api_symbols.csv with felica functions * Sync API versions Co-authored-by: あく <alleteam@gmail.com>
2024-04-10 12:51:36 +03:00
furi_assert(block_count <= 4);
furi_assert(block_numbers);
furi_assert(response_ptr);
felica_poller_prepare_tx_buffer(
instance,
FELICA_CMD_READ_WITHOUT_ENCRYPTION,
service_code,
[FL-3772] Felica poller (#3570) * New types for felica poller * New functions for felica data transmissions * Felica memory map extended with new fields * Init/deinit of mbedtls context added for felica encryption * Functions for session key and mac calculations added * Raw felica_poller implementation added * Removed MAC type parameter from check_mac function * Replaced all data fields needed for auth with context structure * Clean up felica_poller.c * Now RC block is filled with random numbers * New parameter for counting well-read blocks * Some cleanups * Felica file save and load logic added * Now we use card key from context for session key calculation * Copying card key to card block from auth context when both authentications succeeded, otherwise decrement blocks count by 1 * New felica poller event added * Moved some data structions to public namespace * FelicaAuthenticationContext struct moved to felica.h * Field type and name changed for better ones * Helper functions for felica_auth added to the app * New scene for felica card key input added * Logic for felica key input added * Auth context request processing added * Added block index definitions and replaced all index numbers with them * More macro defines * Replace nesting with do while block * New function for write operations mac calculation added * Replace nesting with do while block * Make functions static for now because they are used internally * Wrote some comments * Raw felica render implementation * New felica scenes * Adjusted felica dump rendering according design requirements * New felica scene added * Helper for switching scene during unlock added * Added warning scene and transfer to it * Moved unlock scene logic to separate files * Magic number changed * New felica render logic * Felica scenes adjusted according to design requirements * Felica poller cleanups * Some asserts added and some fixed * Replcaed asserts to checks in public api * Fixed pvs warnings in felica_poller * New event for felica_poller added for incomplete read actions * Handling of new poller event added * Update SConscript with felica files * Update api_symbols.csv with felica functions * Sync API versions Co-authored-by: あく <alleteam@gmail.com>
2024-04-10 12:51:36 +03:00
block_count,
block_numbers,
0,
NULL);
bit_buffer_reset(instance->rx_buffer);
FelicaError error = felica_poller_frame_exchange(
instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT);
if(error == FelicaErrorNone) {
*response_ptr = (FelicaPollerReadCommandResponse*)bit_buffer_get_data(instance->rx_buffer);
}
return error;
}
FelicaError felica_poller_write_blocks(
const FelicaPoller* instance,
const uint8_t block_count,
const uint8_t* const block_numbers,
const uint8_t* data,
FelicaPollerWriteCommandResponse** const response_ptr) {
furi_assert(instance);
furi_assert(block_count <= 2);
furi_assert(block_numbers);
furi_assert(data);
furi_assert(response_ptr);
felica_poller_prepare_tx_buffer(
instance,
FELICA_CMD_WRITE_WITHOUT_ENCRYPTION,
FELICA_SERVICE_RW_ACCESS,
block_count,
block_numbers,
block_count,
data);
bit_buffer_reset(instance->rx_buffer);
FelicaError error = felica_poller_frame_exchange(
instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT);
if(error == FelicaErrorNone) {
*response_ptr =
(FelicaPollerWriteCommandResponse*)bit_buffer_get_data(instance->rx_buffer);
}
return error;
}
[FL-3772] Felica poller (#3570) * New types for felica poller * New functions for felica data transmissions * Felica memory map extended with new fields * Init/deinit of mbedtls context added for felica encryption * Functions for session key and mac calculations added * Raw felica_poller implementation added * Removed MAC type parameter from check_mac function * Replaced all data fields needed for auth with context structure * Clean up felica_poller.c * Now RC block is filled with random numbers * New parameter for counting well-read blocks * Some cleanups * Felica file save and load logic added * Now we use card key from context for session key calculation * Copying card key to card block from auth context when both authentications succeeded, otherwise decrement blocks count by 1 * New felica poller event added * Moved some data structions to public namespace * FelicaAuthenticationContext struct moved to felica.h * Field type and name changed for better ones * Helper functions for felica_auth added to the app * New scene for felica card key input added * Logic for felica key input added * Auth context request processing added * Added block index definitions and replaced all index numbers with them * More macro defines * Replace nesting with do while block * New function for write operations mac calculation added * Replace nesting with do while block * Make functions static for now because they are used internally * Wrote some comments * Raw felica render implementation * New felica scenes * Adjusted felica dump rendering according design requirements * New felica scene added * Helper for switching scene during unlock added * Added warning scene and transfer to it * Moved unlock scene logic to separate files * Magic number changed * New felica render logic * Felica scenes adjusted according to design requirements * Felica poller cleanups * Some asserts added and some fixed * Replcaed asserts to checks in public api * Fixed pvs warnings in felica_poller * New event for felica_poller added for incomplete read actions * Handling of new poller event added * Update SConscript with felica files * Update api_symbols.csv with felica functions * Sync API versions Co-authored-by: あく <alleteam@gmail.com>
2024-04-10 12:51:36 +03:00
FelicaError felica_poller_activate(FelicaPoller* instance, FelicaData* data) {
furi_assert(instance);
FelicaError ret;
do {
bit_buffer_reset(instance->tx_buffer);
bit_buffer_reset(instance->rx_buffer);
// Send Polling command
const FelicaPollerPollingCommand polling_cmd = {
.system_code = FELICA_SYSTEM_CODE_CODE,
.request_code = 0,
.time_slot = FELICA_TIME_SLOT_1,
};
FelicaPollerPollingResponse polling_resp = {};
ret = felica_poller_polling(instance, &polling_cmd, &polling_resp);
if(ret != FelicaErrorNone) {
FURI_LOG_T(TAG, "Activation failed error: %d", ret);
break;
}
data->idm = polling_resp.idm;
data->pmm = polling_resp.pmm;
instance->state = FelicaPollerStateActivated;
} while(false);
return ret;
}
NFC FeliCa: Service Directory Traverse + Dump All Unencrypted-Readable Services' Blocks (#4254) * SimpleArray attached to FelicaData * tx rx done. response parsing done (in log) * dynamic vector as buffer. rendering begin * On screen render for directory tree * flags in render to indicate is_public_readable * beautify render flags * format * offload dynamic vector into individual files * saving. exposed dir tree writing for double use * save: additional formatting * save: clean up and some additional notes * load done * delete unnecessary debug log * Load: safer way to handle backward compatibility `parsed` being true is only contingent on whether the header (device type, UID, etc) are correctly read. The detailed data can be absent if saved from previous versions. Side effects: 1. The data format version number must not increment. 2. Newer sections of dumps must be appended in the end of the file. * format * handle block reading according to IC type Old version was aimed for FeliCa Lite dumping, which doesn't apply to FeliCa standard. Thus they need to be diverged in the poller run workflow. * read block content works. rendering begin * Render Refactor: dir & dump view from submenu * Render: show IC type name * IC parsing function cleanup * Revert "IC parsing function cleanup" This reverts commit ee3f7bf125b54b10d238b0aeb657ba15f27f93ba. * Load: Standard dump. Fully backward compatible * format * sync API version * format saved file * delete unused variable * clean ups * IC type addition * correction * beautify attribute parsing * correction * Lite save: delete extra line * correction: FeliCa link in Lite-S mode * format * Save: simplify printing * update IC type parsing * conform to api standard: const resp ptr to ptr also slightly faster and more readable block dump loop * disambiguate workflow type vs ic type It was too confusing to have the ic name string telling you one thing and ic_type enum saying the other. Might as well use better naming to indicate the use case for the two things * beautify on device render * reject dynamic_vector, embrace m-array * lint * use full variable name * partial fix: poller context's data proper init * edit unit test dump IC code and a small bug fix for the Lite auth workflow * unit test felica dump PMm correction * Fixes for static analysis warnings --------- Co-authored-by: hedger <hedger@nanode.su> Co-authored-by: hedger <hedger@users.noreply.github.com>
2025-10-01 18:54:08 +04:00
static void felica_poller_prepare_tx_buffer_raw(
const FelicaPoller* instance,
const uint8_t command,
const uint8_t* data,
const uint8_t data_length) {
FelicaCommandHeaderRaw cmd = {.length = 0x00, .command = command, .idm = instance->data->idm};
cmd.length = sizeof(FelicaCommandHeaderRaw) + data_length;
bit_buffer_reset(instance->tx_buffer);
bit_buffer_append_bytes(instance->tx_buffer, (uint8_t*)&cmd, sizeof(FelicaCommandHeaderRaw));
if(data_length > 0) {
bit_buffer_append_bytes(instance->tx_buffer, data, data_length);
}
NFC FeliCa: Service Directory Traverse + Dump All Unencrypted-Readable Services' Blocks (#4254) * SimpleArray attached to FelicaData * tx rx done. response parsing done (in log) * dynamic vector as buffer. rendering begin * On screen render for directory tree * flags in render to indicate is_public_readable * beautify render flags * format * offload dynamic vector into individual files * saving. exposed dir tree writing for double use * save: additional formatting * save: clean up and some additional notes * load done * delete unnecessary debug log * Load: safer way to handle backward compatibility `parsed` being true is only contingent on whether the header (device type, UID, etc) are correctly read. The detailed data can be absent if saved from previous versions. Side effects: 1. The data format version number must not increment. 2. Newer sections of dumps must be appended in the end of the file. * format * handle block reading according to IC type Old version was aimed for FeliCa Lite dumping, which doesn't apply to FeliCa standard. Thus they need to be diverged in the poller run workflow. * read block content works. rendering begin * Render Refactor: dir & dump view from submenu * Render: show IC type name * IC parsing function cleanup * Revert "IC parsing function cleanup" This reverts commit ee3f7bf125b54b10d238b0aeb657ba15f27f93ba. * Load: Standard dump. Fully backward compatible * format * sync API version * format saved file * delete unused variable * clean ups * IC type addition * correction * beautify attribute parsing * correction * Lite save: delete extra line * correction: FeliCa link in Lite-S mode * format * Save: simplify printing * update IC type parsing * conform to api standard: const resp ptr to ptr also slightly faster and more readable block dump loop * disambiguate workflow type vs ic type It was too confusing to have the ic name string telling you one thing and ic_type enum saying the other. Might as well use better naming to indicate the use case for the two things * beautify on device render * reject dynamic_vector, embrace m-array * lint * use full variable name * partial fix: poller context's data proper init * edit unit test dump IC code and a small bug fix for the Lite auth workflow * unit test felica dump PMm correction * Fixes for static analysis warnings --------- Co-authored-by: hedger <hedger@nanode.su> Co-authored-by: hedger <hedger@users.noreply.github.com>
2025-10-01 18:54:08 +04:00
}
FelicaError felica_poller_list_service_by_cursor(
FelicaPoller* instance,
uint16_t cursor,
FelicaListServiceCommandResponse** const response_ptr) {
furi_assert(instance);
furi_assert(response_ptr);
const uint8_t data[2] = {(uint8_t)(cursor & 0xFF), (uint8_t)((cursor >> 8) & 0xFF)};
felica_poller_prepare_tx_buffer_raw(
instance, FELICA_CMD_LIST_SERVICE_CODE, data, sizeof(data));
bit_buffer_reset(instance->rx_buffer);
FelicaError error = felica_poller_frame_exchange(
instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT);
if(error != FelicaErrorNone) {
FURI_LOG_E(TAG, "List service by cursor failed with error: %d", error);
return error;
}
size_t rx_len = bit_buffer_get_size_bytes(instance->rx_buffer);
if(rx_len < sizeof(FelicaCommandHeaderRaw) + 2) return FelicaErrorProtocol;
// error is known to be FelicaErrorNone here
*response_ptr = (FelicaListServiceCommandResponse*)bit_buffer_get_data(instance->rx_buffer);
return error;
}
FelicaError felica_poller_list_system_code(
FelicaPoller* instance,
FelicaListSystemCodeCommandResponse** const response_ptr) {
furi_assert(instance);
furi_assert(response_ptr);
uint8_t data[] = {0};
felica_poller_prepare_tx_buffer_raw(instance, FELICA_CMD_REQUEST_SYSTEM_CODE, data, 0);
bit_buffer_reset(instance->rx_buffer);
FelicaError error = felica_poller_frame_exchange(
instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT);
if(error != FelicaErrorNone) {
FURI_LOG_E(TAG, "Request system code failed with error: %d", error);
return error;
}
size_t rx_len = bit_buffer_get_size_bytes(instance->rx_buffer);
if(rx_len < sizeof(FelicaCommandHeaderRaw) + 3) return FelicaErrorProtocol;
// at least 1 system code + the count being 0x01
// error is known to be FelicaErrorNone here
*response_ptr = (FelicaListSystemCodeCommandResponse*)bit_buffer_get_data(instance->rx_buffer);
return error;
}