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:
parent
8127a2ca63
commit
225094e2c8
4 changed files with 98 additions and 56 deletions
|
@ -42,6 +42,11 @@ typedef struct nfc_context nfc_context;
|
||||||
*/
|
*/
|
||||||
typedef struct nfc_device nfc_device;
|
typedef struct nfc_device nfc_device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NFC device driver
|
||||||
|
*/
|
||||||
|
typedef struct nfc_driver nfc_driver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection string
|
* Connection string
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -79,6 +79,7 @@ extern "C" {
|
||||||
/* Library initialization/deinitialization */
|
/* Library initialization/deinitialization */
|
||||||
NFC_EXPORT void nfc_init(nfc_context **context) ATTRIBUTE_NONNULL(1);
|
NFC_EXPORT void nfc_init(nfc_context **context) ATTRIBUTE_NONNULL(1);
|
||||||
NFC_EXPORT void nfc_exit(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 Device/Hardware manipulation */
|
||||||
NFC_EXPORT nfc_device *nfc_open(nfc_context *context, const nfc_connstring connstring) ATTRIBUTE_NONNULL(1);
|
NFC_EXPORT nfc_device *nfc_open(nfc_context *context, const nfc_connstring connstring) ATTRIBUTE_NONNULL(1);
|
||||||
|
|
|
@ -29,32 +29,6 @@
|
||||||
|
|
||||||
# include <nfc/nfc-types.h>
|
# include <nfc/nfc-types.h>
|
||||||
|
|
||||||
# if defined (DRIVER_ACR122_PCSC_ENABLED)
|
extern const struct nfc_driver_list* nfc_drivers;
|
||||||
# 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[];
|
|
||||||
|
|
||||||
#endif // __NFC_DRIVERS_H__
|
#endif // __NFC_DRIVERS_H__
|
||||||
|
|
120
libnfc/nfc.c
120
libnfc/nfc.c
|
@ -81,31 +81,89 @@
|
||||||
#include "target-subr.h"
|
#include "target-subr.h"
|
||||||
#include "drivers.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_CATEGORY "libnfc.general"
|
||||||
#define LOG_GROUP NFC_LOG_GROUP_GENERAL
|
#define LOG_GROUP NFC_LOG_GROUP_GENERAL
|
||||||
|
|
||||||
const struct nfc_driver *nfc_drivers[] = {
|
struct nfc_driver_list
|
||||||
# if defined (DRIVER_PN53X_USB_ENABLED)
|
{
|
||||||
&pn53x_usb_driver,
|
const struct nfc_driver_list *next;
|
||||||
# endif /* DRIVER_PN53X_USB_ENABLED */
|
const struct nfc_driver *driver;
|
||||||
# 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
/** @ingroup lib
|
||||||
* @brief Initialize libnfc.
|
* @brief Initialize libnfc.
|
||||||
* This function must be called before calling any other libnfc function
|
* This function must be called before calling any other libnfc function
|
||||||
|
@ -115,6 +173,9 @@ void
|
||||||
nfc_init(nfc_context **context)
|
nfc_init(nfc_context **context)
|
||||||
{
|
{
|
||||||
*context = nfc_context_new();
|
*context = nfc_context_new();
|
||||||
|
|
||||||
|
if (!nfc_drivers)
|
||||||
|
nfc_drivers_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @ingroup lib
|
/** @ingroup lib
|
||||||
|
@ -160,14 +221,15 @@ nfc_open(nfc_context *context, const nfc_connstring connstring)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search through the device list for an available device
|
// Search through the device list for an available device
|
||||||
const struct nfc_driver *ndr;
|
const struct nfc_driver_list *pndl = nfc_drivers;
|
||||||
const struct nfc_driver **pndr = nfc_drivers;
|
while (pndl) {
|
||||||
while ((ndr = *pndr)) {
|
const struct nfc_driver *ndr = pndl->driver;
|
||||||
|
|
||||||
// Specific device is requested: using device description
|
// Specific device is requested: using device description
|
||||||
if (0 != strncmp(ndr->name, ncs, strlen(ndr->name))) {
|
if (0 != strncmp(ndr->name, ncs, strlen(ndr->name))) {
|
||||||
// Check if connstring driver is usb -> accept any driver *_usb
|
// 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)) {
|
if ((0 != strncmp("usb", ncs, strlen("usb"))) || 0 != strncmp("_usb", ndr->name + (strlen(ndr->name) - 4), 4)) {
|
||||||
pndr++;
|
pndl = pndl->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +239,7 @@ nfc_open(nfc_context *context, const nfc_connstring connstring)
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
if (0 == strncmp("usb", ncs, strlen("usb"))) {
|
if (0 == strncmp("usb", ncs, strlen("usb"))) {
|
||||||
// We've to test the other usb drivers before giving up
|
// We've to test the other usb drivers before giving up
|
||||||
pndr++;
|
pndl = pndl->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open \"%s\".", ncs);
|
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)
|
nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
|
||||||
{
|
{
|
||||||
size_t device_found = 0;
|
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)
|
// Load manually configured devices (from config file and env variables)
|
||||||
// TODO From env var...
|
// TODO From env var...
|
||||||
|
@ -272,7 +332,9 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
|
||||||
|
|
||||||
// Device auto-detection
|
// Device auto-detection
|
||||||
if (context->allow_autoscan) {
|
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;
|
size_t _device_found = 0;
|
||||||
if ((ndr->scan_type == NOT_INTRUSIVE) || ((context->allow_intrusive_scan) && (ndr->scan_type == INTRUSIVE))) {
|
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));
|
_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;
|
break;
|
||||||
}
|
}
|
||||||
} // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE
|
} // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE
|
||||||
pndr++;
|
pndl = pndl->next;
|
||||||
}
|
}
|
||||||
} else if (context->user_defined_device_count == 0) {
|
} 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");
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: %s" , "user must specify device(s) manually when autoscan is disabled");
|
||||||
|
|
Loading…
Reference in a new issue