27 #endif // HAVE_CONFIG_H
35 #include "../drivers.h"
42 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(3500)
43 #elif defined(__APPLE__)
44 # include <wintypes.h>
45 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
46 #elif defined (__FreeBSD__) || defined (__OpenBSD__)
47 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE (((0x31) << 16) | ((3500) << 2))
48 #elif defined (__linux__)
51 # define IOCTL_CCID_ESCAPE_SCARD_CTL_CODE SCARD_CTL_CODE(1)
53 # error "Can't determine serial string for your system"
59 #define SCARD_OPERATION_SUCCESS 0x61
60 #define SCARD_OPERATION_ERROR 0x63
62 #ifndef SCARD_PROTOCOL_UNDEFINED
63 # define SCARD_PROTOCOL_UNDEFINED SCARD_PROTOCOL_UNSET
66 #define FIRMWARE_TEXT "ACR122U" // Tested on: ACR122U101(ACS), ACR122U102(Tikitag), ACR122U203(ACS)
68 #define ACR122_WRAP_LEN 5
69 #define ACR122_COMMAND_LEN 266
70 #define ACR122_RESPONSE_LEN 268
72 const char *supported_devices[] = {
83 SCARD_IO_REQUEST ioCard;
86 static SCARDCONTEXT _SCardContext;
87 static int _iSCardContextRefCount = 0;
90 acr122_get_scardcontext (
void)
92 if (_iSCardContextRefCount == 0) {
93 if (SCardEstablishContext (SCARD_SCOPE_USER, NULL, NULL, &_SCardContext) != SCARD_S_SUCCESS)
96 _iSCardContextRefCount++;
98 return &_SCardContext;
102 acr122_free_scardcontext (
void)
104 if (_iSCardContextRefCount) {
105 _iSCardContextRefCount--;
106 if (!_iSCardContextRefCount) {
107 SCardReleaseContext (_SCardContext);
114 acr122_pick_device (
void)
118 if ((pndd = malloc (
sizeof (*pndd)))) {
122 DBG (
"%s",
"acr122_list_devices failed");
128 DBG (
"%s",
"No device found");
151 char acDeviceNames[256 + 64 * DRIVERS_MAX_DEVICES];
152 size_t szDeviceNamesLen =
sizeof (acDeviceNames);
153 uint32_t uiBusIndex = 0;
159 memset (acDeviceNames,
'\0', szDeviceNamesLen);
164 if (!(pscc = acr122_get_scardcontext ())) {
165 DBG (
"%s",
"PCSC context not found");
169 if (SCardListReaders (*pscc, NULL, acDeviceNames, (
void *) &szDeviceNamesLen) != SCARD_S_SUCCESS)
174 while ((acDeviceNames[szPos] !=
'\0') && ((*pszDeviceFound) < szDevices)) {
180 for (i = 0; supported_devices[i] && !bSupported; i++) {
181 int l = strlen (supported_devices[i]);
182 bSupported = 0 == strncmp (supported_devices[i], acDeviceNames + szPos, l);
187 strncpy (pnddDevices[*pszDeviceFound].acDevice, acDeviceNames + szPos, DEVICE_NAME_LENGTH - 1);
188 pnddDevices[*pszDeviceFound].
acDevice[DEVICE_NAME_LENGTH - 1] =
'\0';
189 pnddDevices[*pszDeviceFound].
pcDriver = ACR122_DRIVER_NAME;
190 pnddDevices[*pszDeviceFound].
uiBusIndex = uiBusIndex;
193 DBG (
"PCSC device [%s] is not NFC capable or not supported by libnfc.", acDeviceNames + szPos);
197 while (acDeviceNames[szPos++] !=
'\0');
199 acr122_free_scardcontext ();
216 DBG (
"Attempt to connect to %s", pndd->
acDevice);
218 if (!(pscc = acr122_get_scardcontext ()))
221 if (SCardConnect (*pscc, pndd->
acDevice, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &(as.hCard), (
void *) &(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
223 if (SCardConnect (*pscc, pndd->
acDevice, SCARD_SHARE_DIRECT, 0, &(as.hCard), (
void *) &(as.ioCard.dwProtocol)) != SCARD_S_SUCCESS) {
225 DBG (
"%s",
"PCSC connect failed");
230 as.ioCard.cbPciLength =
sizeof (SCARD_IO_REQUEST);
234 if (strstr (pcFirmware, FIRMWARE_TEXT) != NULL) {
236 pas = malloc (
sizeof (acr122_spec_t));
243 strcpy (pnd->
acName + strlen (pnd->
acName), pcFirmware);
245 pnd->
nds = (nfc_device_spec_t) pas;
257 acr122_spec_t *pas = (acr122_spec_t *) pnd->
nds;
258 SCardDisconnect (pas->hCard, SCARD_LEAVE_CARD);
259 acr122_free_scardcontext ();
265 acr122_transceive (
nfc_device_t * pnd,
const byte_t * pbtTx,
const size_t szTx, byte_t * pbtRx,
size_t * pszRx)
267 byte_t abtRxCmd[5] = { 0xFF, 0xC0, 0x00, 0x00 };
268 size_t szRxCmdLen =
sizeof (abtRxCmd);
269 byte_t abtRxBuf[ACR122_RESPONSE_LEN];
271 byte_t abtTxBuf[ACR122_WRAP_LEN + ACR122_COMMAND_LEN] = { 0xFF, 0x00, 0x00, 0x00 };
272 acr122_spec_t *pas = (acr122_spec_t *) pnd->
nds;
276 if (szTx > ACR122_COMMAND_LEN) {
284 memcpy (abtTxBuf + 5, pbtTx, szTx);
285 szRxBufLen =
sizeof (abtRxBuf);
287 PRINT_HEX (
"TX", abtTxBuf, szTx + 5);
290 if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
292 (pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtTxBuf, szTx + 5, abtRxBuf, szRxBufLen,
293 (
void *) &szRxBufLen) != SCARD_S_SUCCESS) {
298 if (SCardTransmit (pas->hCard, &(pas->ioCard), abtTxBuf, szTx + 5, NULL, abtRxBuf, (
void *) &szRxBufLen) !=
305 if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_T0) {
307 if (szRxBufLen != 2) {
312 if (*abtRxBuf == SCARD_OPERATION_ERROR) {
317 abtRxCmd[4] = abtRxBuf[1];
318 szRxBufLen =
sizeof (abtRxBuf);
319 if (SCardTransmit (pas->hCard, &(pas->ioCard), abtRxCmd, szRxCmdLen, NULL, abtRxBuf, (
void *) &szRxBufLen) !=
326 PRINT_HEX (
"RX", abtRxBuf, szRxBufLen);
330 if (pbtRx == NULL || pszRx == NULL)
334 if (szRxBufLen < 4 || (szRxBufLen - 4) > *pszRx) {
339 *pszRx = ((size_t) szRxBufLen) - 4;
340 memcpy (pbtRx, abtRxBuf + 2, *pszRx);
347 acr122_firmware (
const nfc_device_spec_t nds)
349 byte_t abtGetFw[5] = { 0xFF, 0x00, 0x48, 0x00, 0x00 };
352 acr122_spec_t *pas = (acr122_spec_t *) nds;
353 static char abtFw[11];
354 size_t szFwLen =
sizeof (abtFw);
355 memset (abtFw, 0x00, szFwLen);
356 if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
357 uiResult = SCardControl (pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtGetFw, sizeof (abtGetFw), abtFw, szFwLen-1, (
void *) &szFwLen);
359 uiResult = SCardTransmit (pas->hCard, &(pas->ioCard), abtGetFw, sizeof (abtGetFw), NULL, (byte_t *) abtFw, (
void *) &szFwLen);
362 if (uiResult != SCARD_S_SUCCESS) {
363 ERR (
"No ACR122 firmware received, Error: %08x", uiResult);
370 acr122_led_red (
const nfc_device_spec_t nds,
bool bOn)
372 byte_t abtLed[9] = { 0xFF, 0x00, 0x40, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00 };
373 acr122_spec_t *pas = (acr122_spec_t *) nds;
375 size_t szBufLen =
sizeof (abtBuf);
377 if (pas->ioCard.dwProtocol == SCARD_PROTOCOL_UNDEFINED) {
379 (pas->hCard, IOCTL_CCID_ESCAPE_SCARD_CTL_CODE, abtLed, sizeof (abtLed), abtBuf, szBufLen,
380 (
void *) &szBufLen) == SCARD_S_SUCCESS);
382 return (SCardTransmit
383 (pas->hCard, &(pas->ioCard), abtLed,
sizeof (abtLed), NULL, (byte_t *) abtBuf,
384 (
void *) &szBufLen) == SCARD_S_SUCCESS);