Skip to content

Commit 3361e70

Browse files
authored
Merge pull request #20 from bettse/t_1
T=1
2 parents a19b63d + 29f36f5 commit 3361e70

File tree

7 files changed

+333
-31
lines changed

7 files changed

+333
-31
lines changed

ccid.c

+59-23
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,44 @@ void seader_ccid_GetSlotStatus(SeaderUartBridge* seader_uart, uint8_t slot) {
6363
void seader_ccid_SetParameters(Seader* seader, uint8_t slot, uint8_t* atr, size_t atr_len) {
6464
SeaderWorker* seader_worker = seader->worker;
6565
SeaderUartBridge* seader_uart = seader_worker->uart;
66-
UNUSED(slot);
67-
UNUSED(atr);
6866
UNUSED(atr_len);
69-
uint8_t T1 = 1;
67+
FURI_LOG_D(TAG, "seader_ccid_SetParameters(%d)", slot);
68+
69+
uint8_t payloadLen = 0;
70+
if(seader_uart->T == 0) {
71+
payloadLen = 5;
72+
} else if(atr[4] == 0xB1 && seader_uart->T == 1) {
73+
payloadLen = 7;
74+
}
7075
memset(seader_uart->tx_buf, 0, SEADER_UART_RX_BUF_SIZE);
7176
seader_uart->tx_buf[0] = SYNC;
7277
seader_uart->tx_buf[1] = CTRL;
7378
seader_uart->tx_buf[2 + 0] = CCID_MESSAGE_TYPE_PC_to_RDR_SetParameters;
74-
seader_uart->tx_buf[2 + 1] = 0;
75-
seader_uart->tx_buf[2 + 5] = sam_slot;
76-
seader_uart->tx_buf[2 + 6] = getSequence(sam_slot);
77-
seader_uart->tx_buf[2 + 7] = T1;
79+
seader_uart->tx_buf[2 + 1] = payloadLen;
80+
seader_uart->tx_buf[2 + 5] = slot;
81+
seader_uart->tx_buf[2 + 6] = getSequence(slot);
82+
seader_uart->tx_buf[2 + 7] = seader_uart->T;
7883
seader_uart->tx_buf[2 + 8] = 0;
7984
seader_uart->tx_buf[2 + 9] = 0;
8085

81-
seader_uart->tx_len = seader_add_lrc(seader_uart->tx_buf, 2 + 10);
86+
if(seader_uart->T == 0) {
87+
// I'm leaving this here for completeness, but it was actually causing ICC_MUTE on the first apdu.
88+
seader_uart->tx_buf[2 + 10] = 0x96; //atr[2]; //bmFindexDindex
89+
seader_uart->tx_buf[2 + 11] = 0x00; //bmTCCKST1
90+
seader_uart->tx_buf[2 + 12] = 0x00; //bGuardTimeT0
91+
seader_uart->tx_buf[2 + 13] = 0x0a; //bWaitingIntegerT0
92+
seader_uart->tx_buf[2 + 14] = 0x00; //bClockStop
93+
} else if(seader_uart->T == 1) {
94+
seader_uart->tx_buf[2 + 10] = atr[2]; //bmFindexDindex
95+
seader_uart->tx_buf[2 + 11] = 0x10; //bmTCCKST1
96+
seader_uart->tx_buf[2 + 12] = 0xfe; //bGuardTimeT1
97+
seader_uart->tx_buf[2 + 13] = atr[6]; //bWaitingIntegerT1
98+
seader_uart->tx_buf[2 + 14] = atr[8]; //bClockStop
99+
seader_uart->tx_buf[2 + 15] = atr[5]; //bIFSC
100+
seader_uart->tx_buf[2 + 16] = 0x00; //bNadValue
101+
}
82102

103+
seader_uart->tx_len = seader_add_lrc(seader_uart->tx_buf, 2 + 10 + payloadLen);
83104
furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
84105
}
85106

@@ -121,14 +142,16 @@ void seader_ccid_XfrBlockToSlot(
121142
seader_uart->tx_buf[2 + 8] = 0;
122143
seader_uart->tx_buf[2 + 9] = 0;
123144

124-
memcpy(seader_uart->tx_buf + 2 + 10, data, len);
125-
seader_uart->tx_len = seader_add_lrc(seader_uart->tx_buf, 2 + 10 + len);
145+
uint8_t header_len = 2 + 10;
146+
memcpy(seader_uart->tx_buf + header_len, data, len);
147+
seader_uart->tx_len = header_len + len;
148+
seader_uart->tx_len = seader_add_lrc(seader_uart->tx_buf, seader_uart->tx_len);
126149

127150
char display[SEADER_UART_RX_BUF_SIZE * 2 + 1] = {0};
128151
for(uint8_t i = 0; i < seader_uart->tx_len; i++) {
129152
snprintf(display + (i * 2), sizeof(display), "%02x", seader_uart->tx_buf[i]);
130153
}
131-
FURI_LOG_D(TAG, "seader_ccid_XfrBlock %d bytes: %s", seader_uart->tx_len, display);
154+
FURI_LOG_D(TAG, "seader_ccid_XfrBlockToSlot(%d) %d: %s", slot, seader_uart->tx_len, display);
132155

133156
furi_thread_flags_set(furi_thread_get_id(seader_uart->tx_thread), WorkerEvtSamRx);
134157
}
@@ -319,10 +342,25 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
319342
return message.consumed;
320343
}
321344

