nfc_initiator_transceive_bytes() now take a constant size for Rx buffer to have a cleaner API: no more in/out parameters
Romuald Conty
11 years ago
9 | 9 | str_nfc_baud_rate() |
10 | 10 | - New nfc_device_get_information_about() function to retreive some device's |
11 | 11 | information |
12 | - No more in/out function parameter: nfc_initiator_transceive_bytes() now | |
13 | take a constant size for Rx buffer | |
12 | 14 | |
13 | 15 | New in 1.6.0-rc1: |
14 | 16 |
103 | 103 | printf ("Sent bits: "); |
104 | 104 | print_hex (pbtTx, szTx); |
105 | 105 | } |
106 | int res; | |
106 | 107 | // Transmit the command bytes |
107 | if (nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, 0) < 0) | |
108 | if ((res = nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0) | |
108 | 109 | return false; |
109 | 110 | |
110 | 111 | // Show received answer |
111 | 112 | if (!quiet_output) { |
112 | 113 | printf ("Received bits: "); |
113 | print_hex (abtRx, szRx); | |
114 | print_hex (abtRx, res); | |
114 | 115 | } |
115 | 116 | // Succesful transfer |
116 | 117 | return true; |
63 | 63 | { |
64 | 64 | nfc_target nt; |
65 | 65 | uint8_t abtRx[MAX_FRAME_LEN]; |
66 | size_t szRx = sizeof(abtRx); | |
67 | 66 | uint8_t abtTx[] = "Hello World!"; |
68 | 67 | |
69 | 68 | if (argc > 1) { |
94 | 93 | print_nfc_target (nt, false); |
95 | 94 | |
96 | 95 | printf ("Sending: %s\n", abtTx); |
97 | if (nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, &szRx, 0) < 0) { | |
96 | int res; | |
97 | if ((res = nfc_initiator_transceive_bytes (pnd, abtTx, sizeof(abtTx), abtRx, sizeof(abtRx), 0)) < 0) { | |
98 | 98 | nfc_perror(pnd, "nfc_initiator_transceive_bytes"); |
99 | 99 | goto error; |
100 | 100 | } |
101 | 101 | |
102 | abtRx[szRx] = 0; | |
102 | abtRx[res] = 0; | |
103 | 103 | printf ("Received: %s\n", abtRx); |
104 | 104 | |
105 | 105 | if (nfc_initiator_deselect_target (pnd) < 0) { |
57 | 57 | |
58 | 58 | static uint8_t abtRx[MAX_FRAME_LEN]; |
59 | 59 | static int szRxBits; |
60 | static size_t szRx = sizeof(abtRx); | |
61 | 60 | static uint8_t abtRawUid[12]; |
62 | 61 | static uint8_t abtAtqa[2]; |
63 | 62 | static uint8_t abtSak; |
116 | 115 | printf ("Sent bits: "); |
117 | 116 | print_hex (pbtTx, szTx); |
118 | 117 | } |
118 | int res; | |
119 | 119 | // Transmit the command bytes |
120 | if (nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, 0) < 0) | |
120 | if ((res = nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0) | |
121 | 121 | return false; |
122 | 122 | |
123 | 123 | // Show received answer |
124 | 124 | if (!quiet_output) { |
125 | 125 | printf ("Received bits: "); |
126 | print_hex (abtRx, szRx); | |
126 | print_hex (abtRx, res); | |
127 | 127 | } |
128 | 128 | // Succesful transfer |
129 | 129 | return true; |
81 | 81 | NFC_EXPORT int nfc_initiator_select_dep_target (nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout); |
82 | 82 | NFC_EXPORT int nfc_initiator_poll_dep_target (nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout); |
83 | 83 | NFC_EXPORT int nfc_initiator_deselect_target (nfc_device *pnd); |
84 | NFC_EXPORT int nfc_initiator_transceive_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, size_t *pszRx, int timeout); | |
84 | NFC_EXPORT int nfc_initiator_transceive_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, int timeout); | |
85 | 85 | NFC_EXPORT int nfc_initiator_transceive_bits (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar); |
86 | 86 | NFC_EXPORT int nfc_initiator_transceive_bytes_timed (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, uint32_t *cycles); |
87 | 87 | NFC_EXPORT int nfc_initiator_transceive_bits_timed (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles); |
1002 | 1002 | int timeout) |
1003 | 1003 | { |
1004 | 1004 | uint8_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; |
1005 | size_t szTargetsData = sizeof(abtTargetsData); | |
1005 | size_t szTargetsData; | |
1006 | 1006 | int res = 0; |
1007 | 1007 | |
1008 | 1008 | if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) { |
1026 | 1026 | // Some work to do before getting the UID... |
1027 | 1027 | uint8_t abtInitiate[]="\x06\x00"; |
1028 | 1028 | size_t szInitiateLen = 2; |
1029 | uint8_t abtSelect[]="\x0e\x00"; | |
1030 | size_t szSelectLen = 2; | |
1029 | uint8_t abtSelect[] = { 0x0e, 0x00 }; | |
1031 | 1030 | uint8_t abtRx[1]; |
1032 | size_t szRxLen = 1; | |
1033 | 1031 | // Getting random Chip_ID |
1034 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, &szRxLen, timeout)) < 0) { | |
1032 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtInitiate, szInitiateLen, abtRx, sizeof(abtRx), timeout)) < 0) { | |
1035 | 1033 | return res; |
1036 | 1034 | } |
1037 | 1035 | abtSelect[1] = abtRx[0]; |
1038 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtSelect, szSelectLen, abtRx, &szRxLen, timeout)) < 0) { | |
1036 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtSelect, sizeof(abtSelect), abtRx, sizeof(abtRx), timeout)) < 0) { | |
1039 | 1037 | return res; |
1040 | 1038 | } |
1039 | szTargetsData = (size_t)res; | |
1041 | 1040 | } |
1042 | 1041 | else if (nm.nmt == NMT_ISO14443B2CT) { |
1043 | 1042 | // Some work to do before getting the UID... |
1044 | uint8_t abtReqt[]="\x10"; | |
1045 | size_t szReqtLen = 1; | |
1043 | const uint8_t abtReqt[]= { 0x10 }; | |
1046 | 1044 | // Getting product code / fab code & store it in output buffer after the serial nr we'll obtain later |
1047 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtReqt, szReqtLen, abtTargetsData+2, &szTargetsData, timeout)) < 0) { | |
1045 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtReqt, sizeof(abtReqt), abtTargetsData+2, sizeof(abtTargetsData)-2, timeout)) < 0) { | |
1048 | 1046 | return res; |
1049 | 1047 | } |
1050 | } | |
1051 | if ((res = pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) < 0) { | |
1048 | szTargetsData = (size_t)res; | |
1049 | } | |
1050 | if ((res = pn53x_initiator_transceive_bytes (pnd, pbtInitData, szInitData, abtTargetsData, sizeof(abtTargetsData), timeout)) < 0) { | |
1052 | 1051 | return res; |
1053 | 1052 | } |
1054 | 1053 | if (nm.nmt == NMT_ISO14443B2CT) { |
1055 | 1054 | if (szTargetsData != 2) |
1056 | return NFC_ECHIP; | |
1057 | uint8_t abtRead[]="\xC4"; // Reading UID_MSB (Read address 4) | |
1058 | size_t szReadLen = 1; | |
1059 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtRead, szReadLen, abtTargetsData+4, &szTargetsData, timeout) < 0)) { | |
1055 | return NFC_ECHIP; // FIXME: It should not return a NFC_ECHIP here! | |
1056 | uint8_t abtRead[]= { 0xC4 }; // Reading UID_MSB (Read address 4) | |
1057 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtRead, sizeof(abtRead), abtTargetsData+4, sizeof(abtTargetsData)-4, timeout) < 0)) { | |
1060 | 1058 | return res; |
1061 | 1059 | } |
1062 | 1060 | szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB |
1071 | 1069 | if (nm.nmt == NMT_ISO14443BI) { |
1072 | 1070 | // Select tag |
1073 | 1071 | uint8_t abtAttrib[6]; |
1074 | size_t szAttribLen = sizeof(abtAttrib); | |
1075 | memcpy(abtAttrib, abtTargetsData, szAttribLen); | |
1072 | memcpy(abtAttrib, abtTargetsData, sizeof(abtAttrib)); | |
1076 | 1073 | abtAttrib[1] = 0x0f; // ATTRIB |
1077 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtAttrib, szAttribLen, NULL, NULL, timeout)) < 0) { | |
1074 | if ((res = pn53x_initiator_transceive_bytes (pnd, abtAttrib, sizeof(abtAttrib), NULL, 0, timeout)) < 0) { | |
1078 | 1075 | return res; |
1079 | 1076 | } |
1077 | szTargetsData = (size_t)res; | |
1080 | 1078 | } |
1081 | 1079 | return abtTargetsData[0]; |
1082 | 1080 | } // else: |
1283 | 1281 | |
1284 | 1282 | int |
1285 | 1283 | pn53x_initiator_transceive_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, |
1286 | size_t *pszRx, int timeout) | |
1284 | const size_t szRx, int timeout) | |
1287 | 1285 | { |
1288 | 1286 | size_t szExtraTxLen; |
1289 | 1287 | uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; |
1316 | 1314 | // Send the frame to the PN53X chip and get the answer |
1317 | 1315 | // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42) |
1318 | 1316 | uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; |
1319 | size_t szRx = sizeof(abtRx); | |
1320 | ||
1321 | if ((res = pn53x_transceive (pnd, abtCmd, szTx + szExtraTxLen, abtRx, szRx, timeout)) < 0) { | |
1317 | if ((res = pn53x_transceive (pnd, abtCmd, szTx + szExtraTxLen, abtRx, sizeof(abtRx), timeout)) < 0) { | |
1322 | 1318 | pnd->last_error = res; |
1323 | 1319 | return pnd->last_error; |
1324 | 1320 | } |
1325 | szRx = (size_t) res; | |
1321 | const size_t szRxLen = (size_t)res - 1; | |
1326 | 1322 | if (pbtRx != NULL) { |
1327 | // Save the received byte count | |
1328 | *pszRx = szRx - 1; | |
1329 | ||
1323 | if (szRxLen > szRx) { | |
1324 | return NFC_EOVFLOW; | |
1325 | } | |
1330 | 1326 | // Copy the received bytes |
1331 | memcpy (pbtRx, abtRx + 1, *pszRx); | |
1327 | memcpy (pbtRx, abtRx + 1, szRxLen); | |
1332 | 1328 | } |
1333 | 1329 | // Everything went successful, we return received bytes count |
1334 | return (szRx - 1); | |
1330 | return szRxLen; | |
1335 | 1331 | } |
1336 | 1332 | |
1337 | 1333 | static void __pn53x_init_timer(struct nfc_device *pnd, const uint32_t max_cycles) |
327 | 327 | int pn53x_initiator_transceive_bits (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, |
328 | 328 | const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar); |
329 | 329 | int pn53x_initiator_transceive_bytes (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, |
330 | uint8_t *pbtRx, size_t *pszRx, int timeout); | |
330 | uint8_t *pbtRx, const size_t szRx, int timeout); | |
331 | 331 | int pn53x_initiator_transceive_bits_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, |
332 | 332 | const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles); |
333 | 333 | int pn53x_initiator_transceive_bytes_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, |
144 | 144 | int (*initiator_poll_target) (struct nfc_device *pnd, const nfc_modulation * pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t btPeriod, nfc_target * pnt); |
145 | 145 | int (*initiator_select_dep_target) (struct nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info * pndiInitiator, nfc_target * pnt, const int timeout); |
146 | 146 | int (*initiator_deselect_target) (struct nfc_device *pnd); |
147 | int (*initiator_transceive_bytes) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, size_t * pszRx, int timeout); | |
147 | int (*initiator_transceive_bytes) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, const size_t szRx, int timeout); | |
148 | 148 | int (*initiator_transceive_bits) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTxBits, const uint8_t * pbtTxPar, uint8_t * pbtRx, uint8_t * pbtRxPar); |
149 | 149 | int (*initiator_transceive_bytes_timed) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, uint32_t * cycles); |
150 | 150 | int (*initiator_transceive_bits_timed) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTxBits, const uint8_t * pbtTxPar, uint8_t * pbtRx, uint8_t * pbtRxPar, uint32_t * cycles); |
596 | 596 | * @param pbtTx contains a byte array of the frame that needs to be transmitted. |
597 | 597 | * @param szTx contains the length in bytes. |
598 | 598 | * @param[out] pbtRx response from the tags |
599 | * @param pszRx size of \a pbtRx | |
599 | * @param szRx size of \a pbtRx (Will return NFC_EOVFLOW if RX exceeds this size) | |
600 | 600 | * @param timeout in milliseconds |
601 | 601 | * |
602 | 602 | * The NFC device (configured as initiator) will transmit the supplied bytes (\a pbtTx) to the target. |
616 | 616 | */ |
617 | 617 | int |
618 | 618 | nfc_initiator_transceive_bytes (nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, |
619 | size_t *pszRx, int timeout) | |
620 | { | |
621 | HAL (initiator_transceive_bytes, pnd, pbtTx, szTx, pbtRx, pszRx, timeout) | |
619 | const size_t szRx, int timeout) | |
620 | { | |
621 | HAL (initiator_transceive_bytes, pnd, pbtTx, szTx, pbtRx, szRx, timeout) | |
622 | 622 | } |
623 | 623 | |
624 | 624 | /** @ingroup initiator |
53 | 53 | nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp) |
54 | 54 | { |
55 | 55 | uint8_t abtRx[265]; |
56 | size_t szRx = sizeof(abtRx); | |
57 | 56 | size_t szParamLen; |
58 | 57 | uint8_t abtCmd[265]; |
59 | 58 | //bool bEasyFraming; |
104 | 103 | } |
105 | 104 | // Fire the mifare command |
106 | 105 | int res; |
107 | if ((res = nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, -1)) < 0) { | |
106 | if ((res = nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1)) < 0) { | |
108 | 107 | if (res == NFC_ERFTRANS) { |
109 | 108 | // "Invalid received frame", usual means we are |
110 | 109 | // authenticated on a sector but the requested MIFARE cmd (read, write) |
125 | 124 | |
126 | 125 | // When we have executed a read command, copy the received bytes into the param |
127 | 126 | if (mc == MC_READ) { |
128 | if (szRx == 16) { | |
127 | if (res == 16) { | |
129 | 128 | memcpy (pmp->mpd.abtData, abtRx, 16); |
130 | 129 | } else { |
131 | 130 | return false; |
82 | 82 | |
83 | 83 | static uint8_t abtRx[MAX_FRAME_LEN]; |
84 | 84 | static int szRxBits; |
85 | static size_t szRx = sizeof(abtRx); | |
86 | 85 | |
87 | 86 | uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 }; |
88 | 87 | |
115 | 114 | printf ("Sent bits: "); |
116 | 115 | print_hex (pbtTx, szTx); |
117 | 116 | // Transmit the command bytes |
118 | if (nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, &szRx, 0) < 0) | |
117 | int res; | |
118 | if ((res = nfc_initiator_transceive_bytes (pnd, pbtTx, szTx, abtRx, sizeof(abtRx), 0)) < 0) | |
119 | 119 | return false; |
120 | 120 | |
121 | 121 | // Show received answer |
122 | 122 | printf ("Received bits: "); |
123 | print_hex (abtRx, szRx); | |
123 | print_hex (abtRx, res); | |
124 | 124 | // Succesful transfer |
125 | 125 | return true; |
126 | 126 | } |
110 | 110 | size_t frame_len = sizeof(frame); |
111 | 111 | build_felica_frame (nt.nti.nfi, CHECK, payload, payload_len, frame, &frame_len); |
112 | 112 | |
113 | uint8_t res[1024]; | |
114 | ||
115 | size_t res_len; | |
116 | if (nfc_initiator_transceive_bytes (dev, frame, frame_len, res, &res_len, 0) < 0) { | |
117 | return -1; | |
118 | } | |
119 | const size_t res_overhead = 1 + 1 + 8 + 2; // 1+1+8+2: LEN + CMD + NFCID2 + STATUS | |
120 | if (res_len < res_overhead) { | |
113 | uint8_t rx[1024]; | |
114 | int res; | |
115 | if ((res = nfc_initiator_transceive_bytes (dev, frame, frame_len, rx, sizeof(rx), 0)) < 0) { | |
116 | return res; | |
117 | } | |
118 | const int res_overhead = 1 + 1 + 8 + 2; // 1+1+8+2: LEN + CMD + NFCID2 + STATUS | |
119 | if (res < res_overhead) { | |
121 | 120 | // Not enough data |
122 | 121 | return -1; |
123 | 122 | } |
124 | uint8_t felica_res_len = res[0]; | |
125 | if (res_len != felica_res_len) { | |
123 | uint8_t felica_res_len = rx[0]; | |
124 | if (res != felica_res_len) { | |
126 | 125 | // Error while receiving felica frame |
127 | 126 | return -1; |
128 | 127 | } |
129 | if ((CHECK + 1) != res[1]) { | |
128 | if ((CHECK + 1) != rx[1]) { | |
130 | 129 | // Command return does not match |
131 | 130 | return -1; |
132 | 131 | } |
133 | if (0 != memcmp (&res[2], nt.nti.nfi.abtId, 8)) { | |
132 | if (0 != memcmp (&rx[2], nt.nti.nfi.abtId, 8)) { | |
134 | 133 | // NFCID2 does not match |
135 | 134 | return -1; |
136 | 135 | } |
137 | const uint8_t status_flag1 = res[10]; | |
138 | const uint8_t status_flag2 = res[11]; | |
136 | const uint8_t status_flag1 = rx[10]; | |
137 | const uint8_t status_flag2 = rx[11]; | |
139 | 138 | if ((status_flag1) || (status_flag2)) { |
140 | 139 | // Felica card's error |
141 | 140 | fprintf (stderr, "Status bytes: %02x, %02x\n", status_flag1, status_flag2); |
142 | 141 | return -1; |
143 | 142 | } |
144 | 143 | // const uint8_t res_block_count = res[12]; |
145 | *data_len = res_len - res_overhead + 1; // +1 => block count is stored on 1 byte | |
146 | memcpy (data, &res[res_overhead+1], *data_len); | |
144 | *data_len = res - res_overhead + 1; // +1 => block count is stored on 1 byte | |
145 | memcpy (data, &rx[res_overhead+1], *data_len); | |
147 | 146 | return *data_len; |
148 | 147 | } |
149 | 148 |
364 | 364 | } |
365 | 365 | |
366 | 366 | printf ("NFC emulator device: %s opened\n", nfc_device_get_name (pndTarget)); |
367 | ||
368 | szCapduLen = sizeof (abtCapdu); | |
369 | if (nfc_target_init (pndTarget, &ntEmulatedTarget, abtCapdu, szCapduLen, 0) < 0) { | |
367 | int res; | |
368 | if ((res = nfc_target_init (pndTarget, &ntEmulatedTarget, abtCapdu, sizeof(abtCapdu), 0)) < 0) { | |
370 | 369 | ERR ("%s", "Initialization of NFC emulator failed"); |
371 | 370 | if (!target_only_mode) { |
372 | 371 | nfc_close (pndInitiator); |
377 | 376 | } |
378 | 377 | printf ("%s\n", "Done, relaying frames now!"); |
379 | 378 | } |
380 | ||
381 | 379 | |
382 | 380 | while (!quitting) { |
383 | 381 | bool ret; |
418 | 416 | |
419 | 417 | if (!target_only_mode) { |
420 | 418 | // Forward the frame to the original tag |
421 | ret = (nfc_initiator_transceive_bytes | |
422 | (pndInitiator, abtCapdu, szCapduLen, abtRapdu, &szRapduLen, 0) < 0) ? 0 : 1; | |
419 | if ((res = nfc_initiator_transceive_bytes (pndInitiator, abtCapdu, szCapduLen, abtRapdu, sizeof(abtRapdu), -1) < 0)) { | |
420 | ret = false; | |
421 | } else { | |
422 | szCapduLen = (size_t) res; | |
423 | ret = true; | |
424 | } | |
423 | 425 | } else { |
424 | 426 | if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") != EXIT_SUCCESS) { |
425 | 427 | fprintf (stderr, "Error while scanning R-APDU from FD3\n"); |