pcsc-lite  1.8.10
atrhandler.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
3  *
4  * Copyright (C) 1999-2002
5  * David Corcoran <corcoran@linuxnet.com>
6  * Copyright (C) 2002-2011
7  * Ludovic Rousseau <ludovic.rousseau@free.fr>
8  *
9  * $Id: atrhandler.c 6701 2013-07-30 13:10:21Z rousseau $
10  */
11 
22 #include "config.h"
23 #include <string.h>
24 
25 #include "misc.h"
26 #include "pcsclite.h"
27 #include "debuglog.h"
28 #include "atrhandler.h"
29 
30 /*
31  * Uncomment the following for ATR debugging
32  * or use ./configure --enable-debugatr
33  */
34 /* #define ATR_DEBUG */
35 
45 short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
46  PUCHAR pucAtr, DWORD dwLength)
47 {
48  USHORT p;
49  UCHAR Y1i, T; /* MSN/LSN of TDi */
50  int i = 1; /* value of the index in TAi, TBi, etc. */
51 
52 #ifdef ATR_DEBUG
53  if (dwLength > 0)
54  LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
55 #endif
56 
57  if (dwLength < 2)
58  return 0;
60  /*
61  * Zero out the bitmasks
62  */
63  *availableProtocols = SCARD_PROTOCOL_UNDEFINED;
64  *currentProtocol = SCARD_PROTOCOL_UNDEFINED;
65 
66  /*
67  * Decode the TS byte
68  */
69  if ((pucAtr[0] != 0x3F) && (pucAtr[0] != 0x3B))
70  return 0;
72  /*
73  * Here comes the platform dependant stuff
74  */
75 
76  /*
77  * Decode the T0 byte
78  */
79  Y1i = pucAtr[1] >> 4; /* Get the MSN in Y1 */
80 
81  p = 2;
82 
83  /*
84  * Examine Y1
85  */
86  do
87  {
88  short TAi, TBi, TCi, TDi; /* Interface characters */
89 
90  TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
91  TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
92  TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
93  TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
94 
95  /* We don't use TBi and TCi but we must calculate them because
96  * of the p++ in the formulae */
97  (void)TBi;
98  (void)TCi;
99 
100 #ifdef ATR_DEBUG
101  Log9(PCSC_LOG_DEBUG,
102  "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
103  i, TAi, i, TBi, i, TCi, i, TDi);
104 #endif
105 
106  /*
107  * Examine TDi to determine protocol and more
108  */
109  if (TDi >= 0)
110  {
111  Y1i = TDi >> 4; /* Get the MSN in Y1 */
112  T = TDi & 0x0F; /* Get the LSN in K */
113 
114  /*
115  * Set the current protocol TD1 (first TD only)
116  */
117  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
118  {
119  switch (T)
120  {
121  case 0:
122  *currentProtocol = SCARD_PROTOCOL_T0;
123  break;
124  case 1:
125  *currentProtocol = SCARD_PROTOCOL_T1;
126  break;
127  default:
128  return 0;
129  }
130  }
131 
132 #ifdef ATR_DEBUG
133  Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
134 #endif
135  if (0 == T)
136  {
137  *availableProtocols |= SCARD_PROTOCOL_T0;
138  }
139  else
140  if (1 == T)
141  {
142  *availableProtocols |= SCARD_PROTOCOL_T1;
143  }
144  else
145  if (15 == T)
146  {
147  *availableProtocols |= SCARD_PROTOCOL_T15;
148  }
149  else
150  {
151  /*
152  * Do nothing for now since other protocols are not
153  * supported at this time
154  */
155  }
156  }
157  else
158  Y1i = 0;
159 
160  /* test presence of TA2 */
161  if ((2 == i) && (TAi >= 0))
162  {
163  T = TAi & 0x0F;
164 #ifdef ATR_DEBUG
165  Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
166 #endif
167  switch (T)
168  {
169  case 0:
170  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T0;
171  break;
172 
173  case 1:
174  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T1;
175  break;
176 
177  default:
178  return 0;
179  }
180  }
181 
182  if (p > MAX_ATR_SIZE)
183  return 0;
185  /* next interface characters index */
186  i++;
187  }
188  while (Y1i != 0);
189 
190  /*
191  * If TDx is not set then the current must be T0
192  */
193  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
194  {
195  *currentProtocol = SCARD_PROTOCOL_T0;
196  *availableProtocols |= SCARD_PROTOCOL_T0;
197  }
198 
199 #ifdef ATR_DEBUG
200  Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
201  *currentProtocol, *availableProtocols);
202 #endif
203 
204  return 1;
205 }
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition: pcsclite.h:153
#define SCARD_PROTOCOL_T15
T=15 protocol.
Definition: pcsclite.h:155
This keeps track of smart card protocols, timing issues and Answer to Reset ATR handling.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition: pcsclite.h:152
short ATRDecodeAtr(int *availableProtocols, int *currentProtocol, PUCHAR pucAtr, DWORD dwLength)
parse an ATR
Definition: atrhandler.c:45
This keeps a list of defines for pcsc-lite.
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
Definition: pcsclite.h:150
#define MAX_ATR_SIZE
Maximum ATR size.
Definition: pcsclite.h:38
This handles debugging.