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
|
||||
|
||||
/* 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 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)
|
||||
|
||||
noinst_HEADERS = \
|
||||
conf.h \
|
||||
drivers.h \
|
||||
iso7816.h \
|
||||
log.h \
|
||||
|
@ -13,6 +14,7 @@ noinst_HEADERS = \
|
|||
|
||||
lib_LTLIBRARIES = libnfc.la
|
||||
libnfc_la_SOURCES = \
|
||||
conf.c \
|
||||
iso14443-subr.c \
|
||||
mirror-subr.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-internal.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool
|
||||
string_as_boolean(const char* s)
|
||||
void
|
||||
string_as_boolean(const char* s, bool *value)
|
||||
{
|
||||
if ((s) && (
|
||||
(strcmp(s, "yes") == 0) ||
|
||||
if (s) {
|
||||
if (!(*value)) {
|
||||
if ( (strcmp(s, "yes") == 0) ||
|
||||
(strcmp(s, "true") == 0) ||
|
||||
(strcmp(s, "1") == 0))) {
|
||||
return true;
|
||||
(strcmp(s, "1") == 0) ) {
|
||||
*value = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ( (strcmp(s, "no") == 0) ||
|
||||
(strcmp(s, "false") == 0) ||
|
||||
(strcmp(s, "0") == 0) ) {
|
||||
*value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nfc_context *
|
||||
|
@ -49,10 +60,20 @@ nfc_context_new(void)
|
|||
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
|
||||
// XXX: Load this option from configuration file too ?
|
||||
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");
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -158,6 +158,7 @@ struct nfc_driver {
|
|||
* Struct which contains internal options, references, pointers, etc. used by library
|
||||
*/
|
||||
struct nfc_context {
|
||||
bool allow_autoscan;
|
||||
bool allow_intrusive_scan;
|
||||
};
|
||||
|
||||
|
@ -195,6 +196,8 @@ struct nfc_device {
|
|||
nfc_device *nfc_device_new(const nfc_connstring connstring);
|
||||
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 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
|
||||
* @brief Initialize libnfc.
|
||||
* 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
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -265,9 +269,14 @@ nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], const size_
|
|||
const struct nfc_driver *ndr;
|
||||
const struct nfc_driver **pndr = nfc_drivers;
|
||||
|
||||
if (!context) context = nfc_context_new(); // Should we support NULL context ?
|
||||
// FIXME: Load device(s) from configuration file(s)
|
||||
if (!context) {
|
||||
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)) {
|
||||
size_t _device_found = 0;
|
||||
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
|
||||
pndr++;
|
||||
}
|
||||
log_fini();
|
||||
}
|
||||
|
||||
return device_found;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,8 @@ main(int argc, const char *argv[])
|
|||
bool verbose = false;
|
||||
int res = 0;
|
||||
|
||||
nfc_init(NULL);
|
||||
nfc_context *context;
|
||||
nfc_init(&context);
|
||||
|
||||
// Display libnfc version
|
||||
acLibnfcVersion = nfc_version();
|
||||
|
@ -97,7 +98,7 @@ main(int argc, const char *argv[])
|
|||
|
||||
/* Lazy way to open an NFC device */
|
||||
#if 0
|
||||
pnd = nfc_open(NULL, NULL);
|
||||
pnd = nfc_open(context, NULL);
|
||||
#endif
|
||||
|
||||
/* 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.pcPort = "/dev/ttyUSB0";
|
||||
ndd.uiSpeed = 115200;
|
||||
pnd = nfc_open(NULL, &ndd);
|
||||
pnd = nfc_open(context, &ndd);
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
ndd.pcDriver = "PN533_USB";
|
||||
strcpy(ndd.acDevice, "SCM Micro / SCL3711-NFC&RW");
|
||||
pnd = nfc_open(NULL, &ndd);
|
||||
pnd = nfc_open(context, &ndd);
|
||||
#endif
|
||||
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) {
|
||||
printf("No NFC device found.\n");
|
||||
|
@ -125,7 +126,7 @@ main(int argc, const char *argv[])
|
|||
|
||||
for (i = 0; i < szDeviceFound; i++) {
|
||||
nfc_target ant[MAX_TARGET_COUNT];
|
||||
pnd = nfc_open(NULL, connstrings[i]);
|
||||
pnd = nfc_open(context, connstrings[i]);
|
||||
|
||||
if (pnd == NULL) {
|
||||
ERR("Unable to open NFC device: %s", connstrings[i]);
|
||||
|
|
Loading…
Reference in a new issue