Skip to content

Commit 16c1b5a

Browse files
authored
Merge pull request #48 from josevcm/develop
fixed ATR detection for some cards
2 parents d1d1760 + 9286d50 commit 16c1b5a

File tree

4 files changed

+33
-23
lines changed

4 files changed

+33
-23
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ channelVCC=3
101101
```
102102

103103
Radio decoder and NFC-A, NFC-B, NFC-F, NFC-V status, controlled from the toolbar option **Radio Acquire**, **Radio Decoder** under **Features** and **Protocol** menu.
104-
Currently, channel signal mappings **channelIO**, **channelCLK**, **channelRST**, **channelVCC** are fixed, change this values has no effect.
105104

106105
```
107106
[decoder.radio]

src/nfc-lib/lib-lab/lab-logic/src/main/cpp/tech/Iso7816.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ struct Iso7816::Impl : IsoTech
404404
{
405405
case FullCharacter:
406406
{
407+
log->trace("\tbyte [{}]: {02x}", {frameStatus.frameSize, characterStatus.data});
408+
407409
// check TS byte to detect convention
408410
switch (characterStatus.data)
409411
{
@@ -433,7 +435,7 @@ struct Iso7816::Impl : IsoTech
433435
frameStatus.frameFlags = 0;
434436
frameStatus.frameSize = 0;
435437
frameStatus.frameData[frameStatus.frameSize++] = characterStatus.data;
436-
frameStatus.symbolRate = 1.0 / protocolStatus.elementaryTimeUnit;
438+
frameStatus.symbolRate = 1.0f / protocolStatus.elementaryTimeUnit;
437439

438440
// clear status for next character
439441
characterStatus = {};
@@ -456,6 +458,8 @@ struct Iso7816::Impl : IsoTech
456458
{
457459
case FullCharacter:
458460
{
461+
log->trace("\tbyte [{}]: {02x} {}->{}", {frameStatus.frameSize, characterStatus.data, characterStatus.start, characterStatus.end});
462+
459463
// update frame status and add character to frame data
460464
frameStatus.frameEnd = characterStatus.end;
461465
frameStatus.frameFlags |= characterStatus.flags;
@@ -661,7 +665,7 @@ struct Iso7816::Impl : IsoTech
661665
if (!frameStatus.frameStart)
662666
frameStatus.frameStart = characterStatus.start;
663667

664-
log->trace("\tbyte [{}]: {02x}", {frameStatus.frameSize, characterStatus.data});
668+
log->trace("\tbyte [{}]: {02x} {}->{}", {frameStatus.frameSize, characterStatus.data, characterStatus.start, characterStatus.end});
665669

666670
// update frame and add character to frame data
667671
frameStatus.frameEnd = characterStatus.end;
@@ -709,7 +713,7 @@ struct Iso7816::Impl : IsoTech
709713
if (!frameStatus.frameStart)
710714
frameStatus.frameStart = characterStatus.start;
711715

712-
log->trace("\tbyte [{}]: {02x}", {frameStatus.frameSize, characterStatus.data});
716+
log->trace("\tbyte [{}]: {02x} {}->{}", {frameStatus.frameSize, characterStatus.data, characterStatus.start, characterStatus.end});
713717

714718
// update frame and add character to frame data
715719
frameStatus.frameEnd = characterStatus.end;
@@ -965,7 +969,7 @@ struct Iso7816::Impl : IsoTech
965969

966970
bool updateParameters = false;
967971

968-
int i = 1, n = 2, k = 1, p = 0;
972+
int i = 1, n = 2, k = 1, c = 0;
969973

970974
do
971975
{
@@ -1065,8 +1069,8 @@ struct Iso7816::Impl : IsoTech
10651069
// check presence of TDk
10661070
if (frame[i] & ATR_TD_MASK)
10671071
{
1068-
// next protocol parameters
1069-
p = frame[i] & 0x0f;
1072+
// check presence of TCK (then T!=0 on some of TDk bytes)
1073+
c |= frame[i] & 0x0f;
10701074

10711075
// next structural byte
10721076
i = n++;
@@ -1081,6 +1085,10 @@ struct Iso7816::Impl : IsoTech
10811085

10821086
log->info("\thistorical bytes {}", {hb});
10831087

1088+
// check presence of TCK
1089+
if (c)
1090+
frame.setFrameFlags(!checkLrc(frame) ? CrcError : 0);
1091+
10841092
// update protocol parameters
10851093
if (updateParameters)
10861094
updateProtocol(protocolStatus.elementaryTime, protocolStatus.frequencyFactorIndex, protocolStatus.baudRateFactorIndex);
@@ -1183,7 +1191,7 @@ struct Iso7816::Impl : IsoTech
11831191
if (frame.frameType() != IsoRequestFrame && frame.frameType() != IsoResponseFrame)
11841192
return false;
11851193

1186-
// check if frame is an I-Block, bit 8 must be and length must be at least prologue + epilogue bytes
1194+
// check if frame is an I-Block, bit 8 must be clear
11871195
if (frame[1] & 0x80)
11881196
return false;
11891197

@@ -1206,7 +1214,7 @@ struct Iso7816::Impl : IsoTech
12061214
if (frame.frameType() != IsoRequestFrame && frame.frameType() != IsoResponseFrame)
12071215
return false;
12081216

1209-
// check if frame is an I-Block, bit 8 must be and length must be at least 4 bytes
1217+
// check if frame is an R-Block, bit 8,7 must be 1,0
12101218
if ((frame[1] & 0xC0) != 0x80)
12111219
return false;
12121220

@@ -1225,7 +1233,7 @@ struct Iso7816::Impl : IsoTech
12251233
if (frame.frameType() != IsoRequestFrame && frame.frameType() != IsoResponseFrame)
12261234
return false;
12271235

1228-
// check if frame is an I-Block, bit 8 must be and length must be at least 4 bytes
1236+
// check if frame is an S-Block, bit 8,7 must be 1,1
12291237
if ((frame[1] & 0xC0) != 0xC0)
12301238
return false;
12311239

@@ -1350,30 +1358,33 @@ struct Iso7816::Impl : IsoTech
13501358
if (size > ATR_MAX_LEN)
13511359
return ResultFailed;
13521360

1353-
int i = 1, n = 1;
1361+
int i = 1, n = 1, c = 0;
13541362
int hb = atr[n++] & 0x0f;
1355-
int ck = 0;
13561363

13571364
do
13581365
{
13591366
if (atr[i] & ATR_TA_MASK) n++; // skip TAi
13601367
if (atr[i] & ATR_TB_MASK) n++; // skip TBi
13611368
if (atr[i] & ATR_TC_MASK) n++; // skip TCi
1362-
if (atr[i] & ATR_TD_MASK) i = n++; // check next TDi
13631369

1370+
// check presence of TDk, and protocol indicator != 0 to trigger TCK check
1371+
if (atr[i] & ATR_TD_MASK)
1372+
{
1373+
// get protocol indicator
1374+
c |= atr[i] & 0x0f;
1375+
1376+
// next structural byte
1377+
i = n++;
1378+
}
13641379
}
13651380
while ((i == n - 1) && n < size);
13661381

1367-
// check frame size with historical bytes
1368-
if (size < n + hb + 1)
1382+
// check frame size with historical bytes and presence of TCK
1383+
if (size < n + hb + (c ? 1 : 0))
13691384
return ResultInvalid;
13701385

1371-
// finally check LCR parity
1372-
for (int j = 1; j < size; j++)
1373-
ck ^= atr[j];
1374-
1375-
// check parity
1376-
return !ck ? ResultSuccess : ResultFailed;
1386+
// ATR completed
1387+
return ResultSuccess;
13771388
}
13781389

13791390
/*

src/nfc-lib/lib-lab/lab-tasks/src/main/cpp/tasks/LogicDecoderTask.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ struct LogicDecoderTask::Impl : LogicDecoderTask, AbstractTask
284284
{
285285
int frames = 0;
286286

287-
log->debug("decode new buffer {} offset {} with {} samples", {buffer->id(), buffer->offset(), buffer->elements()});
287+
log->trace("decode new buffer {} offset {} with {} samples", {buffer->id(), buffer->offset(), buffer->elements()});
288288

289289
for (const auto &frame: decoder->nextFrames(buffer.value()))
290290
{

src/nfc-lib/lib-lab/lab-tasks/src/main/cpp/tasks/RadioDecoderTask.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ struct RadioDecoderTask::Impl : RadioDecoderTask, AbstractTask
371371
{
372372
int frames = 0;
373373

374-
log->debug("decode new buffer {} offset {} with {} samples", {buffer->id(), buffer->offset(), buffer->elements()});
374+
log->trace("decode new buffer {} offset {} with {} samples", {buffer->id(), buffer->offset(), buffer->elements()});
375375

376376
for (const auto &frame: decoder->nextFrames(buffer.value()))
377377
{

0 commit comments

Comments
 (0)