Codebase list libfreefare / 2c9275a
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
13 changed file(s) with 70 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
99 str_nfc_baud_rate()
1010 - New nfc_device_get_information_about() function to retreive some device's
1111 information
12 - No more in/out function parameter: nfc_initiator_transceive_bytes() now
13 take a constant size for Rx buffer
1214
1315 New in 1.6.0-rc1:
1416
103103 printf ("Sent bits: ");
104104 print_hex (pbtTx, szTx);
105105 }
106 int res;
106107 // 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)
108109 return false;
109110
110111 // Show received answer
111112 if (!quiet_output) {
112113 printf ("Received bits: ");
113 print_hex (abtRx, szRx);
114 print_hex (abtRx, res);
114115 }
115116 // Succesful transfer
116117 return true;
6363 {
6464 nfc_target nt;
6565 uint8_t abtRx[MAX_FRAME_LEN];
66 size_t szRx = sizeof(abtRx);
6766 uint8_t abtTx[] = "Hello World!";
6867
6968 if (argc > 1) {
9493 print_nfc_target (nt, false);
9594
9695 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) {
9898 nfc_perror(pnd, "nfc_initiator_transceive_bytes");
9999 goto error;
100100 }
101101
102 abtRx[szRx] = 0;
102 abtRx[res] = 0;
103103 printf ("Received: %s\n", abtRx);
104104
105105 if (nfc_initiator_deselect_target (pnd) < 0) {
5757
5858 static uint8_t abtRx[MAX_FRAME_LEN];
5959 static int szRxBits;
60 static size_t szRx = sizeof(abtRx);
6160 static uint8_t abtRawUid[12];
6261 static uint8_t abtAtqa[2];
6362 static uint8_t abtSak;
116115 printf ("Sent bits: ");
117116 print_hex (pbtTx, szTx);
118117 }
118 int res;
119119 // 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)
121121 return false;
122122
123123 // Show received answer
124124 if (!quiet_output) {
125125 printf ("Received bits: ");
126 print_hex (abtRx, szRx);
126 print_hex (abtRx, res);
127127 }
128128 // Succesful transfer
129129 return true;
8181 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);
8282 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);
8383 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);
8585 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);
8686 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);
8787 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);
10021002 int timeout)
10031003 {
10041004 uint8_t abtTargetsData[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
1005 size_t szTargetsData = sizeof(abtTargetsData);
1005 size_t szTargetsData;
10061006 int res = 0;
10071007
10081008 if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) {
10261026 // Some work to do before getting the UID...
10271027 uint8_t abtInitiate[]="\x06\x00";
10281028 size_t szInitiateLen = 2;
1029 uint8_t abtSelect[]="\x0e\x00";
1030 size_t szSelectLen = 2;
1029 uint8_t abtSelect[] = { 0x0e, 0x00 };
10311030 uint8_t abtRx[1];
1032 size_t szRxLen = 1;
10331031 // 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) {
10351033 return res;
10361034 }
10371035 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) {
10391037 return res;
10401038 }
1039 szTargetsData = (size_t)res;
10411040 }
10421041 else if (nm.nmt == NMT_ISO14443B2CT) {
10431042 // Some work to do before getting the UID...
1044 uint8_t abtReqt[]="\x10";
1045 size_t szReqtLen = 1;
1043 const uint8_t abtReqt[]= { 0x10 };
10461044 // 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) {
10481046 return res;
10491047 }
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) {
10521051 return res;
10531052 }
10541053 if (nm.nmt == NMT_ISO14443B2CT) {
10551054 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)) {
10601058 return res;
10611059 }
10621060 szTargetsData = 6; // u16 UID_LSB, u8 prod code, u8 fab code, u16 UID_MSB
10711069 if (nm.nmt == NMT_ISO14443BI) {
10721070 // Select tag
10731071 uint8_t abtAttrib[6];
1074 size_t szAttribLen = sizeof(abtAttrib);
1075 memcpy(abtAttrib, abtTargetsData, szAttribLen);
1072 memcpy(abtAttrib, abtTargetsData, sizeof(abtAttrib));
10761073 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) {
10781075 return res;
10791076 }
1077 szTargetsData = (size_t)res;
10801078 }
10811079 return abtTargetsData[0];
10821080 } // else:
12831281
12841282 int
12851283 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)
12871285 {
12881286 size_t szExtraTxLen;
12891287 uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
13161314 // Send the frame to the PN53X chip and get the answer
13171315 // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
13181316 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) {
13221318 pnd->last_error = res;
13231319 return pnd->last_error;
13241320 }
1325 szRx = (size_t) res;
1321 const size_t szRxLen = (size_t)res - 1;
13261322 if (pbtRx != NULL) {
1327 // Save the received byte count
1328 *pszRx = szRx - 1;
1329
1323 if (szRxLen > szRx) {
1324 return NFC_EOVFLOW;
1325 }
13301326 // Copy the received bytes
1331 memcpy (pbtRx, abtRx + 1, *pszRx);
1327 memcpy (pbtRx, abtRx + 1, szRxLen);
13321328 }
13331329 // Everything went successful, we return received bytes count
1334 return (szRx - 1);
1330 return szRxLen;
13351331 }
13361332
13371333 static void __pn53x_init_timer(struct nfc_device *pnd, const uint32_t max_cycles)
327327 int pn53x_initiator_transceive_bits (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits,
328328 const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar);
329329 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);
331331 int pn53x_initiator_transceive_bits_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits,
332332 const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar, uint32_t *cycles);
333333 int pn53x_initiator_transceive_bytes_timed (struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx,
144144 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);
145145 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);
146146 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);
148148 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);
149149 int (*initiator_transceive_bytes_timed) (struct nfc_device *pnd, const uint8_t * pbtTx, const size_t szTx, uint8_t * pbtRx, uint32_t * cycles);
150150 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);
596596 * @param pbtTx contains a byte array of the frame that needs to be transmitted.
597597 * @param szTx contains the length in bytes.
598598 * @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)
600600 * @param timeout in milliseconds
601601 *
602602 * The NFC device (configured as initiator) will transmit the supplied bytes (\a pbtTx) to the target.
616616 */
617617 int
618618 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)
622622 }
623623
624624 /** @ingroup initiator
5353 nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
5454 {
5555 uint8_t abtRx[265];
56 size_t szRx = sizeof(abtRx);
5756 size_t szParamLen;
5857 uint8_t abtCmd[265];
5958 //bool bEasyFraming;
104103 }
105104 // Fire the mifare command
106105 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) {
108107 if (res == NFC_ERFTRANS) {
109108 // "Invalid received frame", usual means we are
110109 // authenticated on a sector but the requested MIFARE cmd (read, write)
125124
126125 // When we have executed a read command, copy the received bytes into the param
127126 if (mc == MC_READ) {
128 if (szRx == 16) {
127 if (res == 16) {
129128 memcpy (pmp->mpd.abtData, abtRx, 16);
130129 } else {
131130 return false;
8282
8383 static uint8_t abtRx[MAX_FRAME_LEN];
8484 static int szRxBits;
85 static size_t szRx = sizeof(abtRx);
8685
8786 uint8_t abtHalt[4] = { 0x50, 0x00, 0x00, 0x00 };
8887
115114 printf ("Sent bits: ");
116115 print_hex (pbtTx, szTx);
117116 // 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)
119119 return false;
120120
121121 // Show received answer
122122 printf ("Received bits: ");
123 print_hex (abtRx, szRx);
123 print_hex (abtRx, res);
124124 // Succesful transfer
125125 return true;
126126 }
110110 size_t frame_len = sizeof(frame);
111111 build_felica_frame (nt.nti.nfi, CHECK, payload, payload_len, frame, &frame_len);
112112
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) {
121120 // Not enough data
122121 return -1;
123122 }
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) {
126125 // Error while receiving felica frame
127126 return -1;
128127 }
129 if ((CHECK + 1) != res[1]) {
128 if ((CHECK + 1) != rx[1]) {
130129 // Command return does not match
131130 return -1;
132131 }
133 if (0 != memcmp (&res[2], nt.nti.nfi.abtId, 8)) {
132 if (0 != memcmp (&rx[2], nt.nti.nfi.abtId, 8)) {
134133 // NFCID2 does not match
135134 return -1;
136135 }
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];
139138 if ((status_flag1) || (status_flag2)) {
140139 // Felica card's error
141140 fprintf (stderr, "Status bytes: %02x, %02x\n", status_flag1, status_flag2);
142141 return -1;
143142 }
144143 // 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);
147146 return *data_len;
148147 }
149148
364364 }
365365
366366 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) {
370369 ERR ("%s", "Initialization of NFC emulator failed");
371370 if (!target_only_mode) {
372371 nfc_close (pndInitiator);
377376 }
378377 printf ("%s\n", "Done, relaying frames now!");
379378 }
380
381379
382380 while (!quitting) {
383381 bool ret;
418416
419417 if (!target_only_mode) {
420418 // 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 }
423425 } else {
424426 if (scan_hex_fd3(abtRapdu, &szRapduLen, "R-APDU") != EXIT_SUCCESS) {
425427 fprintf (stderr, "Error while scanning R-APDU from FD3\n");