mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2025-10-04 11:07:02 +02:00
Use flags for ISO14443-4 layer decode result
This commit is contained in:
@@ -59,9 +59,11 @@ struct Iso14443_4Layer {
|
||||
uint8_t nad;
|
||||
};
|
||||
|
||||
static inline void iso14443_4_layer_update_pcb(Iso14443_4Layer* instance) {
|
||||
static inline void iso14443_4_layer_update_pcb(Iso14443_4Layer* instance, bool toggle_num) {
|
||||
instance->pcb_prev = instance->pcb;
|
||||
instance->pcb ^= (uint8_t)0x01;
|
||||
if(toggle_num) {
|
||||
instance->pcb ^= (uint8_t)0x01;
|
||||
}
|
||||
}
|
||||
|
||||
Iso14443_4Layer* iso14443_4_layer_alloc(void) {
|
||||
@@ -115,7 +117,7 @@ void iso14443_4_layer_encode_command(
|
||||
bit_buffer_append_byte(block_data, instance->pcb);
|
||||
bit_buffer_append(block_data, input_data);
|
||||
|
||||
iso14443_4_layer_update_pcb(instance);
|
||||
iso14443_4_layer_update_pcb(instance, true);
|
||||
}
|
||||
|
||||
static inline uint8_t iso14443_4_layer_get_response_pcb(const BitBuffer* block_data) {
|
||||
@@ -137,7 +139,7 @@ bool iso14443_4_layer_decode_response(
|
||||
ret = (ISO14443_4_BLOCK_PCB_IS_R_BLOCK(response_pcb)) &&
|
||||
(!ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(response_pcb));
|
||||
instance->pcb &= ISO14443_4_BLOCK_PCB_MASK;
|
||||
iso14443_4_layer_update_pcb(instance);
|
||||
iso14443_4_layer_update_pcb(instance, true);
|
||||
} else if(ISO14443_4_BLOCK_PCB_IS_CHAIN_ACTIVE(instance->pcb_prev)) {
|
||||
const uint8_t response_pcb = iso14443_4_layer_get_response_pcb(block_data);
|
||||
ret = (ISO14443_4_BLOCK_PCB_IS_R_BLOCK(response_pcb)) &&
|
||||
@@ -165,65 +167,69 @@ void iso14443_4_layer_set_nad_supported(Iso14443_4Layer* instance, bool nad) {
|
||||
instance->nad = nad ? 0 : ISO14443_4_LAYER_NAD_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Iso14443_4LayerStatus iso14443_4_layer_decode_command(
|
||||
Iso14443_4LayerResult iso14443_4_layer_decode_command(
|
||||
Iso14443_4Layer* instance,
|
||||
const BitBuffer* input_data,
|
||||
BitBuffer* block_data) {
|
||||
uint8_t prologue_len = 0;
|
||||
instance->pcb_prev = bit_buffer_get_byte(input_data, prologue_len++);
|
||||
furi_assert(instance);
|
||||
|
||||
if(ISO14443_4_BLOCK_PCB_IS_I_BLOCK(instance->pcb_prev)) {
|
||||
if(instance->pcb_prev & ISO14443_4_BLOCK_PCB_I_CID_MASK) {
|
||||
uint8_t prologue_len = 0;
|
||||
instance->pcb = bit_buffer_get_byte(input_data, prologue_len++);
|
||||
|
||||
if(ISO14443_4_BLOCK_PCB_IS_I_BLOCK(instance->pcb)) {
|
||||
if(instance->pcb & ISO14443_4_BLOCK_PCB_I_CID_MASK) {
|
||||
const uint8_t cid = bit_buffer_get_byte(input_data, prologue_len++) &
|
||||
ISO14443_4_BLOCK_CID_MASK;
|
||||
if(instance->cid == ISO14443_4_LAYER_CID_NOT_SUPPORTED || cid != instance->cid) {
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
} else if(instance->cid != ISO14443_4_LAYER_CID_NOT_SUPPORTED && instance->cid != 0) {
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
if(instance->pcb_prev & ISO14443_4_BLOCK_PCB_I_NAD_MASK) {
|
||||
if(instance->pcb & ISO14443_4_BLOCK_PCB_I_NAD_MASK) {
|
||||
if(instance->nad == ISO14443_4_LAYER_NAD_NOT_SUPPORTED) {
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
instance->nad = bit_buffer_get_byte(input_data, prologue_len++);
|
||||
// FIXME: unset NAD when chaining after first block
|
||||
}
|
||||
// FIXME: chaining
|
||||
bit_buffer_copy_right(block_data, input_data, prologue_len);
|
||||
return Iso14443_4LayerStatusOk;
|
||||
iso14443_4_layer_update_pcb(instance, false);
|
||||
return Iso14443_4LayerResultData;
|
||||
|
||||
} else if(ISO14443_4_BLOCK_PCB_IS_S_BLOCK(instance->pcb_prev)) {
|
||||
if(instance->pcb_prev & ISO14443_4_BLOCK_PCB_S_CID_MASK) {
|
||||
} else if(ISO14443_4_BLOCK_PCB_IS_S_BLOCK(instance->pcb)) {
|
||||
if(instance->pcb & ISO14443_4_BLOCK_PCB_S_CID_MASK) {
|
||||
const uint8_t cid = bit_buffer_get_byte(input_data, prologue_len++) &
|
||||
ISO14443_4_BLOCK_CID_MASK;
|
||||
if(instance->cid == ISO14443_4_LAYER_CID_NOT_SUPPORTED || cid != instance->cid) {
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
} else if(instance->cid != ISO14443_4_LAYER_CID_NOT_SUPPORTED && instance->cid != 0) {
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
if((instance->pcb_prev & ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_MASK) == 0) {
|
||||
if((instance->pcb & ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_MASK) == 0) {
|
||||
// DESELECT
|
||||
bit_buffer_copy(block_data, input_data);
|
||||
return Iso14443_4LayerStatusSendAndHalt;
|
||||
return Iso14443_4LayerResultSend | Iso14443_4LayerResultHalt;
|
||||
} else {
|
||||
// WTX ACK or wrong value
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
|
||||
// FIXME: R blocks
|
||||
}
|
||||
return Iso14443_4LayerStatusIgnore;
|
||||
return Iso14443_4LayerResultSkip;
|
||||
}
|
||||
|
||||
bool iso14443_4_layer_encode_response(
|
||||
Iso14443_4Layer* instance,
|
||||
const BitBuffer* input_data,
|
||||
BitBuffer* block_data) {
|
||||
furi_assert(instance);
|
||||
|
||||
if(ISO14443_4_BLOCK_PCB_IS_I_BLOCK(instance->pcb_prev)) {
|
||||
instance->pcb = instance->pcb_prev;
|
||||
bit_buffer_append_byte(block_data, instance->pcb);
|
||||
bit_buffer_append_byte(block_data, 0x00);
|
||||
if(instance->pcb_prev & ISO14443_4_BLOCK_PCB_I_CID_MASK) {
|
||||
bit_buffer_append_byte(block_data, instance->cid);
|
||||
}
|
||||
@@ -239,6 +245,7 @@ bool iso14443_4_layer_encode_response(
|
||||
instance->pcb &= ~ISO14443_4_BLOCK_PCB_I_CHAIN_MASK;
|
||||
bit_buffer_set_byte(block_data, 0, instance->pcb);
|
||||
bit_buffer_append(block_data, input_data);
|
||||
iso14443_4_layer_update_pcb(instance, false);
|
||||
return true;
|
||||
|
||||
// FIXME: R blocks
|
||||
|
@@ -33,12 +33,13 @@ bool iso14443_4_layer_decode_response(
|
||||
// Listener mode
|
||||
|
||||
typedef enum {
|
||||
Iso14443_4LayerStatusOk,
|
||||
Iso14443_4LayerStatusIgnore,
|
||||
Iso14443_4LayerStatusSendAndHalt,
|
||||
} Iso14443_4LayerStatus;
|
||||
Iso14443_4LayerResultSkip = (0),
|
||||
Iso14443_4LayerResultData = (1 << 1),
|
||||
Iso14443_4LayerResultSend = (1 << 2),
|
||||
Iso14443_4LayerResultHalt = (1 << 3),
|
||||
} Iso14443_4LayerResult;
|
||||
|
||||
Iso14443_4LayerStatus iso14443_4_layer_decode_command(
|
||||
Iso14443_4LayerResult iso14443_4_layer_decode_command(
|
||||
Iso14443_4Layer* instance,
|
||||
const BitBuffer* input_data,
|
||||
BitBuffer* block_data);
|
||||
|
@@ -88,19 +88,21 @@ static NfcCommand iso14443_4a_listener_run(NfcGenericEvent event, void* context)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Iso14443_4LayerStatus status =
|
||||
Iso14443_4LayerResult status =
|
||||
iso14443_4_layer_decode_command(instance->iso14443_4_layer, rx_buffer, rx_buffer);
|
||||
if(status == Iso14443_4LayerStatusSendAndHalt) {
|
||||
if(iso14443_3a_listener_send_standard_frame(
|
||||
instance->iso14443_3a_listener, rx_buffer) == Iso14443_3aErrorNone) {
|
||||
iso14443_4a_listener_reset(instance);
|
||||
if(instance->callback) {
|
||||
instance->iso14443_4a_event.type = Iso14443_4aListenerEventTypeHalted;
|
||||
instance->callback(instance->generic_event, instance->context);
|
||||
}
|
||||
command = NfcCommandSleep;
|
||||
if(status & Iso14443_4LayerResultSend) {
|
||||
iso14443_3a_listener_send_standard_frame(
|
||||
instance->iso14443_3a_listener, rx_buffer);
|
||||
}
|
||||
if(status & Iso14443_4LayerResultHalt) {
|
||||
iso14443_4a_listener_reset(instance);
|
||||
if(instance->callback) {
|
||||
instance->iso14443_4a_event.type = Iso14443_4aListenerEventTypeHalted;
|
||||
instance->callback(instance->generic_event, instance->context);
|
||||
}
|
||||
} else if(status == Iso14443_4LayerStatusOk) {
|
||||
command = NfcCommandSleep;
|
||||
}
|
||||
if(status & Iso14443_4LayerResultData) {
|
||||
instance->iso14443_4a_event.type = Iso14443_4aListenerEventTypeReceivedData;
|
||||
instance->iso14443_4a_event.data->buffer = rx_buffer;
|
||||
|
||||
|
Reference in New Issue
Block a user