205 lines
3.8 KiB
C
205 lines
3.8 KiB
C
|
#include "atr_decoder.h"
|
||
|
#include "debug.h"
|
||
|
|
||
|
enum {
|
||
|
T0 = 0,
|
||
|
T1,
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
TA1,
|
||
|
TA2,
|
||
|
TA15,
|
||
|
TC1,
|
||
|
TC2,
|
||
|
TD1,
|
||
|
// For array declaration
|
||
|
TOTAL,
|
||
|
};
|
||
|
|
||
|
static uint8_t parsed_data[TOTAL];
|
||
|
static uint8_t default_fd = DEFAULT_FD;
|
||
|
static uint32_t parsed_bitmask;
|
||
|
|
||
|
void atr_reset(void)
|
||
|
{
|
||
|
parsed_bitmask = 0;
|
||
|
}
|
||
|
|
||
|
bool atr_decode(SC_ATR *atr)
|
||
|
{
|
||
|
int mask, i;
|
||
|
int currentProtocol;
|
||
|
int index;
|
||
|
uint8_t TA15 = 0x07;
|
||
|
|
||
|
// T0
|
||
|
atr->HLength = atr->T0 & 0x0F;
|
||
|
mask = atr->T0 & 0xF0;
|
||
|
index = 1;
|
||
|
|
||
|
while (mask != 0)
|
||
|
{
|
||
|
int T[4];
|
||
|
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
if ((mask >> (i + 4)) & 0x01)
|
||
|
{
|
||
|
T[i] = (int)atr->T[atr->ILength];
|
||
|
atr->ILength++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
T[i] = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TA
|
||
|
if (T[0] != -1)
|
||
|
{
|
||
|
// TA1 - Fi, Di
|
||
|
if (index == 1)
|
||
|
{
|
||
|
parsed_data[TA1] = T[0] & 0xFF;
|
||
|
parsed_bitmask |= (1 << TA1);
|
||
|
}
|
||
|
else if (index == 2)
|
||
|
{ // TA2 - PPS Mode
|
||
|
parsed_data[TA2] = T[0] & 0xFF;
|
||
|
parsed_bitmask |= (1 << TA2);
|
||
|
}
|
||
|
else if (currentProtocol == 15)
|
||
|
{
|
||
|
parsed_data[TA15] = T[0] & 0xFF;
|
||
|
parsed_bitmask |= (1 << TA15);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TB - deprecated or T = 1, do not support for now
|
||
|
|
||
|
// TC
|
||
|
if (T[2] != -1)
|
||
|
{
|
||
|
//TC1 - Extra guard time
|
||
|
if (index == 1)
|
||
|
{
|
||
|
parsed_data[TC1] = T[2] & 0xFF;
|
||
|
parsed_bitmask |= (1 << TC1);
|
||
|
}
|
||
|
else if (index == 2)
|
||
|
{
|
||
|
parsed_data[TC2] = T[2] & 0xFF;
|
||
|
parsed_bitmask |= (1 << TC2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TD
|
||
|
if (T[3] != -1)
|
||
|
{
|
||
|
// next TD exist
|
||
|
mask = T[3] & 0xF0;
|
||
|
currentProtocol = T[3] & 0x0F;
|
||
|
// TD1
|
||
|
if (index == 1)
|
||
|
{
|
||
|
parsed_data[TD1] = T[3] & 0xFF;
|
||
|
parsed_bitmask |= (1 << TD1);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mask = 0;
|
||
|
}
|
||
|
|
||
|
index++;
|
||
|
}
|
||
|
|
||
|
// TH
|
||
|
atr->Th_Start = atr->ILength;
|
||
|
// TCK exists
|
||
|
if (atr->ILength + atr->HLength + 2 != atr->TotalLength)
|
||
|
{
|
||
|
uint8_t check = atr->T0;
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < atr->TotalLength - 2; i++)
|
||
|
{
|
||
|
check ^= atr->T[i];
|
||
|
}
|
||
|
|
||
|
atr->Check = check;
|
||
|
}
|
||
|
|
||
|
return (bool)atr->Check;
|
||
|
}
|
||
|
|
||
|
uint8_t atr_decoder_get_extra_guard_time(void)
|
||
|
{
|
||
|
if (parsed_bitmask & (1 << TC1))
|
||
|
return parsed_data[TC1];
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
uint8_t atr_decoder_get_waiting_integer(void)
|
||
|
{
|
||
|
uint8_t wi = 10;
|
||
|
if (parsed_bitmask & (1 << TC2))
|
||
|
wi = parsed_data[TC2];
|
||
|
|
||
|
return wi;
|
||
|
}
|
||
|
|
||
|
bool atr_decoder_get_clock_stop(bool *high)
|
||
|
{
|
||
|
bool en = false;
|
||
|
|
||
|
*high = false;
|
||
|
if ((parsed_bitmask & (1 << TA15)) && (parsed_data[TA15] & 0xC0))
|
||
|
{
|
||
|
en = true;
|
||
|
*high = (bool)((parsed_data[TA15] & 0x80) == 0);
|
||
|
}
|
||
|
return en;
|
||
|
}
|
||
|
|
||
|
bool atr_decoder_allow_pps(void)
|
||
|
{
|
||
|
return (bool)((parsed_bitmask & (1 << TA2)) == 0);
|
||
|
}
|
||
|
|
||
|
bool atr_decoder_allow_switch_mode(void)
|
||
|
{
|
||
|
return (bool)((parsed_bitmask & (1 << TA2)) && (!(parsed_data[TA2] & 0x80))); //bypb add:!
|
||
|
}
|
||
|
|
||
|
uint8_t atr_decoder_get_protocol(void)
|
||
|
{
|
||
|
// specific mode
|
||
|
if (parsed_bitmask & (1 << TA2))
|
||
|
{
|
||
|
return parsed_data[TA2] & 0x0F;
|
||
|
}
|
||
|
// first offer
|
||
|
else if (parsed_bitmask & (1 << TD1))
|
||
|
{
|
||
|
return parsed_data[TD1] & 0x0F;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
uint8_t atr_decoder_get_FD(void)
|
||
|
{
|
||
|
if (parsed_bitmask & (1 << TA1))
|
||
|
{
|
||
|
return parsed_data[TA1];
|
||
|
}
|
||
|
return default_fd;
|
||
|
}
|
||
|
|
||
|
void atr_decoder_config_default_FD(uint8_t fd)
|
||
|
{
|
||
|
default_fd = fd;
|
||
|
}
|