From daa178b18f7a0d1dfae4b3cd7484e77045c72813 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Thu, 29 Jul 2010 14:16:11 +0000 Subject: [PATCH] Enhance error handeling. - New API functions: nfc_strerror(), nfc_strerror_r() and nfc_perror(); - Drivers now have a reference to chips callback methods; - Rename -pn53x_err2string to pn53x_strerror and add it to pn53x_callbacks_list. --- ChangeLog | 8 ++++ include/nfc/nfc-types.h | 11 +++++ include/nfc/nfc.h | 5 +++ libnfc/chips/pn53x.c | 89 +++++++++++++++-------------------------- libnfc/chips/pn53x.h | 6 +++ libnfc/drivers.h | 14 ++++--- libnfc/nfc.c | 26 ++++++++++++ 7 files changed, 96 insertions(+), 63 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff1a91c..fab2442 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +??? +---- + +Changes: + - API: New nfc_perror(), nfc_strerror() and nfc_strerror_r() functions. + + + Apr 6, 2010 - 1.3.4 -------------------- diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h index 51d07db..2b0c4a8 100644 --- a/include/nfc/nfc-types.h +++ b/include/nfc/nfc-types.h @@ -93,6 +93,15 @@ typedef struct { uint32_t uiBusIndex; } nfc_device_desc_t; +/** + * @struct chip_callbacks + * @brief Functions for chip specific functions. + */ +struct chip_callbacks { + /** Error lookup */ + const char* (*strerror) (const nfc_device_t *pnd); +}; + /** * @struct driver_callbacks * @brief Generic structure to handle NFC device functions. @@ -100,6 +109,8 @@ typedef struct { struct driver_callbacks { /** Driver name */ const char* acDriver; + /** Chip specific callback functions */ + const struct chip_callbacks *pcc; /** Pick devices callback */ nfc_device_desc_t *(*pick_device)(void); /** List devices callback */ diff --git a/include/nfc/nfc.h b/include/nfc/nfc.h index 6756abc..b1df6cc 100644 --- a/include/nfc/nfc.h +++ b/include/nfc/nfc.h @@ -78,6 +78,11 @@ NFC_EXPORT bool nfc_target_send_bits(nfc_device_t* pnd, const byte_t* pbtTx, con NFC_EXPORT bool nfc_target_send_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen); NFC_EXPORT bool nfc_target_send_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen); +/* Error reporting */ +NFC_EXPORT const char *nfc_strerror (const nfc_device_t *pnd); +NFC_EXPORT int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen); +NFC_EXPORT void nfc_perror (const nfc_device_t *pnd, const char *pcString); + /* Special data accessors */ NFC_EXPORT const char* nfc_device_name(nfc_device_t* pnd); diff --git a/libnfc/chips/pn53x.c b/libnfc/chips/pn53x.c index d7b913e..8e7cf92 100644 --- a/libnfc/chips/pn53x.c +++ b/libnfc/chips/pn53x.c @@ -60,9 +60,6 @@ const byte_t pncmd_target_receive [ 2] = { 0xD4,0x88 }; const byte_t pncmd_target_send [264] = { 0xD4,0x90 }; const byte_t pncmd_target_get_status [ 2] = { 0xD4,0x8A }; -const char * -pn53x_err2string (int iError, char const **ppcDescription); - bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen) { byte_t abtRx[MAX_FRAME_LEN]; @@ -81,16 +78,6 @@ bool pn53x_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxL pnd->iErrorCode = pbtRx[0] & 0x3f; - // Make sure there was no failure reported by the PN53X chip (0x00 == OK) - if (pnd->iErrorCode != 0) { - const char *s, *l; - - s = pn53x_err2string (pnd->iErrorCode, &l); - if (s) { - printf (" s = %s\n l = %s\n", s, l); - } - } - // Succesful transmission return (0 == pnd->iErrorCode); } @@ -322,61 +309,49 @@ pn53x_InDeselect(nfc_device_t* pnd, const uint8_t ui8Target) } struct sErrorMessage { - int iError; + int iErrorCode; const char *pcErrorMsg; - const char *pcErrorDescription; } sErrorMessages[] = { - { 0x00, "success", "The request was successful." }, - { 0x01, "timout", "Time Out, the target has not answered." }, - { 0x02, "crc error", "A CRC error has been detected by the CIU." }, - { 0x03, "parity error", "A Parity error has been detected by the CIU." }, - { 0x04, "wrong bit count", "During an anti-collision/select operation (ISO/IEC14443-3 Type A and ISO/" - "IEC18092 106 kbps passive mode), an erroneous Bit Count has been detected." }, - { 0x05, "framing error", "Framing error during Mifare operation." }, - { 0x06, "bit-collision", "An abnormal bit-collision has been detected during bit wise anti-collision" - " at 106 kbps." }, - { 0x07, "buffer too small", "Communication buffer size insufficient." }, - { 0x09, "buffer overflow", "RF Buffer overflow has been detected by the CIU (bit BufferOvfl of the register" - " CIU_Error)." }, - { 0x0a, "timout", "In active communication mode, the RF field has not been switched on in time by" - " the counterpart (as defined in NFCIP-1 standard)." }, - { 0x0b, "protocol error", "RF Protocol error." }, - { 0x0d, "temerature", "The internal temperature sensor has detected overheating, and therefore has" - " automatically switched off the antenna drivers." }, - { 0x0e, "overflow", "Internal buffer overflow." }, - { 0x10, "invalid parameter", "Invalid parameter."}, + { 0x00, "Success" }, + { 0x01, "Timeout" }, + { 0x02, "CRC Error" }, + { 0x03, "Parity Error" }, + { 0x04, "Erroneous Bit Count" }, + { 0x05, "Framing Error" }, + { 0x06, "Bit-collision" }, + { 0x07, "Buffer Too Small" }, + { 0x09, "Buffer Overflow" }, + { 0x0a, "Timeout" }, + { 0x0b, "Protocol Error" }, + { 0x0d, "Overheating" }, + { 0x0e, "Internal Buffer overflow." }, + { 0x10, "Invalid Parameter" }, /* DEP Errors */ - { 0x12, "unknown command", "The PN532 configured in target mode does not support the command received from" - " the initiator." }, - { 0x13, "invalid parameter", "The data format does not match to the specification." }, + { 0x12, "Unknown DEP Command" }, + { 0x13, "Invalid Parameter" }, /* MIFARE */ - { 0x14, "authentication", "Authentication error." }, - { 0x23, "check byte", "ISO/IEC14443-3: UID Check byte is wrong." }, - { 0x25, "invalid state", "The system is in a state which does not allow the operation." }, - { 0x26, "operation not allowed", "Operation not allowed in this configuration (host controller interface)." }, - { 0x27, "command not acceptable", "This command is not acceptable due to the current context of the PN532" - " (Initiator vs. Target, unknown target number, Target not in the good state," - " ...)" }, - { 0x29, "target released", "The PN532 configured as target has been released by its initiator." }, - { 0x2a, "card id mismatch", "PN532 and ISO/IEC14443-3B only: the ID of the card does not match, meaning " - "that the expected card has been exchanged with another one." }, - { 0x2B, "card discarded", "PN532 and ISO/IEC14443-3B only: the card previously activated has disappeared." }, - { 0x2C, "NFCID3 mismatch", "Mismatch between the NFCID3 initiator and the NFCID3 target in DEP 212/424 kbps" - " passive." }, - { 0x2D, "over current", "An over-current event has been detected." }, - { 0x2E, "NAD missing", "NAD missing in DEP frame." }, + { 0x14, "Authentication Error" }, + /* */ + { 0x23, "Wrong ISO/IEC14443-3 Check Byte" }, + { 0x25, "Invalid State" }, + { 0x26, "Operation Not Allowed" }, + { 0x27, "Command Not Acceptable" }, + { 0x29, "Target Released" }, + { 0x2a, "Card ID Mismatch" }, + { 0x2B, "Card Discarded" }, + { 0x2C, "NFCID3 Mismatch" }, + { 0x2D, "Over Current" }, + { 0x2E, "NAD Missing in DEP Frame" } }; const char * -pn53x_err2string (int iError, char const **ppcDescription) +pn53x_strerror (const nfc_device_t *pnd) { - const char *pcRes = NULL; + const char *pcRes = "Unknown error"; for (size_t i=0; i < (sizeof (sErrorMessages) / sizeof (struct sErrorMessage)); i++) { - if (sErrorMessages[i].iError == iError) { + if (sErrorMessages[i].iErrorCode == pnd->iErrorCode) { pcRes = sErrorMessages[i].pcErrorMsg; - if (ppcDescription) - *ppcDescription = sErrorMessages[i].pcErrorDescription; break; } } diff --git a/libnfc/chips/pn53x.h b/libnfc/chips/pn53x.h index a371d22..efef7d7 100644 --- a/libnfc/chips/pn53x.h +++ b/libnfc/chips/pn53x.h @@ -81,5 +81,11 @@ bool pn53x_decode_target_data(const byte_t* pbtRawData, size_t szDataLen, nfc_ch bool pn53x_InListPassiveTarget(const nfc_device_t* pnd, const nfc_modulation_t nmInitModulation, const byte_t szMaxTargets, const byte_t* pbtInitiatorData, const size_t szInitiatorDataLen, byte_t* pbtTargetsData, size_t* pszTargetsData); bool pn53x_InDeselect(nfc_device_t* pnd, const uint8_t ui8Target); +const char *pn53x_strerror (const nfc_device_t *pnd); + +static const struct chip_callbacks pn53x_callbacks_list = { + pn53x_strerror +}; + #endif // __NFC_CHIPS_PN53X_H__ diff --git a/libnfc/drivers.h b/libnfc/drivers.h index b79228d..399b53f 100644 --- a/libnfc/drivers.h +++ b/libnfc/drivers.h @@ -27,6 +27,8 @@ #include +#include "chips/pn53x.h" + #if defined (DRIVER_ACR122_ENABLED) #include "drivers/acr122.h" #endif /* DRIVER_ACR122_ENABLED */ @@ -55,21 +57,21 @@ #define MAX_FRAME_LEN 264 static const struct driver_callbacks drivers_callbacks_list[] = { -// Driver Name Pick Device List Devices Connect Transceive Disconnect +// Driver Name Chip callbacks Pick Device List Devices Connect Transceive Disconnect #if defined (DRIVER_ACR122_ENABLED) - { ACR122_DRIVER_NAME, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect }, + { ACR122_DRIVER_NAME, &pn53x_callbacks_list, acr122_pick_device, acr122_list_devices, acr122_connect, acr122_transceive, acr122_disconnect }, #endif /* DRIVER_ACR122_ENABLED */ #if defined (DRIVER_PN531_USB_ENABLED) - { PN531_USB_DRIVER_NAME, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect }, + { PN531_USB_DRIVER_NAME, &pn53x_callbacks_list, pn531_usb_pick_device, pn531_usb_list_devices, pn531_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect }, #endif /* DRIVER_PN531_USB_ENABLED */ #if defined (DRIVER_PN533_USB_ENABLED) - { PN533_USB_DRIVER_NAME, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect }, + { PN533_USB_DRIVER_NAME, &pn53x_callbacks_list, pn533_usb_pick_device, pn533_usb_list_devices, pn533_usb_connect, pn53x_usb_transceive, pn53x_usb_disconnect }, #endif /* DRIVER_PN533_USB_ENABLED */ #if defined (DRIVER_ARYGON_ENABLED) - { ARYGON_DRIVER_NAME, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect }, + { ARYGON_DRIVER_NAME, &pn53x_callbacks_list, arygon_pick_device, arygon_list_devices, arygon_connect, arygon_transceive, arygon_disconnect }, #endif /* DRIVER_ARYGON_ENABLED */ #if defined (DRIVER_PN532_UART_ENABLED) - { PN532_UART_DRIVER_NAME, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect }, + { PN532_UART_DRIVER_NAME, &pn53x_callbacks_list, pn532_uart_pick_device, pn532_uart_list_devices, pn532_uart_connect, pn532_uart_transceive, pn532_uart_disconnect }, #endif /* DRIVER_PN532_UART_ENABLED */ }; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index aa139be..460a60c 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -1004,6 +1004,32 @@ bool nfc_target_send_dep_bytes(nfc_device_t* pnd, const byte_t* pbtTx, const siz return true; } +/** + * @brief Return the PCD error string + * @return Returns a string + */ +const char *nfc_strerror (const nfc_device_t *pnd) +{ + return pnd->pdc->pcc->strerror (pnd); +} + +/** + * @brief Renders the PCD error in pcStrErrBuf for a maximum size of szBufLen caracters + * @return Returns 0 upon success + */ +int nfc_strerror_r (const nfc_device_t *pnd, char *pcStrErrBuf, size_t szBufLen) +{ + return (snprintf (pcStrErrBuf, szBufLen, "%s", nfc_strerror (pnd)) < 0) ? -1 : 0; +} + +/** + * @brief Display the PCD error a-la perror + */ +void nfc_perror (const nfc_device_t *pnd, const char *pcString) +{ + fprintf (stderr, "%s: %s\n", pcString, nfc_strerror (pnd)); +} + /* Special data accessors */ /**