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.
This commit is contained in:
lego 2013-02-01 14:40:40 +02:00
parent 8127a2ca63
commit 225094e2c8
4 changed files with 98 additions and 56 deletions

View file

@ -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
*/

View file

@ -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);

View file

@ -29,32 +29,6 @@
# include <nfc/nfc-types.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 DRIVERS_MAX_DEVICES 16
extern const struct nfc_driver *nfc_drivers[];
extern const struct nfc_driver_list* nfc_drivers;
#endif // __NFC_DRIVERS_H__

View file

@ -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");