pcsc-lite  1.8.8
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 5962 2011-09-24 08:24:34Z 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 #ifdef ATR_DEBUG
96  Log9(PCSC_LOG_DEBUG,
97  "TA%d: %02X, TB%d: %02X, TC%d: %02X, TD%d: %02X",
98  i, TAi, i, TBi, i, TCi, i, TDi);
99 #endif
100 
101  /*
102  * Examine TDi to determine protocol and more
103  */
104  if (TDi >= 0)
105  {
106  Y1i = TDi >> 4; /* Get the MSN in Y1 */
107  T = TDi & 0x0F; /* Get the LSN in K */
108 
109  /*
110  * Set the current protocol TD1 (first TD only)
111  */
112  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
113  {
114  switch (T)
115  {
116  case 0:
117  *currentProtocol = SCARD_PROTOCOL_T0;
118  break;
119  case 1:
120  *currentProtocol = SCARD_PROTOCOL_T1;
121  break;
122  default:
123  return 0;
124  }
125  }
126 
127 #ifdef ATR_DEBUG
128  Log2(PCSC_LOG_DEBUG, "T=%d Protocol Found", T);
129 #endif
130  if (0 == T)
131  {
132  *availableProtocols |= SCARD_PROTOCOL_T0;
133  }
134  else
135  if (1 == T)
136  {
137  *availableProtocols |= SCARD_PROTOCOL_T1;
138  }
139  else
140  if (15 == T)
141  {
142  *availableProtocols |= SCARD_PROTOCOL_T15;
143  }
144  else
145  {
146  /*
147  * Do nothing for now since other protocols are not
148  * supported at this time
149  */
150  }
151  }
152  else
153  Y1i = 0;
154 
155  /* test presence of TA2 */
156  if ((2 == i) && (TAi >= 0))
157  {
158  T = TAi & 0x0F;
159 #ifdef ATR_DEBUG
160  Log2(PCSC_LOG_DEBUG, "Specific mode: T=%d", T);
161 #endif
162  switch (T)
163  {
164  case 0:
165  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T0;
166  break;
167 
168  case 1:
169  *currentProtocol = *availableProtocols = SCARD_PROTOCOL_T1;
170  break;
171 
172  default:
173  return 0;
174  }
175  }
176 
177  if (p > MAX_ATR_SIZE)
178  return 0;
180  /* next interface characters index */
181  i++;
182  }
183  while (Y1i != 0);
184 
185  /*
186  * If TDx is not set then the current must be T0
187  */
188  if (*currentProtocol == SCARD_PROTOCOL_UNDEFINED)
189  {
190  *currentProtocol = SCARD_PROTOCOL_T0;
191  *availableProtocols |= SCARD_PROTOCOL_T0;
192  }
193 
194 #ifdef ATR_DEBUG
195  Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
196  *currentProtocol, *availableProtocols);
197 #endif
198 
199  return 1;
200 }
#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.