diff --git a/ccid.c b/ccid.c index 75e7976..a091a31 100644 --- a/ccid.c +++ b/ccid.c @@ -11,7 +11,6 @@ bool powered[2] = {false, false}; uint8_t sam_slot = 0; uint8_t sequence[2] = {0, 0}; uint8_t retries = 3; -uint8_t T = 0; uint8_t getSequence(uint8_t slot) { if(sequence[slot] > 254) { @@ -66,31 +65,32 @@ void seader_ccid_SetParameters(Seader* seader, uint8_t slot, uint8_t* atr, size_ SeaderUartBridge* seader_uart = seader_worker->uart; UNUSED(atr_len); FURI_LOG_D(TAG, "seader_ccid_SetParameters(%d)", slot); - if(memcmp(SAM_ATR2, atr, sizeof(SAM_ATR2)) == 0) { - // I don't have an ATR2 to test with - seader_worker_send_version(seader); - if(seader_worker->callback) { - seader_worker->callback(SeaderWorkerEventSamPresent, seader_worker->context); - } - return; - } + uint8_t payloadLen = 0; - if(atr[4] == 0xB1) { - T = 1; + if(seader_uart->T == 0) { + payloadLen = 5; + } else if(atr[4] == 0xB1 && seader_uart->T == 1) { payloadLen = 7; } memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE); seader_uart->tx_buf[0] = SYNC; seader_uart->tx_buf[1] = CTRL; seader_uart->tx_buf[2 + 0] = CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters; - seader_uart->tx_buf[2 + 1] = 0x07; + seader_uart->tx_buf[2 + 1] = payloadLen; seader_uart->tx_buf[2 + 5] = slot; seader_uart->tx_buf[2 + 6] = getSequence(slot); - seader_uart->tx_buf[2 + 7] = T; + seader_uart->tx_buf[2 + 7] = seader_uart->T; seader_uart->tx_buf[2 + 8] = 0; seader_uart->tx_buf[2 + 9] = 0; - if(T == 1) { + if(seader_uart->T == 0) { + // I'm leaving this here for completeness, but it was actually causing ICC_MUTE on the first apdu. + seader_uart->tx_buf[2 + 10] = 0x96; //atr[2]; //bmFindexDindex + seader_uart->tx_buf[2 + 11] = 0x00; //bmTCCKST1 + seader_uart->tx_buf[2 + 12] = 0x00; //bGuardTimeT0 + seader_uart->tx_buf[2 + 13] = 0x0a; //bWaitingIntegerT0 + seader_uart->tx_buf[2 + 14] = 0x00; //bClockStop + } else if(seader_uart->T == 1) { seader_uart->tx_buf[2 + 10] = atr[2]; //bmFindexDindex seader_uart->tx_buf[2 + 11] = 0x10; //bmTCCKST1 seader_uart->tx_buf[2 + 12] = 0xfe; //bGuardTimeT1 @@ -144,12 +144,6 @@ void seader_ccid_XfrBlockToSlot( uint8_t header_len = 2 + 10; memcpy(seader_uart->tx_buf + header_len, data, len); seader_uart->tx_len = header_len + len; - - if (T == 1) { - seader_add_lrc(seader_uart->tx_buf + 2 + 10, len + 3); - seader_uart->tx_len += 1; - } - seader_uart->tx_len = seader_add_lrc(seader_uart->tx_buf, seader_uart->tx_len); char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0}; @@ -349,11 +343,23 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) { if(message.bMessageType == CCID_MESSAGE_TYPE_RDR_to_PC_Parameters) { FURI_LOG_D(TAG, "Got Parameters"); - seader_t_1_set_IFSD(seader); + if(seader_uart->T == 1) { + seader_t_1_set_IFSD(seader); + } else { + seader_worker_send_version(seader); + if(seader_worker->callback) { + seader_worker->callback(SeaderWorkerEventSamPresent, seader_worker->context); + } + } } else if(message.bMessageType == CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock) { if(hasSAM) { if(message.bSlot == sam_slot) { - seader_recv_t1(seader, &message); + if(seader_uart->T == 0) { + seader_worker_process_sam_message( + seader, message.payload, message.dwLength); + } else if(seader_uart->T == 1) { + seader_recv_t1(seader, &message); + } } else { FURI_LOG_D(TAG, "Discarding message on non-sam slot"); } @@ -362,12 +368,18 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) { FURI_LOG_I(TAG, "SAM ATR!"); hasSAM = true; sam_slot = message.bSlot; - seader_ccid_SetParameters(seader, sam_slot, message.payload, message.dwLength); + if(seader_uart->T == 0) { + seader_ccid_GetParameters(seader_uart); + } else if(seader_uart->T == 1) { + seader_ccid_SetParameters( + seader, sam_slot, message.payload, message.dwLength); + } } else if(memcmp(SAM_ATR2, message.payload, sizeof(SAM_ATR2)) == 0) { FURI_LOG_I(TAG, "SAM ATR2!"); hasSAM = true; sam_slot = message.bSlot; - seader_ccid_SetParameters(seader, sam_slot, message.payload, message.dwLength); + // I don't have an ATR2 to test with + seader_ccid_GetParameters(seader_uart); } else { FURI_LOG_W(TAG, "Unknown ATR"); if(seader_worker->callback) { diff --git a/sam_api.c b/sam_api.c index 107ae31..0a08827 100644 --- a/sam_api.c +++ b/sam_api.c @@ -136,7 +136,7 @@ void seader_picopass_state_machine(Seader* seader, uint8_t* buffer, size_t len) bit_buffer_free(rx_buffer); } -#define APDU_HEADER_LEN 7 +uint8_t APDU_HEADER_LEN = 5; bool seader_send_apdu( Seader* seader, uint8_t CLA, @@ -148,6 +148,10 @@ bool seader_send_apdu( SeaderWorker* seader_worker = seader->worker; SeaderUartBridge* seader_uart = seader_worker->uart; + if(seader_uart->T == 1) { + APDU_HEADER_LEN = 7; + } + if(APDU_HEADER_LEN + payloadLen > SEADER_UART_RX_BUF_SIZE) { FURI_LOG_E(TAG, "Cannot send message, too long: %d", APDU_HEADER_LEN + payloadLen); return false; @@ -158,9 +162,15 @@ bool seader_send_apdu( apdu[1] = INS; apdu[2] = P1; apdu[3] = P2; - apdu[4] = 0x00; - apdu[5] = 0x00; - apdu[6] = payloadLen; + + if(seader_uart->T == 1) { + apdu[4] = 0x00; + apdu[5] = 0x00; + apdu[6] = payloadLen; + } else { + apdu[4] = payloadLen; + } + memcpy(apdu + APDU_HEADER_LEN, payload, payloadLen); uint8_t length = APDU_HEADER_LEN + payloadLen; @@ -170,7 +180,12 @@ bool seader_send_apdu( } FURI_LOG_D(TAG, "seader_send_apdu %s", display); - seader_send_t1(seader_uart, apdu, length); + if(seader_uart->T == 1) { + seader_send_t1(seader_uart, apdu, length); + } else { + seader_ccid_XfrBlock(seader_uart, apdu, length); + } + return true; } @@ -632,6 +647,7 @@ void seader_iso15693_transmit( uint8_t* buffer, size_t len) { SeaderWorker* seader_worker = seader->worker; + BitBuffer* tx_buffer = bit_buffer_alloc(len); BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE); diff --git a/seader_bridge.h b/seader_bridge.h index 66602f4..0c68abe 100644 --- a/seader_bridge.h +++ b/seader_bridge.h @@ -42,6 +42,9 @@ struct SeaderUartBridge { uint8_t rx_buf[SEADER_UART_RX_BUF_SIZE]; uint8_t tx_buf[SEADER_UART_RX_BUF_SIZE]; size_t tx_len; + + // T=0 or T=1 + uint8_t T; }; typedef struct SeaderUartBridge SeaderUartBridge; diff --git a/t_1.c b/t_1.c index 837645f..5ac85bb 100644 --- a/t_1.c +++ b/t_1.c @@ -6,10 +6,10 @@ /* I know my T=1 is terrible, but I'm also only targetting one specific 'card' */ -#define MORE_BIT 0x20 -#define IFSD_VALUE 0xfe -#define IFSC_VALUE 0xfe // Fom the SAM ATR -#define R_BLOCK 0x80 +#define MORE_BIT 0x20 +#define IFSD_VALUE 0xfe +#define IFSC_VALUE 0xfe // Fom the SAM ATR +#define R_BLOCK 0x80 #define R_SEQUENCE_NUMBER_MASK 0x10 // TODO: T1 struct diff --git a/uart.c b/uart.c index 3929572..2e7632b 100644 --- a/uart.c +++ b/uart.c @@ -159,6 +159,9 @@ int32_t seader_uart_worker(void* context) { SeaderUartBridge* seader_uart_enable(SeaderUartConfig* cfg, Seader* seader) { SeaderUartBridge* seader_uart = malloc(sizeof(SeaderUartBridge)); + seader_uart->T = 0; + seader_uart->T = (seader->is_debug_enabled ? 1 : 0); + memcpy(&(seader_uart->cfg_new), cfg, sizeof(SeaderUartConfig)); seader_uart->thread =