Improved code for PN532 driver

This commit is contained in:
Marcos Vives Del Sol 2015-06-15 22:45:11 +02:00
parent 942faef582
commit 6204340059
7 changed files with 103 additions and 132 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@
*.la *.la
*.lo *.lo
*.o *.o
*.stackdump
*~ *~
Doxyfile Doxyfile
INSTALL INSTALL

View File

@ -430,3 +430,16 @@ oom:
return res; return res;
} }
void
uart_list_free(char ** acPorts)
{
char *acPort;
size_t iDevice = 0;
while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}
free(acPorts);
}

View File

@ -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); int uart_send(serial_port sp, const uint8_t *pbtTx, const size_t szTx, int timeout);
char **uart_list_ports(void); char **uart_list_ports(void);
void uart_list_free(char **acPorts);
#endif // __NFC_BUS_UART_H__ #endif // __NFC_BUS_UART_H__

View File

@ -333,10 +333,7 @@ pn53x_transceive(struct nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx
}; };
if (res < 0) { 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); 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; 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 (nm.nmt == NMT_ISO14443BI || nm.nmt == NMT_ISO14443B2SR || nm.nmt == NMT_ISO14443B2CT) {
if (CHIP_DATA(pnd)->type == RCS360) { 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 // 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 NFC_ENOTIMPL;
return pnd->last_error;
} }
// No native support in InListPassiveTarget so we do discovery by hand // 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) { 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 { } else {
const pn53x_modulation pm = pn53x_nm_to_pm(nm); const pn53x_modulation pm = pn53x_nm_to_pm(nm);
if ((PM_UNDEFINED == pm) || (NBR_UNDEFINED == nm.nbr)) { if ((PM_UNDEFINED == pm) || (NBR_UNDEFINED == nm.nbr)) {
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
if ((res = pn53x_InListPassiveTarget(pnd, pm, 1, pbtInitData, szInitData, abtTargetsData, &szTargetsData, timeout)) <= 0) 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) { if (pn53x_current_target_new(pnd, &nttmp) == NULL) {
pnd->last_error = NFC_ESOFT; return NFC_ESOFT;
return pnd->last_error;
} }
// Is a tag info struct available // Is a tag info struct available
if (pnt) { if (pnt) {
@ -1209,8 +1203,7 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
for (size_t n = 0; n < szModulations; n++) { for (size_t n = 0; n < szModulations; n++) {
const pn53x_target_type ptt = pn53x_nm_to_ptt(pnmModulations[n]); const pn53x_target_type ptt = pn53x_nm_to_ptt(pnmModulations[n]);
if (PTT_UNDEFINED == ptt) { if (PTT_UNDEFINED == ptt) {
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
apttTargetTypes[szTargetTypes] = ptt; apttTargetTypes[szTargetTypes] = ptt;
if ((pnd->bAutoIso14443_4) && (ptt == PTT_MIFARE)) { // Hack to have ATS 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; return res;
switch (res) { switch (res) {
case 0: case 0:
return pnd->last_error = NFC_SUCCESS; return NFC_SUCCESS;
break; break;
case 1: case 1:
*pnt = ntTargets[0]; *pnt = ntTargets[0];
if (pn53x_current_target_new(pnd, pnt) == NULL) { if (pn53x_current_target_new(pnd, pnt) == NULL) {
return pnd->last_error = NFC_ESOFT; return NFC_ESOFT;
} }
return res; return res;
case 2: case 2:
*pnt = ntTargets[1]; // We keep the selected one *pnt = ntTargets[1]; // We keep the selected one
if (pn53x_current_target_new(pnd, pnt) == NULL) { if (pn53x_current_target_new(pnd, pnt) == NULL) {
return pnd->last_error = NFC_ESOFT; return NFC_ESOFT;
} }
return res; return res;
default: default:
@ -1259,8 +1252,8 @@ pn53x_initiator_poll_target(struct nfc_device *pnd,
const int timeout_ms = uiPeriod * 150; const int timeout_ms = uiPeriod * 150;
if ((res = pn53x_initiator_select_passive_target_ext(pnd, pnmModulations[n], pbtInitiatorData, szInitiatorData, pnt, timeout_ms)) < 0) { if ((res = pn53x_initiator_select_passive_target_ext(pnd, pnmModulations[n], pbtInitiatorData, szInitiatorData, pnt, timeout_ms)) < 0) {
if (pnd->last_error != NFC_ETIMEOUT) { if (res != NFC_ETIMEOUT) {
result = pnd->last_error; result = res;
goto end; goto end;
} }
} else { } 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 // We can not just send bytes without parity if while the PN53X expects we handled them
if (!pnd->bPar) { if (!pnd->bPar) {
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
// Copy the data into the command frame // 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 // 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) { if ((res = pn53x_set_tx_bits(pnd, 0)) < 0) {
pnd->last_error = res; return res;
return pnd->last_error;
} }
// Send the frame to the PN53X chip and get the answer // 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) // We have to give the amount of bytes + (the two command bytes 0xD4, 0x42)
uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN]; uint8_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
if ((res = pn53x_transceive(pnd, abtCmd, szTx + szExtraTxLen, abtRx, sizeof(abtRx), timeout)) < 0) { if ((res = pn53x_transceive(pnd, abtCmd, szTx + szExtraTxLen, abtRx, sizeof(abtRx), timeout)) < 0) {
pnd->last_error = res; return res;
return pnd->last_error;
} }
const size_t szRxLen = (size_t)res - 1; const size_t szRxLen = (size_t)res - 1;
if (pbtRx != NULL) { 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 // Sorry, no arbitrary parity bits support for now
if (!pnd->bPar) { if (!pnd->bPar) {
pnd->last_error = NFC_ENOTIMPL; return NFC_ENOTIMPL;
return pnd->last_error;
} }
// Sorry, no easy framing support // Sorry, no easy framing support
if (pnd->bEasyFraming) { if (pnd->bEasyFraming) {
pnd->last_error = NFC_ENOTIMPL; return NFC_ENOTIMPL;
return pnd->last_error;
} }
// TODO CRC support but it probably doesn't make sense for (szTxBits % 8 != 0) ... // TODO CRC support but it probably doesn't make sense for (szTxBits % 8 != 0) ...
if (pnd->bCrc) { if (pnd->bCrc) {
pnd->last_error = NFC_ENOTIMPL; return NFC_ENOTIMPL;
return pnd->last_error;
} }
__pn53x_init_timer(pnd, *cycles); __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 // We can not just send bytes without parity while the PN53X expects we handled them
if (!pnd->bPar) { if (!pnd->bPar) {
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
// Sorry, no easy framing support // Sorry, no easy framing support
// TODO to be changed once we'll provide easy framing support from libnfc itself... // TODO to be changed once we'll provide easy framing support from libnfc itself...
if (pnd->bEasyFraming) { if (pnd->bEasyFraming) {
pnd->last_error = NFC_ENOTIMPL; return NFC_ENOTIMPL;
return pnd->last_error;
} }
uint8_t txmode = 0; 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 // Check if there is a saved target
if (CHIP_DATA(pnd)->current_target == NULL) { if (CHIP_DATA(pnd)->current_target == NULL) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "target_is_present(): no saved target"); 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 // Check if the argument target nt is equals to current saved target
if ((pnt != NULL) && (!pn53x_current_target_is(pnd, pnt))) { 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"); 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 // Ping target
@ -2096,7 +2081,7 @@ pn53x_initiator_target_is_present(struct nfc_device *pnd, const nfc_target *pnt)
} }
if (ret == NFC_ETGRELEASED) if (ret == NFC_ETGRELEASED)
pn53x_current_target_free(pnd); pn53x_current_target_free(pnd);
return pnd->last_error = ret; return ret;
} }
#define SAK_ISO14443_4_COMPLIANT 0x20 #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: case NMT_ISO14443A:
ptm = PTM_PASSIVE_ONLY; ptm = PTM_PASSIVE_ONLY;
if ((pnt->nti.nai.abtUid[0] != 0x08) || (pnt->nti.nai.szUidLen != 4)) { if ((pnt->nti.nai.abtUid[0] != 0x08) || (pnt->nti.nai.szUidLen != 4)) {
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
pn53x_set_parameters(pnd, PARAM_AUTO_ATR_RES, false); pn53x_set_parameters(pnd, PARAM_AUTO_ATR_RES, false);
if (CHIP_DATA(pnd)->type == PN532) { // We have a PN532 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_ISO14443B2SR:
case NMT_ISO14443B2CT: case NMT_ISO14443B2CT:
case NMT_JEWEL: case NMT_JEWEL:
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
// Let the PN53X be activated by the RF level detector from power down mode // 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_ISO14443B2SR:
case NMT_ISO14443B2CT: case NMT_ISO14443B2CT:
case NMT_JEWEL: case NMT_JEWEL:
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
bool targetActivated = false; 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 pnt->nti.ndi.ndm = ndm; // Update DEP mode
} }
if (pn53x_current_target_new(pnd, pnt) == NULL) { if (pn53x_current_target_new(pnd, pnt) == NULL) {
pnd->last_error = NFC_ESOFT; return NFC_ESOFT;
return pnd->last_error;
} }
if (ptm & PTM_ISO14443_4_PICC_ONLY) { 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; break;
} else { } else {
// TODO Support EasyFraming for other cases by software // TODO Support EasyFraming for other cases by software
pnd->last_error = NFC_ENOTIMPL; return NFC_ENOTIMPL;
return pnd->last_error;
} }
} }
// NO BREAK // 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); size_t szRx = sizeof(abtRx);
int res = 0; int res = 0;
if ((res = pn53x_transceive(pnd, abtCmd, sizeof(abtCmd), abtRx, szRx, timeout)) < 0) if ((res = pn53x_transceive(pnd, abtCmd, sizeof(abtCmd), abtRx, szRx, timeout)) < 0)
return pnd->last_error; return res;
szRx = (size_t) res; szRx = (size_t) res;
// Save the received bytes count // Save the received bytes count
szRx -= 1; szRx -= 1;
@ -2492,8 +2472,7 @@ pn53x_target_send_bytes(struct nfc_device *pnd, const uint8_t *pbtTx, const size
break; break;
} else { } else {
// TODO Support EasyFraming for other cases by software // TODO Support EasyFraming for other cases by software
pnd->last_error = NFC_ENOTIMPL; return NFC_ENOTIMPL;
return pnd->last_error;
} }
} }
// NO BREAK // 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) { if (CHIP_DATA(pnd)->type != PN532) {
// This function is not supported by pn531 neither pn533 // This function is not supported by pn531 neither pn533
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
switch (sam_mode) { switch (sam_mode) {
@ -2657,8 +2635,7 @@ pn532_SAMConfiguration(struct nfc_device *pnd, const pn532_sam_mode sam_mode, in
szCmd = 3; szCmd = 3;
break; break;
default: default:
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
CHIP_DATA(pnd)->sam_mode = sam_mode; CHIP_DATA(pnd)->sam_mode = sam_mode;
return (pn53x_transceive(pnd, abtCmd, szCmd, NULL, 0, timeout)); return (pn53x_transceive(pnd, abtCmd, szCmd, NULL, 0, timeout));
@ -2709,15 +2686,13 @@ pn53x_InListPassiveTarget(struct nfc_device *pnd,
case PM_ISO14443B_106: case PM_ISO14443B_106:
if (!(pnd->btSupportByte & SUPPORT_ISO14443B)) { if (!(pnd->btSupportByte & SUPPORT_ISO14443B)) {
// Eg. Some PN532 doesn't support type B! // Eg. Some PN532 doesn't support type B!
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
break; break;
case PM_JEWEL_106: case PM_JEWEL_106:
if (CHIP_DATA(pnd)->type == PN531) { if (CHIP_DATA(pnd)->type == PN531) {
// These modulations are not supported by pn531 // These modulations are not supported by pn531
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
break; break;
case PM_ISO14443B_212: case PM_ISO14443B_212:
@ -2725,13 +2700,11 @@ pn53x_InListPassiveTarget(struct nfc_device *pnd,
case PM_ISO14443B_847: case PM_ISO14443B_847:
if ((CHIP_DATA(pnd)->type != PN533) || (!(pnd->btSupportByte & SUPPORT_ISO14443B))) { if ((CHIP_DATA(pnd)->type != PN533) || (!(pnd->btSupportByte & SUPPORT_ISO14443B))) {
// These modulations are not supported by pn531 neither pn532 // These modulations are not supported by pn531 neither pn532
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
break; break;
case PM_UNDEFINED: case PM_UNDEFINED:
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
abtCmd[2] = pmInitModulation; // BrTy, the type of init modulation used for polling a passive tag 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; size_t szTargetFound = 0;
if (CHIP_DATA(pnd)->type != PN532) { if (CHIP_DATA(pnd)->type != PN532) {
// This function is not supported by pn531 neither pn533 // This function is not supported by pn531 neither pn533
pnd->last_error = NFC_EDEVNOTSUPP; return NFC_EDEVNOTSUPP;
return pnd->last_error;
} }
// InAutoPoll frame looks like this { 0xd4, 0x60, 0x0f, 0x01, 0x00 } => { direction, command, pollnr, period, types... } // 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; break;
case NBR_847: case NBR_847:
case NBR_UNDEFINED: case NBR_UNDEFINED:
pnd->last_error = NFC_EINVARG; return NFC_EINVARG;
return pnd->last_error;
} }
if (pbtNFCID3i) { if (pbtNFCID3i) {
@ -3029,25 +3000,25 @@ pn53x_TgInitAsTarget(struct nfc_device *pnd, pn53x_target_mode ptm,
int int
pn53x_check_ack_frame(struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen) 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 (szRxFrameLen >= sizeof(pn53x_ack_frame)) {
if (0 == memcmp(pbtRxFrame, pn53x_ack_frame, 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"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "PN53x ACKed");
return NFC_SUCCESS; return NFC_SUCCESS;
} }
} }
pnd->last_error = NFC_EIO;
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unexpected PN53x reply!"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unexpected PN53x reply!");
return pnd->last_error; return NFC_EIO;
} }
int int
pn53x_check_error_frame(struct nfc_device *pnd, const uint8_t *pbtRxFrame, const size_t szRxFrameLen) 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 (szRxFrameLen >= sizeof(pn53x_error_frame)) {
if (0 == memcmp(pbtRxFrame, pn53x_error_frame, 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"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "PN53x sent an error frame");
pnd->last_error = NFC_EIO; return NFC_EIO;
return pnd->last_error;
} }
} }
return NFC_SUCCESS; return NFC_SUCCESS;

View File

@ -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); 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); nfc_device *pnd = nfc_device_new(context, connstring);
if (!pnd) { if (!pnd) {
perror("malloc"); perror("nfc_device_new");
uart_close(sp); uart_close(sp);
iDevice = 0; uart_list_free(acPorts);
while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}
free(acPorts);
return 0; return 0;
} }
pnd->driver = &pn532_uart_driver; pnd->driver = &pn532_uart_driver;
@ -109,25 +105,17 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
perror("malloc"); perror("malloc");
uart_close(sp); uart_close(sp);
nfc_device_free(pnd); nfc_device_free(pnd);
iDevice = 0; uart_list_free(acPorts);
while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}
free(acPorts);
return 0; return 0;
} }
DRIVER_DATA(pnd)->port = sp; DRIVER_DATA(pnd)->port = sp;
// Alloc and init chip's data // Alloc and init chip's data
if (pn53x_data_new(pnd, &pn532_uart_io) == NULL) { if (pn53x_data_new(pnd, &pn532_uart_io) == NULL) {
perror("malloc"); perror("pn53x_data_new");
uart_close(DRIVER_DATA(pnd)->port); uart_close(DRIVER_DATA(pnd)->port);
nfc_device_free(pnd); nfc_device_free(pnd);
iDevice = 0; uart_list_free(acPorts);
while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}
free(acPorts);
return 0; return 0;
} }
// SAMConfiguration command if needed to wakeup the chip and pn53x_SAMConfiguration check if the chip is a PN532 // 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); uart_close(DRIVER_DATA(pnd)->port);
pn53x_data_free(pnd); pn53x_data_free(pnd);
nfc_device_free(pnd); nfc_device_free(pnd);
iDevice = 0; uart_list_free(acPorts);
while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}
free(acPorts);
return 0; return 0;
} }
#else #else
@ -169,11 +153,7 @@ pn532_uart_scan(const nfc_context *context, nfc_connstring connstrings[], const
break; break;
} }
} }
iDevice = 0; uart_list_free(acPorts);
while ((acPort = acPorts[iDevice++])) {
free((void *)acPort);
}
free(acPorts);
return device_found; 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; size_t szFrame = 0;
if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) { if ((res = pn53x_build_frame(abtFrame, &szFrame, pbtData, szData)) < 0) {
pnd->last_error = res; return res;
return pnd->last_error;
} }
res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout); res = uart_send(DRIVER_DATA(pnd)->port, abtFrame, szFrame, timeout);
if (res != 0) { if (res != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to transmit data. (TX)"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to transmit data. (TX)");
pnd->last_error = res; return res;
return pnd->last_error;
} }
uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN]; uint8_t abtRxBuf[PN53x_ACK_FRAME__LEN];
res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, sizeof(abtRxBuf), 0, timeout); res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, sizeof(abtRxBuf), 0, timeout);
if (res != 0) { if (res != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%s", "Unable to read ACK"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to read ACK");
pnd->last_error = res; return res;
return pnd->last_error;
} }
if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) { if (pn53x_check_ack_frame(pnd, abtRxBuf, sizeof(abtRxBuf)) == 0) {
// The PN53x is running the sent command // The PN53x is running the sent command
} else { } else {
return pnd->last_error; return NFC_ECHIP;
} }
return NFC_SUCCESS; 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); abort_p = (void *) & (DRIVER_DATA(pnd)->abort_flag);
#endif #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); pn532_uart_ack(pnd);
return NFC_EOPABORTED; return res;
} }
if (pnd->last_error < 0) { if (res < 0) {
goto error; goto error;
} }
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff }; const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
if (0 != (memcmp(abtRxBuf, pn53x_preamble, 3))) { if (0 != (memcmp(abtRxBuf, pn53x_preamble, 3))) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch"); 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; goto error;
} }
@ -406,12 +383,12 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
// Error frame // Error frame
uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout); 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"); 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; goto error;
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) { } else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Extended frame // Extended frame
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout); res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
if (pnd->last_error != 0) { if (res != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
goto error; 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; len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) { if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->last_error = NFC_EIO; res = NFC_EIO;
goto error; goto error;
} }
} else { } 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])) { if (256 != (abtRxBuf[3] + abtRxBuf[4])) {
// TODO: Retry // TODO: Retry
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->last_error = NFC_EIO; res = NFC_EIO;
goto error; goto error;
} }
@ -437,39 +414,39 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
if (len > szDataLen) { 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); 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; goto error;
} }
// TFI + PD0 (CC+1) // TFI + PD0 (CC+1)
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout); res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) { if (res != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
goto error; goto error;
} }
if (abtRxBuf[0] != 0xD5) { if (abtRxBuf[0] != 0xD5) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "TFI Mismatch");
pnd->last_error = NFC_EIO; res = NFC_EIO;
goto error; goto error;
} }
if (abtRxBuf[1] != CHIP_DATA(pnd)->last_command + 1) { if (abtRxBuf[1] != CHIP_DATA(pnd)->last_command + 1) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Command Code verification failed"); 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; goto error;
} }
if (len) { if (len) {
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout); res = uart_receive(DRIVER_DATA(pnd)->port, pbtData, len, 0, timeout);
if (pnd->last_error != 0) { if (res != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
goto error; goto error;
} }
} }
pnd->last_error = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout); res = uart_receive(DRIVER_DATA(pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) { if (res != 0) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
goto error; goto error;
} }
@ -482,20 +459,20 @@ pn532_uart_receive(nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, in
if (btDCS != abtRxBuf[0]) { if (btDCS != abtRxBuf[0]) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Data checksum mismatch"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Data checksum mismatch");
pnd->last_error = NFC_EIO; res = NFC_EIO;
goto error; goto error;
} }
if (0x00 != abtRxBuf[1]) { if (0x00 != abtRxBuf[1]) {
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame postamble mismatch"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
pnd->last_error = NFC_EIO; res = NFC_EIO;
goto error; goto error;
} }
// The PN53x command is done and we successfully received the reply // The PN53x command is done and we successfully received the reply
return len; return len;
error: error:
uart_flush_input(DRIVER_DATA(pnd)->port, true); uart_flush_input(DRIVER_DATA(pnd)->port, true);
return pnd->last_error; return res;
} }
int int

View File

@ -27,6 +27,8 @@
#ifndef __LOG_H__ #ifndef __LOG_H__
#define __LOG_H__ #define __LOG_H__
#include <string.h>
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H

View File

@ -44,13 +44,19 @@
* @macro HAL * @macro HAL
* @brief Execute corresponding driver function if exists. * @brief Execute corresponding driver function if exists.
*/ */
#define HAL( FUNCTION, ... ) pnd->last_error = 0; \ #define HAL( FUNCTION, ... ) do { \
if (pnd->driver->FUNCTION) { \ if (!pnd->driver->FUNCTION) { \
return pnd->driver->FUNCTION( __VA_ARGS__ ); \
} else { \
pnd->last_error = NFC_EDEVNOTSUPP; \ 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 #ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b))