Hi @AlexanderB ,
yes I am reading from another HCE target with the CLRC663(using mainly MFRC630 functions). So my HCE target is an android app. I have the same issue using only the desfire card so can not blaim the android app for it.
I am sending APDU commands to read and write into desfire card (or the HCE) I have no problem writing into the card and gettting the success response, bearing in mind that using other devices I can fully read whatever I wrote in the file.
I also need to be able to read what I wrote into the file, but am limited to 14 bytes read!
Here I attached my code:
typedef struct {
uint8_t FileNo[1];
uint8_t Offset[3];
uint8_t Length[3];
}EmulatedCard;
//============================================================
uint8_t ReadDataSetting[18] = {0}; // I know my data is 18 bytes as I wrote 16bytes into the file +2 // bytes operation status
EmulatedCard LockSettig = {{0x01}, {0x07, 0x00, 0x00}, {sizeof(ReadDataSetting), 0x00, 0x00}};
MIFARE_Emulated_ReadData( ReadDataSetting, sizeof(ReadDataSetting), LockSettig.FileNo, LockSettig.Offset, LockSettig.Length);
//============================================================
void MIFARE_Emulated_ReadData(uint8_t ReadData[], uint32_t* ReadDataSize, uint8_t FileNo[], uint8_t Offset[], uint8_t Length[]){
uint8_t cmd[8] = {0};
cmd[0] = 0xBD; // --------------Command for Reading
memcpy(cmd +1, FileNo, 1);
memcpy(cmd +2, Offset, 3);
memcpy(cmd +5, Length, 3);
uint8_t status = CLRC663_14443p4_transfer(cmd, sizeof(cmd), ReadData, &ReadDataSize);
}
// ================================================================
uint8_t CLRC663_14443p4_transfer(uint8_t cmd[], uint32_t cmdSize, uint8_t data[], uint32_t* dataSize)
{
uint8_t req[cmdSize+1];
req[0] = get_pcb();
memcpy(&req[1], cmd, cmdSize);
uint32_t reqSize = sizeof(req);
uint8_t status = 0;
uint32_t retries = 6;
uint8_t bCheckNad;
do
{
uint32_t dataSize = sizeof(data);
status = CLRC663_transfer(req, reqSize, data, &dataSize);
if(status>0)
{
/* NXP phpalI14443p4_Sw.c */
/* I-Block handling */
if (0u != (PHPAL_I14443P4_SW_IS_I_BLOCK(data[PHPAL_I14443P4_SW_PCB_POS])))
{
//OK
break;
}
/* R(ACK) handling */
else if ((PHPAL_I14443P4_SW_IS_R_BLOCK(data[PHPAL_I14443P4_SW_PCB_POS]) > 0U) && (PHPAL_I14443P4_SW_IS_ACK(data[PHPAL_I14443P4_SW_PCB_POS]) > 0U))
{
break;
}
/* S(WTX) handling */
else if ((PHPAL_I14443P4_SW_IS_S_BLOCK(data[PHPAL_I14443P4_SW_PCB_POS]) > 0U) && (PHPAL_I14443P4_SW_IS_WTX(data[PHPAL_I14443P4_SW_PCB_POS]) > 0U))
{
/* Retrieve WTXM */
uint8_t bWtxm = data[dataSize-1u];
/* Ignore and clear the Power Level Indication */
bWtxm &= 0x3FU;
/* Generate S(WTX) frame */
/* S-Block PCB */
req[PHPAL_I14443P4_SW_PCB_POS] = PHPAL_I14443P4_SW_S_BLOCK | PHPAL_I14443P4_SW_S_BLOCK_RFU_BITS;
req[PHPAL_I14443P4_SW_PCB_POS] |= PHPAL_I14443P4_SW_PCB_WTX;
req[PHPAL_I14443P4_SW_PCB_POS+1] = bWtxm;
reqSize = 2;
//TODO: wait?
}
/* S(DESELECT) handling */
else if ((PHPAL_I14443P4_SW_IS_S_BLOCK(data[PHPAL_I14443P4_SW_PCB_POS]) > 0U) && (PHPAL_I14443P4_SW_IS_DESELECT(data[PHPAL_I14443P4_SW_PCB_POS]) > 0U))
{
/* S-Block PCB */
req[PHPAL_I14443P4_SW_PCB_POS] = PHPAL_I14443P4_SW_S_BLOCK | PHPAL_I14443P4_SW_S_BLOCK_RFU_BITS;
reqSize = 1;
}
/* We received an invalid block */
else
{
break;
}
}
else
break;
--retries;
}while(retries!=0);
return status;
}
// ===============================================================
uint8_t CLRC663_transfer(uint8_t cmd[], uint32_t cmdSize, uint8_t data[], uint32_t* dataSize)
{
CLRC663_flush_fifo();
CLRC663_write_reg(CLRC663_REG_TXCRCPRESET, CLRC663_RECOM_14443A_CRC | CLRC663_CRC_ON);
CLRC663_write_reg(CLRC663_REG_RXCRCCON, CLRC663_RECOM_14443A_CRC | CLRC663_CRC_ON);
// configure a timeout timer.
uint8_t timer_for_timeout = 0; // should match the enabled interupt.
// enable the global IRQ for idle, errors and timer.
CLRC663_write_reg(CLRC663_REG_IRQ0EN, CLRC663_IRQ0EN_IDLE_IRQEN | CLRC663_IRQ0EN_ERR_IRQEN);
CLRC663_write_reg(CLRC663_REG_IRQ1EN, CLRC663_IRQ1EN_TIMER0_IRQEN);
// Set timer to 221 kHz clock, start at the end of Tx.
CLRC663_timer_set_control(timer_for_timeout, CLRC663_TCONTROL_CLK_211KHZ | CLRC663_TCONTROL_START_TX_END);
// Frame waiting time: FWT = (256 x 16/fc) x 2 FWI
// FWI defaults to four... so that would mean wait for a maximum of ~ 5ms
CLRC663_timer_set_reload(timer_for_timeout, 20000); // 20000 ticks of 5 usec is 100 ms.
CLRC663_timer_set_value(timer_for_timeout, 20000);
uint8_t irq1_value = 0;
uint8_t irq0_value = 0;
CLRC663_clear_irq0(); // clear irq0
CLRC663_clear_irq1(); // clear irq1
// Go into send, then straight after in receive.
CLRC663_cmd_transceive(cmd, cmdSize);
// block until we are done
while (!(irq1_value & (1 << timer_for_timeout))) {
irq1_value = CLRC663_irq1();
if (irq1_value & CLRC663_IRQ1_GLOBAL_IRQ) {
break; // stop polling irq1 and quit the timeout loop.
}
}
CLRC663_cmd_idle();
if (irq1_value & (1 << timer_for_timeout)) {
return 0;
}
irq0_value = CLRC663_irq0();
if ((!(irq0_value &CLRC663_IRQ0_RX_IRQ)) || (irq0_value & CLRC663_IRQ0_ERR_IRQ)) {
// some error
if((irq0_value & CLRC663_IRQ0_ERR_IRQ)) {
uint8_t error = CLRC663_read_reg(CLRC663_REG_ERROR);
}
return 0;
}
//HAL_Delay(10);
// all seems to be well...
uint16_t buffer_length = CLRC663_fifo_length();
uint8_t rx_len = (buffer_length <= *dataSize) ? buffer_length : *dataSize;
fifo_readall(data, rx_len);
// CLRC663_read_fifo(data, rx_len);
*dataSize = rx_len;
return rx_len;
}
so at this line, buffer_length = CLRC663_fifo_length() , fifo length does not go higher than 14 bytes and hence I can't read any more data.
I really appreciate any help.
Kind regards,
Mina