Improved code for PN532 driver
This commit is contained in:
parent
942faef582
commit
6204340059
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.stackdump
|
||||
*~
|
||||
Doxyfile
|
||||
INSTALL
|
||||
|
||||
@ -430,3 +430,16 @@ oom:
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
uart_list_free(char ** acPorts)
|
||||
{
|
||||
char *acPort;
|
||||
size_t iDevice = 0;
|
||||
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
free((void *)acPort);
|
||||
}
|
||||
|
||||
free(acPorts);
|
||||
}
|
||||
|
||||
@ -58,5 +58,6 @@ int uart_receive(serial_port sp, uint8_t *pbtRx, const size_t szRx, void *ab
|
||||
int uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout);
|
||||
|
||||
char **uart_list_ports(void);
|
||||
void uart_list_free(char **acPorts);
|
||||
|
||||
#endif // __NFC_BUS_UART_H__
|
||||
|
||||
@ -333,10 +333,7 @@ pn53x_transceive(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx
|
||||
};
|
||||
|
||||
if (res < 0) {
|
||||
pnd->last_error = res;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Chip error: \"%s\" (%02x), returned error: \"%s\" (%d))", pn53x_strerror(pnd), CHIP_DATA(pnd)->last_status_byte, nfc_strerror(pnd), res);
|
||||
} else {
|
||||
pnd->last_error = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -1064,8 +1061,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
if (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) {
|
||||
if (CHIP_DATA(pnd)->type == RCS360) {
|
||||
// TODO add support for RC-S360, at the moment it refuses to send raw frames without a first select
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
// No native support in InListPassiveTarget so we do discovery by hand
|
||||
if ((res = nfc_device_set_property_bool(pnd, NP_FORCE_ISO14443_B, true)) < 0) {
|
||||
@ -1151,8 +1147,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
} else {
|
||||
const pn53x_modulation pm = pn53x_nm_to_pm(nm);
|
||||
if ((PM_UNDEFINED == pm) || (NBR_UNDEFINED == nm.nbr)) {
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
|
||||
if ((res = pn53x_InListPassiveTarget(pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) <= 0)
|
||||
@ -1175,8 +1170,7 @@ pn53x_initiator_select_passive_target_ext(struct nfc_device *pnd,
|
||||
}
|
||||
}
|
||||
if (pn53x_current_target_new(pnd, &nttmp) == NULL) {
|
||||
pnd->last_error = NFC_ESOFT;
|
||||
return pnd->last_error;
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
// Is a tag info struct available
|
||||
if (pnt) {
|
||||
@ -1209,8 +1203,7 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
|
||||
for (size_t n = 0; n < szModulations; n++) {
|
||||
const pn53x_target_type ptt = pn53x_nm_to_ptt(pnmModulations[n]);
|
||||
if (PTT_UNDEFINED == ptt) {
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
apttTargetTypes[szTargetTypes] = ptt;
|
||||
if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS
|
||||
@ -1227,18 +1220,18 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
|
||||
return res;
|
||||
switch (res) {
|
||||
case 0:
|
||||
return pnd->last_error = NFC_SUCCESS;
|
||||
return NFC_SUCCESS;
|
||||
break;
|
||||
case 1:
|
||||
*pnt = ntTargets[0];
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
return pnd->last_error = NFC_ESOFT;
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
return res;
|
||||
case 2:
|
||||
*pnt = ntTargets[1]; // We keep the selected one
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
return pnd->last_error = NFC_ESOFT;
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
return res;
|
||||
default:
|
||||
@ -1259,8 +1252,8 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
|
||||
const int timeout_ms = uiPeriod * 150;
|
||||
|
||||
if ((res = pn53x_initiator_select_passive_target_ext(pnd, pnmModulations[n], pbtInitiatorData, szInitiatorData, pnt, timeout_ms)) < 0) {
|
||||
if (pnd->last_error != NFC_ETIMEOUT) {
|
||||
result = pnd->last_error;
|
||||
if (res != NFC_ETIMEOUT) {
|
||||
result = res;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
@ -1401,8 +1394,7 @@ pn53x_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, c
|
||||
|
||||
// We can not just send bytes without parity if while the PN53X expects we handled them
|
||||
if (!pnd->bPar) {
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
|
||||
// Copy the data into the command frame
|
||||
@ -1419,16 +1411,14 @@ pn53x_initiator_transceive_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, c
|
||||
|
||||
// To transfer command frames bytes we can not have any leading bits, reset this to zero
|
||||
if ((res = pn53x_set_tx_bits(pnd, 0)) < 0) {
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Send the frame to the PN53X chip and get the answer
|
||||
// We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
|
||||
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||
if ((res = pn53x_transceive(pnd, abtCmd, szTx + szExtraTxLen, abtRx, sizeof(abtRx), timeout)) < 0) {
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
return res;
|
||||
}
|
||||
const size_t szRxLen = (size_t)res - 1;
|
||||
if (pbtRx != NULL) {
|
||||
@ -1538,18 +1528,15 @@ pn53x_initiator_transceive_bits_timed(struct nfc_device *pnd, const uint8_t *pbt
|
||||
|
||||
// Sorry, no arbitrary parity bits support for now
|
||||
if (!pnd->bPar) {
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
// Sorry, no easy framing support
|
||||
if (pnd->bEasyFraming) {
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
// TODO CRC support but it probably doesn't make sense for (szTxBits % 8 != 0) ...
|
||||
if (pnd->bCrc) {
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
|
||||
__pn53x_init_timer(pnd, *cycles);
|
||||
@ -1636,14 +1623,12 @@ pn53x_initiator_transceive_bytes_timed(struct nfc_device *pnd, const uint8_t *pb
|
||||
|
||||
// We can not just send bytes without parity while the PN53X expects we handled them
|
||||
if (!pnd->bPar) {
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
// Sorry, no easy framing support
|
||||
// TODO to be changed once we'll provide easy framing support from libnfc itself...
|
||||
if (pnd->bEasyFraming) {
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
|
||||
uint8_t txmode = 0;
|
||||
@ -2046,13 +2031,13 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
// Check if there is a saved target
|
||||
if (CHIP_DATA(pnd)->current_target == NULL) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): no saved target");
|
||||
return pnd->last_error = NFC_EINVARG;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
|
||||
// Check if the argument target nt is equals to current saved target
|
||||
if ((pnt != NULL) && (!pn53x_current_target_is(pnd, pnt))) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): another target");
|
||||
return pnd->last_error = NFC_ETGRELEASED;
|
||||
return NFC_ETGRELEASED;
|
||||
}
|
||||
|
||||
// Ping target
|
||||
@ -2096,7 +2081,7 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
|
||||
}
|
||||
if (ret == NFC_ETGRELEASED)
|
||||
pn53x_current_target_free(pnd);
|
||||
return pnd->last_error = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SAK_ISO14443_4_COMPLIANT 0x20
|
||||
@ -2115,8 +2100,7 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443A:
|
||||
ptm = PTM_PASSIVE_ONLY;
|
||||
if ((pnt->nti.nai.abtUid[0] != 0x08) || (pnt->nti.nai.szUidLen != 4)) {
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
pn53x_set_parameters(pnd, PARAM_AUTO_ATR_RES, false);
|
||||
if (CHIP_DATA(pnd)->type == PN532) { // We have a PN532
|
||||
@ -2144,8 +2128,7 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_JEWEL:
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
|
||||
// Let the PN53X be activated by the RF level detector from power down mode
|
||||
@ -2245,8 +2228,7 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
case NMT_ISO14443B2SR:
|
||||
case NMT_ISO14443B2CT:
|
||||
case NMT_JEWEL:
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
|
||||
bool targetActivated = false;
|
||||
@ -2308,8 +2290,7 @@ pn53x_target_init(struct nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const
|
||||
pnt->nti.ndi.ndm = ndm; // Update DEP mode
|
||||
}
|
||||
if (pn53x_current_target_new(pnd, pnt) == NULL) {
|
||||
pnd->last_error = NFC_ESOFT;
|
||||
return pnd->last_error;
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
|
||||
if (ptm & PTM_ISO14443_4_PICC_ONLY) {
|
||||
@ -2387,8 +2368,7 @@ pn53x_target_receive_bytes(struct nfc_device *pnd, uint8_t *pbtRx, const size_t
|
||||
break;
|
||||
} else {
|
||||
// TODO Support EasyFraming for other cases by software
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
}
|
||||
// NO BREAK
|
||||
@ -2410,7 +2390,7 @@ pn53x_target_receive_bytes(struct nfc_device *pnd, uint8_t *pbtRx, const size_t
|
||||
size_t szRx = sizeof(abtRx);
|
||||
int res = 0;
|
||||
if ((res = pn53x_transceive(pnd, abtCmd, sizeof(abtCmd), abtRx, szRx, timeout)) < 0)
|
||||
return pnd->last_error;
|
||||
return res;
|
||||
szRx = (size_t) res;
|
||||
// Save the received bytes count
|
||||
szRx -= 1;
|
||||
@ -2492,8 +2472,7 @@ pn53x_target_send_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, const size
|
||||
break;
|
||||
} else {
|
||||
// TODO Support EasyFraming for other cases by software
|
||||
pnd->last_error = NFC_ENOTIMPL;
|
||||
return pnd->last_error;
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
}
|
||||
// NO BREAK
|
||||
@ -2642,8 +2621,7 @@ pn532_SAMConfiguration(struct nfc_device *pnd, const pn532_sam_mode sam_mode, in
|
||||
|
||||
if (CHIP_DATA(pnd)->type != PN532) {
|
||||
// This function is not supported by pn531 neither pn533
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
|
||||
switch (sam_mode) {
|
||||
@ -2657,8 +2635,7 @@ pn532_SAMConfiguration(struct nfc_device *pnd, const pn532_sam_mode sam_mode, in
|
||||
szCmd = 3;
|
||||
break;
|
||||
default:
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
CHIP_DATA(pnd)->sam_mode = sam_mode;
|
||||
return (pn53x_transceive(pnd, abtCmd, szCmd, NULL, 0, timeout));
|
||||
@ -2709,15 +2686,13 @@ pn53x_InListPassiveTarget(struct nfc_device *pnd,
|
||||
case PM_ISO14443B_106:
|
||||
if (!(pnd->btSupportByte & SUPPORT_ISO14443B)) {
|
||||
// Eg. Some PN532 doesn't support type B!
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
break;
|
||||
case PM_JEWEL_106:
|
||||
if (CHIP_DATA(pnd)->type == PN531) {
|
||||
// These modulations are not supported by pn531
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
break;
|
||||
case PM_ISO14443B_212:
|
||||
@ -2725,13 +2700,11 @@ pn53x_InListPassiveTarget(struct nfc_device *pnd,
|
||||
case PM_ISO14443B_847:
|
||||
if ((CHIP_DATA(pnd)->type != PN533) || (!(pnd->btSupportByte & SUPPORT_ISO14443B))) {
|
||||
// These modulations are not supported by pn531 neither pn532
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
break;
|
||||
case PM_UNDEFINED:
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
abtCmd[2] = pmInitModulation; // BrTy, the type of init modulation used for polling a passive tag
|
||||
|
||||
@ -2804,8 +2777,7 @@ pn53x_InAutoPoll(struct nfc_device *pnd,
|
||||
size_t szTargetFound = 0;
|
||||
if (CHIP_DATA(pnd)->type != PN532) {
|
||||
// This function is not supported by pn531 neither pn533
|
||||
pnd->last_error = NFC_EDEVNOTSUPP;
|
||||
return pnd->last_error;
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
|
||||
// InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... }
|
||||
@ -2903,8 +2875,7 @@ pn53x_InJumpForDEP(struct nfc_device *pnd,
|
||||
break;
|
||||
case NBR_847:
|
||||
case NBR_UNDEFINED:
|
||||
pnd->last_error = NFC_EINVARG;
|
||||
return pnd->last_error;
|
||||
return NFC_EINVARG;
|
||||
}
|
||||
|
||||
if (pbtNFCID3i) {
|
||||
@ -3029,25 +3000,25 @@ pn53x_TgInitAsTarget(struct nfc_device *pnd, pn53x_target_mode ptm,
|
||||
int
|
||||
pn53x_check_ack_frame(struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen)
|
||||
{
|
||||
(void)pnd;
|
||||
if (szRxFrameLen >= sizeof(pn53x_ack_frame)) {
|
||||
if (0 == memcmp(pbtRxFrame, pn53x_ack_frame, sizeof(pn53x_ack_frame))) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "PN53x ACKed");
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
}
|
||||
pnd->last_error = NFC_EIO;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unexpected PN53x reply!");
|
||||
return pnd->last_error;
|
||||
return NFC_EIO;
|
||||
}
|
||||
|
||||
int
|
||||
pn53x_check_error_frame(struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen)
|
||||
{
|
||||
(void)pnd;
|
||||
if (szRxFrameLen >= sizeof(pn53x_error_frame)) {
|
||||
if (0 == memcmp(pbtRxFrame, pn53x_error_frame, sizeof(pn53x_error_frame))) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "PN53x sent an error frame");
|
||||
pnd->last_error = NFC_EIO;
|
||||
return pnd->last_error;
|
||||
return NFC_EIO;
|
||||
}
|
||||
}
|
||||
return NFC_SUCCESS;
|
||||
|
||||
@ -94,13 +94,9 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
snprintf(connstring, sizeof(nfc_connstring), "%s:%s:%"PRIu32, PN532_UART_DRIVER_NAME, acPort, PN532_UART_DEFAULT_SPEED);
|
||||
nfc_device *pnd = nfc_device_new(context, connstring);
|
||||
if (!pnd) {
|
||||
perror("malloc");
|
||||
perror("nfc_device_new");
|
||||
uart_close(sp);
|
||||
iDevice = 0;
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
free((void *)acPort);
|
||||
}
|
||||
free(acPorts);
|
||||
uart_list_free(acPorts);
|
||||
return 0;
|
||||
}
|
||||
pnd->driver = &pn532_uart_driver;
|
||||
@ -109,25 +105,17 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
perror("malloc");
|
||||
uart_close(sp);
|
||||
nfc_device_free(pnd);
|
||||
iDevice = 0;
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
free((void *)acPort);
|
||||
}
|
||||
free(acPorts);
|
||||
uart_list_free(acPorts);
|
||||
return 0;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
|
||||
// Alloc and init chip's data
|
||||
if (pn53x_data_new(pnd, &pn532_uart_io) == NULL) {
|
||||
perror("malloc");
|
||||
perror("pn53x_data_new");
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
nfc_device_free(pnd);
|
||||
iDevice = 0;
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
free((void *)acPort);
|
||||
}
|
||||
free(acPorts);
|
||||
uart_list_free(acPorts);
|
||||
return 0;
|
||||
}
|
||||
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532
|
||||
@ -141,11 +129,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
uart_close(DRIVER_DATA(pnd)->port);
|
||||
pn53x_data_free(pnd);
|
||||
nfc_device_free(pnd);
|
||||
iDevice = 0;
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
free((void *)acPort);
|
||||
}
|
||||
free(acPorts);
|
||||
uart_list_free(acPorts);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@ -169,11 +153,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
|
||||
break;
|
||||
}
|
||||
}
|
||||
iDevice = 0;
|
||||
while ((acPort = acPorts[iDevice++])) {
|
||||
free((void *)acPort);
|
||||
}
|
||||
free(acPorts);
|
||||
uart_list_free(acPorts);
|
||||
return device_found;
|
||||
}
|
||||
|
||||
@ -344,29 +324,26 @@ pn532_uart_send(nfc_device *pnd, const uint8_t *pbtData, const size_t szData, in
|
||||
size_t szFrame = 0;
|
||||
|
||||
if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) {
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
return res;
|
||||
}
|
||||
|
||||
res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout);
|
||||
if (res != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)");
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to transmit data. (TX)");
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN];
|
||||
res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, sizeof(abtRxBuf), 0, timeout);
|
||||
if (res != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to read ACK");
|
||||
pnd->last_error = res;
|
||||
return pnd->last_error;
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to read ACK");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) {
|
||||
// The PN53x is running the sent command
|
||||
} else {
|
||||
return pnd->last_error;
|
||||
return NFC_ECHIP;
|
||||
}
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
@ -384,21 +361,21 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
|
||||
abort_p = (void *) & (DRIVER_DATA(pnd)->abort_flag);
|
||||
#endif
|
||||
|
||||
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 5, abort_p, timeout);
|
||||
int res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 5, abort_p, timeout);
|
||||
|
||||
if (abort_p && (NFC_EOPABORTED == pnd->last_error)) {
|
||||
if (abort_p && (NFC_EOPABORTED == res)) {
|
||||
pn532_uart_ack(pnd);
|
||||
return NFC_EOPABORTED;
|
||||
return res;
|
||||
}
|
||||
|
||||
if (pnd->last_error < 0) {
|
||||
if (res < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
|
||||
if (0 != (memcmp(abtRxBuf, pn53x_preamble, 3))) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -406,12 +383,12 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
|
||||
// Error frame
|
||||
uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Application level error detected");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
|
||||
// Extended frame
|
||||
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
|
||||
if (pnd->last_error != 0) {
|
||||
res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
|
||||
if (res != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||
goto error;
|
||||
}
|
||||
@ -419,7 +396,7 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
|
||||
len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
|
||||
if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
@ -427,7 +404,7 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
|
||||
if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
|
||||
// TODO: Retry
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -437,39 +414,39 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
|
||||
|
||||
if (len > szDataLen) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %" PRIuPTR ", len: %" PRIuPTR ")", szDataLen, len);
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// TFI + PD0 (CC+1)
|
||||
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||
if (pnd->last_error != 0) {
|
||||
res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||
if (res != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (abtRxBuf[0] != 0xD5) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (abtRxBuf[1] != CHIP_DATA(pnd)->last_command + 1) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Command Code verification failed");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout);
|
||||
if (pnd->last_error != 0) {
|
||||
res = uart_receive(DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout);
|
||||
if (res != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||
if (pnd->last_error != 0) {
|
||||
res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
|
||||
if (res != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
|
||||
goto error;
|
||||
}
|
||||
@ -482,20 +459,20 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
|
||||
|
||||
if (btDCS != abtRxBuf[0]) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Data checksum mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (0x00 != abtRxBuf[1]) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
|
||||
pnd->last_error = NFC_EIO;
|
||||
res = NFC_EIO;
|
||||
goto error;
|
||||
}
|
||||
// The PN53x command is done and we successfully received the reply
|
||||
return len;
|
||||
error:
|
||||
uart_flush_input(DRIVER_DATA(pnd)->port, true);
|
||||
return pnd->last_error;
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
#ifndef __LOG_H__
|
||||
#define __LOG_H__
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
@ -44,13 +44,19 @@
|
||||
* @macro HAL
|
||||
* @brief Execute corresponding driver function if exists.
|
||||
*/
|
||||
#define HAL( FUNCTION, ... ) pnd->last_error = 0; \
|
||||
if (pnd->driver->FUNCTION) { \
|
||||
return pnd->driver->FUNCTION( __VA_ARGS__ ); \
|
||||
} else { \
|
||||
#define HAL( FUNCTION, ... ) do { \
|
||||
if (!pnd->driver->FUNCTION) { \
|
||||
pnd->last_error = NFC_EDEVNOTSUPP; \
|
||||
return false; \
|
||||
}
|
||||
return pnd->last_error; \
|
||||
} \
|
||||
int __ret = pnd->driver->FUNCTION( __VA_ARGS__ ); \
|
||||
if (__ret < 0) { \
|
||||
pnd->last_error = __ret; \
|
||||
} else { \
|
||||
pnd->last_error = NFC_SUCCESS; \
|
||||
} \
|
||||
return __ret; \
|
||||
} while (0);
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user