diff --git a/NEWS b/NEWS index 03c19ad..dfb37e3 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,17 @@ New in TBD: +Configuration: + libnfc can now uses a configuration file for special setups, or features + activation. This file (/etc/nfc/libnfc.conf under GNU/Linux systems) already + support some keywords: + - "allow_autoscan" to enable/disable device auto-detection feature; + - "allow_intrusive_autoscan" to enable/disable intrusive auto-detection + (ie. serial port probing); + - "log_level" to select library verbosity; + - "device.name" and "device.connstring" to define a user device, + this is the recommended method if user have a not-easily detectable + device (ie. serial ones). + API Changes: * Types diff --git a/libnfc.conf.sample b/libnfc.conf.sample index c9ebd8f..691e310 100644 --- a/libnfc.conf.sample +++ b/libnfc.conf.sample @@ -11,3 +11,9 @@ # Valid log levels are (in order of verbosity): 0 (none), 1 (error), 2 (info), 3 (debug) # Note: if you set --enable-debug option, the default log level is "debug" #log_level = 1 + +# Manually set default device (no default) +# To set a default device, you must set both name and connstring for your device +# Note: if autoscan is enabled, default device will be the first device available is device list. +#device.name = "microBuilder.eu" +#device.connstring = "pn532_uart:/dev/ttyUSB0" diff --git a/libnfc/conf.c b/libnfc/conf.c index 4a10aa8..1e93f09 100644 --- a/libnfc/conf.c +++ b/libnfc/conf.c @@ -44,7 +44,7 @@ conf_parse_file(const char* filename, void (*conf_keyvalue)(void* data, const ch return false; } char line[BUFSIZ]; - const char *str_regex = "^[[:space:]]*([[:alnum:]_]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$"; + const char *str_regex = "^[[:space:]]*([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$"; regex_t preg; if(regcomp (&preg, str_regex, REG_EXTENDED|REG_NOTEOL) != 0) { printf ("regcomp error\n"); @@ -89,18 +89,36 @@ static void conf_keyvalue_context(void *data, const char* key, const char* value) { nfc_context *context = (nfc_context*)data; - printf ("key: [%s], value: [%s]\n", key, value); + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "key: [%s], value: [%s]", key, value); if (strcmp(key, "allow_autoscan") == 0) { string_as_boolean(value, &(context->allow_autoscan)); } else if (strcmp(key, "allow_intrusive_scan") == 0) { string_as_boolean(value, &(context->allow_intrusive_scan)); } else if (strcmp(key, "log_level") == 0) { context->log_level = atoi(value); + } else if (strcmp(key, "device.name") == 0) { + if ((context->user_defined_device_count == 0) || strcmp(context->user_defined_devices[context->user_defined_device_count-1].name, "") != 0) { + context->user_defined_device_count++; + } + strcpy(context->user_defined_devices[context->user_defined_device_count-1].name, value); + } else if (strcmp(key, "device.connstring") == 0) { + if ((context->user_defined_device_count == 0) || strcmp(context->user_defined_devices[context->user_defined_device_count-1].connstring, "") != 0) { + context->user_defined_device_count++; + } + strcpy(context->user_defined_devices[context->user_defined_device_count-1].connstring, value); } else { log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "unknown key in config line: %s = %s", key, value); } } +static void +conf_keyvalue_device(void *data, const char* key, const char* value) +{ + char newkey[BUFSIZ]; + sprintf(newkey, "device.%s", key); + conf_keyvalue_context(data, newkey, value); +} + void conf_load(nfc_context *context) { diff --git a/libnfc/nfc-internal.c b/libnfc/nfc-internal.c index f4c2e93..635e2f4 100644 --- a/libnfc/nfc-internal.c +++ b/libnfc/nfc-internal.c @@ -73,6 +73,13 @@ nfc_context_new(void) res->log_level = 1; #endif + // Clear user defined devices array + for (int i=0; iuser_defined_devices[i].name, ""); + strcpy(res->user_defined_devices[i].connstring, ""); + } + res->user_defined_device_count = 0; + // Load options from configuration file (ie. /etc/nfc/libnfc.conf) conf_load(res); @@ -87,16 +94,29 @@ nfc_context_new(void) res->log_level = atoi(envvar); } + // Initialize log before use it... + log_init(res); + // Debug context state +#if defined DEBUG log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_NONE, "log_level is set to %"PRIu32, res->log_level); +#else + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "log_level is set to %"PRIu32, res->log_level); +#endif log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "allow_autoscan is set to %s", (res->allow_autoscan)?"true":"false"); log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "allow_intrusive_scan is set to %s", (res->allow_intrusive_scan)?"true":"false"); + + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "%d device(s) defined by user", res->user_defined_device_count); + for(uint32_t i=0; iuser_defined_device_count; i++) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, " #%d name: \"%s\", connstring: \"%s\"", i, res->user_defined_devices[i].name, res->user_defined_devices[i].connstring); + } return res; } void nfc_context_free(nfc_context *context) { + log_exit(); free(context); } diff --git a/libnfc/nfc-internal.h b/libnfc/nfc-internal.h index 8a061ea..0bda86d 100644 --- a/libnfc/nfc-internal.h +++ b/libnfc/nfc-internal.h @@ -152,6 +152,13 @@ struct nfc_driver { # define DEVICE_NAME_LENGTH 256 # define DEVICE_PORT_LENGTH 64 +#define MAX_USER_DEFINED_DEVICES 4 + +struct nfc_user_defined_device { + char name[DEVICE_NAME_LENGTH]; + nfc_connstring connstring; +}; + /** * @struct nfc_context * @brief NFC library context @@ -160,7 +167,9 @@ struct nfc_driver { struct nfc_context { bool allow_autoscan; bool allow_intrusive_scan; - int log_level; + uint32_t log_level; + struct nfc_user_defined_device user_defined_devices[MAX_USER_DEFINED_DEVICES]; + unsigned int user_defined_device_count; }; nfc_context *nfc_context_new(void); @@ -171,7 +180,7 @@ void nfc_context_free(nfc_context *context); * @brief NFC device information */ struct nfc_device { - nfc_context *context; + const nfc_context *context; const struct nfc_driver *driver; void *driver_data; void *chip_data; diff --git a/libnfc/nfc.c b/libnfc/nfc.c index aae7597..cb3aa1b 100644 --- a/libnfc/nfc.c +++ b/libnfc/nfc.c @@ -119,7 +119,6 @@ nfc_init(nfc_context **context) exit(EXIT_FAILURE); } *context = nfc_context_new(); - log_init(*context); } /** @ingroup lib @@ -131,7 +130,6 @@ void nfc_exit(nfc_context *context) { nfc_context_free(context); - log_exit(); } /** @ingroup dev @@ -222,7 +220,13 @@ nfc_open(nfc_context *context, const nfc_connstring connstring) log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Unable to open \"%s\".", ncs); return pnd; } - + for (uint32_t i=0; i>context->user_defined_device_count; i++) { + if (strcmp(ncs, context->user_defined_devices[i].connstring) == 0) { + // This is a device sets by user, we use the device name given by user + strcpy(pnd->name, context->user_defined_devices[i].name); + break; + } + } log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "\"%s\" (%s) has been claimed.", pnd->name, pnd->connstring); return pnd; } @@ -266,10 +270,18 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_ const struct nfc_driver **pndr = nfc_drivers; if (!context) { - printf ("NULL context is not supported anymore! Please fix your code."); + printf ("NULL context is not supported anymore! Please fix your code.\n"); + exit(EXIT_FAILURE); } - // TODO Load manually configured devices (from config file and env variables) + // Load manually configured devices (from config file and env variables) + // TODO From env var... + for (uint32_t i=0; iuser_defined_device_count; i++) { + strcpy((char*)(connstrings+device_found), context->user_defined_devices[i].connstring); + device_found++; + if(device_found >= connstrings_len) + return device_found; + } // Device auto-detection if (context->allow_autoscan) { @@ -286,6 +298,8 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_ } // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE pndr++; } + } else if (context->user_defined_device_count) { + log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_INFO, "Warning: autoscan have been disabled but no other devices have bet set."); } return device_found;