Import code to load configuration from file.
WARNING: This commit do not contains a fully cleaned code: - Only nfc-list have been tested - Some -commented- code is not used ATM - Some printf-as-debug remain in this commit ... but that a bit usable so... happy hacking ;-)
This commit is contained in:
parent
3ee77eb79e
commit
7963fdfc3b
9 changed files with 231 additions and 36 deletions
|
@ -63,7 +63,7 @@ extern "C" {
|
||||||
# endif // __cplusplus
|
# endif // __cplusplus
|
||||||
|
|
||||||
/* Library initialization/deinitialization */
|
/* Library initialization/deinitialization */
|
||||||
NFC_EXPORT void nfc_init(nfc_context *context);
|
NFC_EXPORT void nfc_init(nfc_context **context);
|
||||||
NFC_EXPORT void nfc_exit(nfc_context *context);
|
NFC_EXPORT void nfc_exit(nfc_context *context);
|
||||||
|
|
||||||
/* NFC Device/Hardware manipulation */
|
/* NFC Device/Hardware manipulation */
|
||||||
|
|
8
libnfc.conf.sample
Normal file
8
libnfc.conf.sample
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Allow device auto-detection (default: true)
|
||||||
|
# Note: if this auto-detection is disable, user have to set manually a device
|
||||||
|
# configuration using file or environnement variable
|
||||||
|
#allow_autoscan = true
|
||||||
|
|
||||||
|
# Allow intrusive auto-detection (default: false)
|
||||||
|
# Warning: intrusive auto-detection can seriously disturb other devices
|
||||||
|
#allow_intrusive_autoscan = false
|
|
@ -4,6 +4,7 @@ SUBDIRS = chips buses drivers .
|
||||||
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)
|
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
|
conf.h \
|
||||||
drivers.h \
|
drivers.h \
|
||||||
iso7816.h \
|
iso7816.h \
|
||||||
log.h \
|
log.h \
|
||||||
|
@ -13,6 +14,7 @@ noinst_HEADERS = \
|
||||||
|
|
||||||
lib_LTLIBRARIES = libnfc.la
|
lib_LTLIBRARIES = libnfc.la
|
||||||
libnfc_la_SOURCES = \
|
libnfc_la_SOURCES = \
|
||||||
|
conf.c \
|
||||||
iso14443-subr.c \
|
iso14443-subr.c \
|
||||||
mirror-subr.c \
|
mirror-subr.c \
|
||||||
nfc.c \
|
nfc.c \
|
||||||
|
|
131
libnfc/conf.c
Normal file
131
libnfc/conf.c
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (C) 2012 Romuald Conty
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <nfc/nfc.h>
|
||||||
|
#include "nfc-internal.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#define LOG_CATEGORY "libnfc.config"
|
||||||
|
|
||||||
|
#define LIBNFC_SYSCONFDIR "/etc/nfc"
|
||||||
|
#define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
|
||||||
|
#define LIBNFC_DEVICECONFDIR LIBNFC_SYSCONFDIR"/devices.d"
|
||||||
|
|
||||||
|
|
||||||
|
bool conf_parse_file(const char* filename, void (*conf_keyvalue)(void* data, const char* key, const char* value), void* data)
|
||||||
|
{
|
||||||
|
FILE *f = fopen (filename, "r");
|
||||||
|
if (!f) {
|
||||||
|
perror ("fopen");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char line[BUFSIZ];
|
||||||
|
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");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t nmatch = preg.re_nsub + 1;
|
||||||
|
regmatch_t *pmatch = malloc (sizeof (*pmatch) * nmatch);
|
||||||
|
if(!pmatch) {
|
||||||
|
perror ("malloc");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lineno = 0;
|
||||||
|
while (fgets(line, BUFSIZ, f) != NULL) {
|
||||||
|
lineno++;
|
||||||
|
switch(line[0]) {
|
||||||
|
case '#':
|
||||||
|
case '\n':
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
int match;
|
||||||
|
if ((match = regexec (&preg, line, nmatch, pmatch, 0)) == 0) {
|
||||||
|
const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so;
|
||||||
|
const off_t value_pmatch = pmatch[3].rm_eo!=-1?3:4;
|
||||||
|
const size_t value_size = pmatch[value_pmatch].rm_eo - pmatch[value_pmatch].rm_so;
|
||||||
|
char key[key_size+1];
|
||||||
|
char value[value_size+1];
|
||||||
|
strncpy(key, line+(pmatch[1].rm_so), key_size); key[key_size]='\0';
|
||||||
|
strncpy(value, line+(pmatch[value_pmatch].rm_so), value_size); value[value_size]='\0';
|
||||||
|
conf_keyvalue(data, key, value);
|
||||||
|
} else {
|
||||||
|
log_put( LOG_CATEGORY, NFC_PRIORITY_TRACE, "parse error on line #%d: %s", lineno, line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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 {
|
||||||
|
log_put( LOG_CATEGORY, NFC_PRIORITY_INFO, "unknown key in config line: %s = %s", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
conf_load(nfc_context *context)
|
||||||
|
{
|
||||||
|
conf_parse_file(LIBNFC_CONFFILE, conf_keyvalue_context, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
DIR *d = opendir(LIBNFC_DEVICECONFDIR);
|
||||||
|
if (!d) {
|
||||||
|
perror ("opendir");
|
||||||
|
} else {
|
||||||
|
struct dirent* de;
|
||||||
|
while (de = readdir(d)) {
|
||||||
|
if (de->d_name[0]!='.') {
|
||||||
|
printf ("\t%s\n", de->d_name);
|
||||||
|
char filename[BUFSIZ] = LIBNFC_DEVICECONFDIR"/";
|
||||||
|
strcat (filename, de->d_name);
|
||||||
|
struct stat s;
|
||||||
|
if (stat(filename, &s) == -1) {
|
||||||
|
perror("stat");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(S_ISREG(s.st_mode)) {
|
||||||
|
nfc_open_from_file (filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
19
libnfc/conf.h
Normal file
19
libnfc/conf.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (C) 2012 Romuald Conty
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
void conf_load(nfc_context *context);
|
||||||
|
|
|
@ -24,20 +24,31 @@
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
#include "nfc-internal.h"
|
#include "nfc-internal.h"
|
||||||
|
#include "conf.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static bool
|
void
|
||||||
string_as_boolean(const char* s)
|
string_as_boolean(const char* s, bool *value)
|
||||||
{
|
{
|
||||||
if ((s) && (
|
if (s) {
|
||||||
(strcmp(s, "yes") == 0) ||
|
if (!(*value)) {
|
||||||
|
if ( (strcmp(s, "yes") == 0) ||
|
||||||
(strcmp(s, "true") == 0) ||
|
(strcmp(s, "true") == 0) ||
|
||||||
(strcmp(s, "1") == 0))) {
|
(strcmp(s, "1") == 0) ) {
|
||||||
return true;
|
*value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( (strcmp(s, "no") == 0) ||
|
||||||
|
(strcmp(s, "false") == 0) ||
|
||||||
|
(strcmp(s, "0") == 0) ) {
|
||||||
|
*value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nfc_context *
|
nfc_context *
|
||||||
|
@ -49,10 +60,20 @@ nfc_context_new(void)
|
||||||
err(EXIT_FAILURE, "nfc_context_new: malloc");
|
err(EXIT_FAILURE, "nfc_context_new: malloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default context values
|
||||||
|
res->allow_autoscan = true;
|
||||||
|
res->allow_intrusive_scan = false;
|
||||||
|
|
||||||
|
// Load options from configuration file (ie. /etc/nfc/libnfc.conf)
|
||||||
|
conf_load(res);
|
||||||
|
|
||||||
|
// Environment variables
|
||||||
// Load "intrusive scan" option
|
// Load "intrusive scan" option
|
||||||
// XXX: Load this option from configuration file too ?
|
|
||||||
char *envvar = getenv("LIBNFC_INTRUSIVE_SCAN");
|
char *envvar = getenv("LIBNFC_INTRUSIVE_SCAN");
|
||||||
res->allow_intrusive_scan = string_as_boolean(envvar);
|
string_as_boolean(envvar, &(res->allow_intrusive_scan));
|
||||||
|
|
||||||
|
// Debug context state
|
||||||
|
log_put ("libnfc", NFC_PRIORITY_DEBUG, "allow_autoscan is set to %s", (res->allow_autoscan)?"true":"false");
|
||||||
log_put ("libnfc", NFC_PRIORITY_DEBUG, "allow_intrusive_scan is set to %s", (res->allow_intrusive_scan)?"true":"false");
|
log_put ("libnfc", NFC_PRIORITY_DEBUG, "allow_intrusive_scan is set to %s", (res->allow_intrusive_scan)?"true":"false");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,7 @@ struct nfc_driver {
|
||||||
* Struct which contains internal options, references, pointers, etc. used by library
|
* Struct which contains internal options, references, pointers, etc. used by library
|
||||||
*/
|
*/
|
||||||
struct nfc_context {
|
struct nfc_context {
|
||||||
|
bool allow_autoscan;
|
||||||
bool allow_intrusive_scan;
|
bool allow_intrusive_scan;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,6 +196,8 @@ struct nfc_device {
|
||||||
nfc_device *nfc_device_new(const nfc_connstring connstring);
|
nfc_device *nfc_device_new(const nfc_connstring connstring);
|
||||||
void nfc_device_free(nfc_device *dev);
|
void nfc_device_free(nfc_device *dev);
|
||||||
|
|
||||||
|
void string_as_boolean(const char* s, bool *value);
|
||||||
|
|
||||||
void iso14443_cascade_uid(const uint8_t abtUID[], const size_t szUID, uint8_t *pbtCascadedUID, size_t *pszCascadedUID);
|
void iso14443_cascade_uid(const uint8_t abtUID[], const size_t szUID, uint8_t *pbtCascadedUID, size_t *pszCascadedUID);
|
||||||
|
|
||||||
void prepare_initiator_data(const nfc_modulation nm, uint8_t **ppbtInitiatorData, size_t *pszInitiatorData);
|
void prepare_initiator_data(const nfc_modulation nm, uint8_t **ppbtInitiatorData, size_t *pszInitiatorData);
|
||||||
|
|
22
libnfc/nfc.c
22
libnfc/nfc.c
|
@ -108,12 +108,16 @@ const struct nfc_driver *nfc_drivers[] = {
|
||||||
/** @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
|
||||||
* @param context Optional output location for context pointer
|
* @param context Output location for nfc_context
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nfc_init(nfc_context *context)
|
nfc_init(nfc_context **context)
|
||||||
{
|
{
|
||||||
(void) context;
|
if (!context) {
|
||||||
|
printf("Error: NULL context is not supported anymore, please fix your code.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
*context = nfc_context_new();
|
||||||
log_init();
|
log_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,9 +269,14 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
|
||||||
const struct nfc_driver *ndr;
|
const struct nfc_driver *ndr;
|
||||||
const struct nfc_driver **pndr = nfc_drivers;
|
const struct nfc_driver **pndr = nfc_drivers;
|
||||||
|
|
||||||
if (!context) context = nfc_context_new(); // Should we support NULL context ?
|
if (!context) {
|
||||||
// FIXME: Load device(s) from configuration file(s)
|
printf ("NULL context is not supported anymore! Please fix your code.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Load manually configured devices (from config file and env variables)
|
||||||
|
|
||||||
|
// Device auto-detection
|
||||||
|
if (context->allow_autoscan) {
|
||||||
while ((ndr = *pndr)) {
|
while ((ndr = *pndr)) {
|
||||||
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))) {
|
||||||
|
@ -281,7 +290,8 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
|
||||||
} // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE
|
} // scan_type is INTRUSIVE but not allowed or NOT_AVAILABLE
|
||||||
pndr++;
|
pndr++;
|
||||||
}
|
}
|
||||||
log_fini();
|
}
|
||||||
|
|
||||||
return device_found;
|
return device_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,8 @@ main(int argc, const char *argv[])
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
nfc_init(NULL);
|
nfc_context *context;
|
||||||
|
nfc_init(&context);
|
||||||
|
|
||||||
// Display libnfc version
|
// Display libnfc version
|
||||||
acLibnfcVersion = nfc_version();
|
acLibnfcVersion = nfc_version();
|
||||||
|
@ -97,7 +98,7 @@ main(int argc, const char *argv[])
|
||||||
|
|
||||||
/* Lazy way to open an NFC device */
|
/* Lazy way to open an NFC device */
|
||||||
#if 0
|
#if 0
|
||||||
pnd = nfc_open(NULL, NULL);
|
pnd = nfc_open(context, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 */
|
/* If specific device is wanted, i.e. an ARYGON device on /dev/ttyUSB0 */
|
||||||
|
@ -106,7 +107,7 @@ main(int argc, const char *argv[])
|
||||||
ndd.pcDriver = "ARYGON";
|
ndd.pcDriver = "ARYGON";
|
||||||
ndd.pcPort = "/dev/ttyUSB0";
|
ndd.pcPort = "/dev/ttyUSB0";
|
||||||
ndd.uiSpeed = 115200;
|
ndd.uiSpeed = 115200;
|
||||||
pnd = nfc_open(NULL, &ndd);
|
pnd = nfc_open(context, &ndd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If specific device is wanted, i.e. a SCL3711 on USB */
|
/* If specific device is wanted, i.e. a SCL3711 on USB */
|
||||||
|
@ -114,10 +115,10 @@ main(int argc, const char *argv[])
|
||||||
nfc_device_desc_t ndd;
|
nfc_device_desc_t ndd;
|
||||||
ndd.pcDriver = "PN533_USB";
|
ndd.pcDriver = "PN533_USB";
|
||||||
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
|
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
|
||||||
pnd = nfc_open(NULL, &ndd);
|
pnd = nfc_open(context, &ndd);
|
||||||
#endif
|
#endif
|
||||||
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
nfc_connstring connstrings[MAX_DEVICE_COUNT];
|
||||||
size_t szDeviceFound = nfc_list_devices(NULL, connstrings, MAX_DEVICE_COUNT);
|
size_t szDeviceFound = nfc_list_devices(context, connstrings, MAX_DEVICE_COUNT);
|
||||||
|
|
||||||
if (szDeviceFound == 0) {
|
if (szDeviceFound == 0) {
|
||||||
printf("No NFC device found.\n");
|
printf("No NFC device found.\n");
|
||||||
|
@ -125,7 +126,7 @@ main(int argc, const char *argv[])
|
||||||
|
|
||||||
for (i = 0; i < szDeviceFound; i++) {
|
for (i = 0; i < szDeviceFound; i++) {
|
||||||
nfc_target ant[MAX_TARGET_COUNT];
|
nfc_target ant[MAX_TARGET_COUNT];
|
||||||
pnd = nfc_open(NULL, connstrings[i]);
|
pnd = nfc_open(context, connstrings[i]);
|
||||||
|
|
||||||
if (pnd == NULL) {
|
if (pnd == NULL) {
|
||||||
ERR("Unable to open NFC device: %s", connstrings[i]);
|
ERR("Unable to open NFC device: %s", connstrings[i]);
|
||||||
|
|
Loading…
Reference in a new issue