From 225094e2c8d298e43cabcc904712fe079c8e1bbb Mon Sep 17 00:00:00 2001 From: lego Date: Fri, 1 Feb 2013 14:40:40 +0200 Subject: [PATCH] Add nfc_register_driver. Issue 137. The nfc_register_driver allows users of the library to write their own device drivers without needing to resort to hacking libnfc itself. --- include/nfc/nfc-types.h | 5 ++ include/nfc/nfc.h | 1 + libnfc/drivers.h | 28 +--------- libnfc/nfc.c | 120 ++++++++++++++++++++++++++++++---------- 4 files changed, 98 insertions(+), 56 deletions(-) diff --git a/include/nfc/nfc-types.h b/include/nfc/nfc-types.h index acdf061..d2e8d91 100644 --- a/include/nfc/nfc-types.h +++ b/include/nfc/nfc-types.h @@ -42,6 +42,11 @@ typedef struct nfc_context nfc_context; */ typedef struct nfc_device nfc_device; +/** + * NFC device driver + */ +typedef struct nfc_driver nfc_driver; + /** * Connection string */ diff --git a/include/nfc/nfc.h b/include/nfc/nfc.h index bd311b2..5507140 100644 --- a/include/nfc/nfc.h +++ b/include/nfc/nfc.h @@ -79,6 +79,7 @@ extern "C" { /* Library initialization/deinitialization */ NFC_EXPORT void nfc_init(nfc_context **context) ATTRIBUTE_NONNULL(1); NFC_EXPORT void nfc_exit(nfc_context *context) ATTRIBUTE_NONNULL(1); + NFC_EXPORT int nfc_register_driver(const nfc_driver *driver); /* NFC Device/Hardware manipulation */ NFC_EXPORT nfc_device *nfc_open(nfc_context *context, const nfc_connstring connstring) ATTRIBUTE_NONNULL(1); diff --git a/libnfc/drivers.h b/libnfc/drivers.h index f04f43b..76ed41f 100644 --- a/libnfc/drivers.h +++ b/libnfc/drivers.h @@ -29,32 +29,6 @@ # include -# if defined (DRIVER_ACR122_PCSC_ENABLED) -# include "drivers/acr122_pcsc.h" -# endif /* DRIVER_ACR122_PCSC_ENABLED */ - -# if defined (DRIVER_ACR122_USB_ENABLED) -# include "drivers/acr122_usb.h" -# endif /* DRIVER_ACR122_USB_ENABLED */ - -# if defined (DRIVER_ACR122S_ENABLED) -# include "drivers/acr122s.h" -# endif /* DRIVER_ACR122S_ENABLED */ - -# if defined (DRIVER_PN53X_USB_ENABLED) -# include "drivers/pn53x_usb.h" -# endif /* DRIVER_PN53X_USB_ENABLED */ - -# if defined (DRIVER_ARYGON_ENABLED) -# include "drivers/arygon.h" -# endif /* DRIVER_ARYGON_ENABLED */ - -# if defined (DRIVER_PN532_UART_ENABLED) -# include "drivers/pn532_uart.h" -# endif /* DRIVER_PN532_UART_ENABLED */ - -# define DRIVERS_MAX_DEVICES 16 - -extern const struct nfc_driver *nfc_drivers[]; +extern const struct nfc_driver_list* nfc_drivers; #endif // __NFC_DRIVERS_H__ diff --git a/libnfc/nfc.c b/libnfc/nfc.c index b1dc537..c352a01 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -81,31 +81,89 @@ #include "target-subr.h" #include "drivers.h" +#if defined (DRIVER_ACR122_PCSC_ENABLED) +# include "drivers/acr122_pcsc.h" +#endif /* DRIVER_ACR122_PCSC_ENABLED */ + +#if defined (DRIVER_ACR122_USB_ENABLED) +# include "drivers/acr122_usb.h" +#endif /* DRIVER_ACR122_USB_ENABLED */ + +#if defined (DRIVER_ACR122S_ENABLED) +# include "drivers/acr122s.h" +#endif /* DRIVER_ACR122S_ENABLED */ + +#if defined (DRIVER_PN53X_USB_ENABLED) +# include "drivers/pn53x_usb.h" +#endif /* DRIVER_PN53X_USB_ENABLED */ + +#if defined (DRIVER_ARYGON_ENABLED) +# include "drivers/arygon.h" +#endif /* DRIVER_ARYGON_ENABLED */ + +#if defined (DRIVER_PN532_UART_ENABLED) +# include "drivers/pn532_uart.h" +#endif /* DRIVER_PN532_UART_ENABLED */ + + #define LOG_CATEGORY "libnfc.general" #define LOG_GROUP NFC_LOG_GROUP_GENERAL -const struct nfc_driver *nfc_drivers[] = { -# if defined (DRIVER_PN53X_USB_ENABLED) - &pn53x_usb_driver, -# endif /* DRIVER_PN53X_USB_ENABLED */ -# if defined (DRIVER_ACR122_PCSC_ENABLED) - &acr122_pcsc_driver, -# endif /* DRIVER_ACR122_PCSC_ENABLED */ -# if defined (DRIVER_ACR122_USB_ENABLED) - &acr122_usb_driver, -# endif /* DRIVER_ACR122_USB_ENABLED */ -# if defined (DRIVER_ACR122S_ENABLED) - &acr122s_driver, -# endif /* DRIVER_ACR122S_ENABLED */ -# if defined (DRIVER_PN532_UART_ENABLED) - &pn532_uart_driver, -# endif /* DRIVER_PN532_UART_ENABLED */ -# if defined (DRIVER_ARYGON_ENABLED) - &arygon_driver, -# endif /* DRIVER_ARYGON_ENABLED */ - NULL +struct nfc_driver_list +{ + const struct nfc_driver_list *next; + const struct nfc_driver *driver; }; +const struct nfc_driver_list* nfc_drivers = NULL; + +static void +nfc_drivers_init() +{ +#if defined (DRIVER_PN53X_USB_ENABLED) + nfc_register_driver(&pn53x_usb_driver); +#endif /* DRIVER_PN53X_USB_ENABLED */ +#if defined (DRIVER_ACR122_PCSC_ENABLED) + nfc_register_driver(&acr122_pcsc_driver); +#endif /* DRIVER_ACR122_PCSC_ENABLED */ +#if defined (DRIVER_ACR122_USB_ENABLED) + nfc_register_driver(&acr122_usb_driver); +#endif /* DRIVER_ACR122_USB_ENABLED */ +#if defined (DRIVER_ACR122S_ENABLED) + nfc_register_driver(&acr122s_driver); +#endif /* DRIVER_ACR122S_ENABLED */ +#if defined (DRIVER_PN532_UART_ENABLED) + nfc_register_driver(&pn532_uart_driver); +#endif /* DRIVER_PN532_UART_ENABLED */ +#if defined (DRIVER_ARYGON_ENABLED) + nfc_register_driver(&arygon_driver); +#endif /* DRIVER_ARYGON_ENABLED */ +} + +/** @ingroup lib + * @brief Register an NFC device driver with libnfc. + * This function registers a driver with libnfc, the caller is responsible of managing the lifetime of the + * driver and make sure that any resources associated with the driver are available after registration. + * @param pnd Pointer to an NFC device driver to be registered. + * @retval NFC_SUCCESS If the driver registration succeeds. + */ +int +nfc_register_driver(const struct nfc_driver *ndr) +{ + if (!ndr) + return NFC_EINVARG; + + struct nfc_driver_list *pndl = (struct nfc_driver_list*)malloc(sizeof(struct nfc_driver_list)); + if (!pndl) + return NFC_ESOFT; + + pndl->driver = ndr; + pndl->next = nfc_drivers; + nfc_drivers = pndl; + + return NFC_SUCCESS; +} + /** @ingroup lib * @brief Initialize libnfc. * This function must be called before calling any other libnfc function @@ -115,6 +173,9 @@ void nfc_init(nfc_context **context) { *context = nfc_context_new(); + + if (!nfc_drivers) + nfc_drivers_init(); } /** @ingroup lib @@ -160,14 +221,15 @@ nfc_open(nfc_context *context, const nfc_connstring connstring) } // Search through the device list for an available device - const struct nfc_driver *ndr; - const struct nfc_driver **pndr = nfc_drivers; - while ((ndr = *pndr)) { + const struct nfc_driver_list *pndl = nfc_drivers; + while (pndl) { + const struct nfc_driver *ndr = pndl->driver; + // Specific device is requested: using device description if (0 != strncmp(ndr->name, ncs, strlen(ndr->name))) { // Check if connstring driver is usb -> accept any driver *_usb if ((0 != strncmp("usb", ncs, strlen("usb"))) || 0 != strncmp("_usb", ndr->name + (strlen(ndr->name) - 4), 4)) { - pndr++; + pndl = pndl->next; continue; } } @@ -177,7 +239,7 @@ nfc_open(nfc_context *context, const nfc_connstring connstring) if (pnd == NULL) { if (0 == strncmp("usb", ncs, strlen("usb"))) { // We've to test the other usb drivers before giving up - pndr++; + pndl = pndl->next; continue; } log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open \"%s\".", ncs); @@ -226,8 +288,6 @@ size_t nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len) { size_t device_found = 0; - const struct nfc_driver *ndr; - const struct nfc_driver **pndr = nfc_drivers; // Load manually configured devices (from config file and env variables) // TODO From env var... @@ -272,7 +332,9 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_ // Device auto-detection if (context->allow_autoscan) { - while ((ndr = *pndr)) { + const struct nfc_driver_list *pndl = nfc_drivers; + while (pndl) { + const struct nfc_driver *ndr = pndl->driver; size_t _device_found = 0; if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) { _device_found = ndr->scan(context, connstrings + (device_found), connstrings_len - (device_found)); @@ -283,7 +345,7 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_ break; } } // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE - pndr++; + pndl = pndl->next; } } else if (context->user_defined_device_count == 0) { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: %s" , "user must specify device(s) manually when autoscan is disabled");