322-
if(message.bMessageType == CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock) {
345+
if(message.bMessageType == CCID_MESSAGE_TYPE_RDR_to_PC_Parameters) {
346+
FURI_LOG_D(TAG, "Got Parameters");
347+
if(seader_uart->T == 1) {
348+
seader_t_1_set_IFSD(seader);
349+
} else {
350+
seader_worker_send_version(seader);
351+
if(seader_worker->callback) {
352+
seader_worker->callback(SeaderWorkerEventSamPresent, seader_worker->context);
353+
}
354+
}
355+
} else if(message.bMessageType == CCID_MESSAGE_TYPE_RDR_to_PC_DataBlock) {
323356
if(hasSAM) {
324357
if(message.bSlot == sam_slot) {
325-
seader_worker_process_sam_message(seader, message.payload, message.dwLength);
358+
if(seader_uart->T == 0) {
359+
seader_worker_process_sam_message(
360+
seader, message.payload, message.dwLength);
361+
} else if(seader_uart->T == 1) {
362+
seader_recv_t1(seader, &message);
363+
}
326364
} else {
327365
FURI_LOG_D(TAG, "Discarding message on non-sam slot");
328366
}
@@ -331,20 +369,18 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
331369
FURI_LOG_I(TAG, "SAM ATR!");
332370
hasSAM = true;
333371
sam_slot = message.bSlot;
334-
seader_worker_send_version(seader);
335-
if(seader_worker->callback) {
336-
seader_worker->callback(
337-
SeaderWorkerEventSamPresent, seader_worker->context);
372+
if(seader_uart->T == 0) {
373+
seader_ccid_GetParameters(seader_uart);
374+
} else if(seader_uart->T == 1) {
375+
seader_ccid_SetParameters(
376+
seader, sam_slot, message.payload, message.dwLength);
338377
}
339378
} else if(memcmp(SAM_ATR2, message.payload, sizeof(SAM_ATR2)) == 0) {
340379
FURI_LOG_I(TAG, "SAM ATR2!");
341380
hasSAM = true;
342381
sam_slot = message.bSlot;
343-
seader_worker_send_version(seader);
344-
if(seader_worker->callback) {
345-
seader_worker->callback(
346-
SeaderWorkerEventSamPresent, seader_worker->context);
347-
}
382+
// I don't have an ATR2 to test with
383+
seader_ccid_GetParameters(seader_uart);
348384
} else {
349385
FURI_LOG_W(TAG, "Unknown ATR");
350386
if(seader_worker->callback) {
@@ -353,7 +389,7 @@ size_t seader_ccid_process(Seader* seader, uint8_t* cmd, size_t cmd_len) {
353389
}
354390
}
355391
} else {
356-
FURI_LOG_W(TAG, "Unhandled CCID message type %d", message.bMessageType);
392+
FURI_LOG_W(TAG, "Unhandled CCID message type %02x", message.bMessageType);
357393
}
358394
}
359395

sam_api.c

+27-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#define TAG "SAMAPI"
88

9-
#define APDU_HEADER_LEN 5
109
#define ASN1_PREFIX 6
1110
#define ASN1_DEBUG true
1211
#define SEADER_ICLASS_SR_SIO_BASE_BLOCK 10
@@ -137,19 +136,24 @@ void seader_picopass_state_machine(Seader* seader, uint8_t* buffer, size_t len)
137136
bit_buffer_free(rx_buffer);
138137
}
139138

139+
uint8_t APDU_HEADER_LEN = 5;
140140
bool seader_send_apdu(
141141
Seader* seader,
142142
uint8_t CLA,
143143
uint8_t INS,
144144
uint8_t P1,
145145
uint8_t P2,
146146
uint8_t* payload,
147-
uint8_t length) {
147+
uint8_t payloadLen) {
148148
SeaderWorker* seader_worker = seader->worker;
149149
SeaderUartBridge* seader_uart = seader_worker->uart;
150150

151-
if(APDU_HEADER_LEN + length > SEADER_UART_RX_BUF_SIZE) {
152-
FURI_LOG_E(TAG, "Cannot send message, too long: %d", APDU_HEADER_LEN + length);
151+
if(seader_uart->T == 1) {
152+
APDU_HEADER_LEN = 7;
153+
}
154+
155+
if(APDU_HEADER_LEN + payloadLen > SEADER_UART_RX_BUF_SIZE) {
156+
FURI_LOG_E(TAG, "Cannot send message, too long: %d", APDU_HEADER_LEN + payloadLen);
153157
return false;
154158
}
155159

@@ -158,16 +162,30 @@ bool seader_send_apdu(
158162
apdu[1] = INS;
159163
apdu[2] = P1;
160164
apdu[3] = P2;
161-
apdu[4] = length;
162-
memcpy(apdu + APDU_HEADER_LEN, payload, length);
165+
166+
if(seader_uart->T == 1) {
167+
apdu[4] = 0x00;
168+
apdu[5] = 0x00;
169+
apdu[6] = payloadLen;
170+
} else {
171+
apdu[4] = payloadLen;
172+
}
173+
174+
memcpy(apdu + APDU_HEADER_LEN, payload, payloadLen);
175+
uint8_t length = APDU_HEADER_LEN + payloadLen;
163176

164177
memset(display, 0, sizeof(display));
165-
for(uint8_t i = 0; i < APDU_HEADER_LEN + length; i++) {
178+
for(uint8_t i = 0; i < length; i++) {
166179
snprintf(display + (i * 2), sizeof(display), "%02x", apdu[i]);
167180
}
168181
FURI_LOG_D(TAG, "seader_send_apdu %s", display);
169182

170-
seader_ccid_XfrBlock(seader_uart, apdu, APDU_HEADER_LEN + length);
183+
if(seader_uart->T == 1) {
184+
seader_send_t1(seader_uart, apdu, length);
185+
} else {
186+
seader_ccid_XfrBlock(seader_uart, apdu, length);
187+
}
188+
171189
return true;
172190
}
173191

@@ -629,6 +647,7 @@ void seader_iso15693_transmit(
629647
uint8_t* buffer,
630648
size_t len) {
631649
SeaderWorker* seader_worker = seader->worker;
650+
632651
BitBuffer* tx_buffer = bit_buffer_alloc(len);
633652
BitBuffer* rx_buffer = bit_buffer_alloc(SEADER_POLLER_MAX_BUFFER_SIZE);
634653

seader_bridge.h

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ struct SeaderUartBridge {
4242
uint8_t rx_buf[SEADER_UART_RX_BUF_SIZE];
4343
uint8_t tx_buf[SEADER_UART_RX_BUF_SIZE];
4444
size_t tx_len;
45+
46+
// T=0 or T=1
47+
uint8_t T;
4548
};
4649

4750
typedef struct SeaderUartBridge SeaderUartBridge;

seader_i.h

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "ccid.h"
5252
#include "uart.h"
5353
#include "lrc.h"
54+
#include "t_1.h"
5455
#include "seader_worker.h"
5556
#include "seader_credential.h"
5657

0 commit comments

Comments
 (0)