mirror of
https://github.com/mysensors/MySensors.git
synced 2026-02-19 17:11:28 +01:00
Linux: Use config file for gateway settings (#1061)
- The following settings can be use on the config file:
- verbose=[debug,info,notice,warn,err] - Logging verbosity.
- log_file[0|1] - Enable logging to a file.
- log_filepath=(FILE) - Log file path.
- log_pipe=[0|1] - Enable logging to a named pipe(aka fifo).
Use this option to view your gateway's log messages from the
log_pipe_file (defined below).
To do so, run the following command on another terminal:
- $ cat "log_pipe_file"
- log_pipe_file=(FILE)
- syslog=[0|1] - Enable logging to syslog.
- eeprom_file=[/etc/mysensors.eeprom]
- eeprom_size=[1024]
- Change some mysgw parameters:
- Added:
- -q, --quiet: for quiet mode, disable log messages written to the
terminal.
- Removed:
- -d, --debug: removed, log messages are now enabled by default.
- Replaced:
- -b, --background: replaced by --daemon
- isatty() is no longer used, log messages by default are printed to
stderr unless the gateway is started with --quiet (#1022)
- MY_LINUX_CONFIG_FILE: no longer holds the path to the eeprom file,
but to the configuration file
This commit is contained in:
committed by
Mikael Falkvidd
parent
06f8d2b7e5
commit
2175c993ef
@@ -1873,7 +1873,7 @@
|
||||
* @note For now the configuration file is only used to store the emulated eeprom state.
|
||||
*/
|
||||
#ifndef MY_LINUX_CONFIG_FILE
|
||||
#define MY_LINUX_CONFIG_FILE "/etc/mysensors.dat"
|
||||
#define MY_LINUX_CONFIG_FILE "/etc/mysensors.conf"
|
||||
#endif
|
||||
/** @}*/ // End of LinuxSettingGrpPub group
|
||||
/** @}*/ // End of PlatformSettingGrpPub group
|
||||
|
||||
2
configure
vendored
2
configure
vendored
@@ -37,7 +37,7 @@ Installation options:
|
||||
|
||||
MySensors options:
|
||||
--my-debug=[enable|disable] Enables or disables MySensors core debugging. [enable]
|
||||
--my-config-file=<FILE> Config file path. [/etc/mysensors.dat]
|
||||
--my-config-file=<FILE> Config file path. [/etc/mysensors.conf]
|
||||
--my-gateway=[none|ethernet|serial|mqtt]
|
||||
Set the protocol used to communicate with the controller. [ethernet]
|
||||
--my-node-id=<ID> Disable gateway feature and run as a node with the specified id.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -26,46 +26,8 @@
|
||||
#include "log.h"
|
||||
#include "SoftEeprom.h"
|
||||
|
||||
SoftEeprom::SoftEeprom(const char *fileName, size_t length)
|
||||
SoftEeprom::SoftEeprom() : _length(0), _fileName(NULL), _values(NULL)
|
||||
{
|
||||
struct stat fileInfo;
|
||||
|
||||
_fileName = strdup(fileName);
|
||||
if (_fileName == NULL) {
|
||||
logError("Error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_length = length;
|
||||
_values = new uint8_t[_length];
|
||||
for (size_t i = 0; i < _length; ++i) {
|
||||
_values[i] = 0xFF;
|
||||
}
|
||||
|
||||
if (stat(_fileName, &fileInfo) != 0) {
|
||||
//File does not exist. Create it.
|
||||
logInfo("Config file %s does not exist, creating new config file.\n", _fileName);
|
||||
std::ofstream myFile(_fileName, std::ios::out | std::ios::binary);
|
||||
if (!myFile) {
|
||||
logError("Unable to create config file %s.\n", _fileName);
|
||||
exit(1);
|
||||
}
|
||||
myFile.write((const char*)_values, _length);
|
||||
myFile.close();
|
||||
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
|
||||
logError("Config file %s is not the correct size of %zu. Please remove the file and a new one will be created.\n",
|
||||
_fileName, _length);
|
||||
exit(1);
|
||||
} else {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
logError("Unable to open config to file %s for reading.\n", _fileName);
|
||||
exit(1);
|
||||
}
|
||||
myFile.read((char*)_values, _length);
|
||||
myFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
SoftEeprom::SoftEeprom(const SoftEeprom& other)
|
||||
@@ -81,8 +43,63 @@ SoftEeprom::SoftEeprom(const SoftEeprom& other)
|
||||
|
||||
SoftEeprom::~SoftEeprom()
|
||||
{
|
||||
delete[] _values;
|
||||
free(_fileName);
|
||||
destroy();
|
||||
}
|
||||
|
||||
int SoftEeprom::init(const char *fileName, size_t length)
|
||||
{
|
||||
struct stat fileInfo;
|
||||
|
||||
destroy();
|
||||
|
||||
_fileName = strdup(fileName);
|
||||
if (_fileName == NULL) {
|
||||
logError("Error: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
_length = length;
|
||||
_values = new uint8_t[_length];
|
||||
for (size_t i = 0; i < _length; ++i) {
|
||||
_values[i] = 0xFF;
|
||||
}
|
||||
|
||||
if (stat(_fileName, &fileInfo) != 0) {
|
||||
//File does not exist. Create it.
|
||||
logInfo("EEPROM file %s does not exist, creating new file.\n", _fileName);
|
||||
std::ofstream myFile(_fileName, std::ios::out | std::ios::binary);
|
||||
if (!myFile) {
|
||||
logError("Unable to create config file %s.\n", _fileName);
|
||||
return -1;
|
||||
}
|
||||
myFile.write((const char*)_values, _length);
|
||||
myFile.close();
|
||||
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
|
||||
logError("EEPROM file %s is not the correct size of %zu. Please remove the file and a new one will be created.\n",
|
||||
_fileName, _length);
|
||||
return -1;
|
||||
} else {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
logError("Unable to open EEPROM file %s for reading.\n", _fileName);
|
||||
return -1;
|
||||
}
|
||||
myFile.read((char*)_values, _length);
|
||||
myFile.close();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SoftEeprom::destroy()
|
||||
{
|
||||
if (_values) {
|
||||
delete[] _values;
|
||||
}
|
||||
if (_fileName) {
|
||||
free(_fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void SoftEeprom::readBlock(void* buf, void* addr, size_t length)
|
||||
@@ -90,7 +107,7 @@ void SoftEeprom::readBlock(void* buf, void* addr, size_t length)
|
||||
static bool config_to_mem = false;
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (!config_to_mem) {
|
||||
if (!config_to_mem && length) {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
@@ -144,6 +161,9 @@ void SoftEeprom::writeByte(int addr, uint8_t value)
|
||||
SoftEeprom& SoftEeprom::operator=(const SoftEeprom& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
delete[] _values;
|
||||
free(_fileName);
|
||||
|
||||
_fileName = strdup(other._fileName);
|
||||
|
||||
_length = other._length;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
/**
|
||||
* @brief SoftEeprom constructor.
|
||||
*/
|
||||
SoftEeprom(const char *fileName, size_t length);
|
||||
SoftEeprom();
|
||||
/**
|
||||
* @brief SoftEeprom copy constructor.
|
||||
*/
|
||||
@@ -46,6 +46,19 @@ public:
|
||||
* @brief SoftEeprom destructor.
|
||||
*/
|
||||
~SoftEeprom();
|
||||
/**
|
||||
* @brief Initializes the eeprom class.
|
||||
*
|
||||
* @param fileName filepath where the data is saved.
|
||||
* @param length eeprom size in bytes.
|
||||
* @return 0 if SUCCESS or -1 if FAILURE.
|
||||
*/
|
||||
int init(const char *fileName, size_t length);
|
||||
/**
|
||||
* @brief Clear all allocated memory variables.
|
||||
*
|
||||
*/
|
||||
void destroy();
|
||||
/**
|
||||
* @brief Read a block of bytes from eeprom.
|
||||
*
|
||||
|
||||
249
drivers/Linux/config.c
Normal file
249
drivers/Linux/config.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* Based on mosquitto project, Copyright (c) 2012 Roger Light <roger@atchoo.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "log.h"
|
||||
|
||||
static int _config_create(const char *config_file);
|
||||
static int _config_parse_int(char *token, const char *name, int *value);
|
||||
static int _config_parse_string(char *token, const char *name, char **value);
|
||||
|
||||
int config_parse(const char *config_file)
|
||||
{
|
||||
FILE *fptr;
|
||||
char buf[1024];
|
||||
struct stat fileInfo;
|
||||
|
||||
if (stat(config_file, &fileInfo) != 0) {
|
||||
//File does not exist. Create it.
|
||||
logInfo("Config file %s does not exist, creating new file.\n", config_file);
|
||||
_config_create(config_file);
|
||||
}
|
||||
|
||||
fptr = fopen(config_file, "rt");
|
||||
if (!fptr) {
|
||||
logError("Error opening config file \"%s\".\n", config_file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
conf.verbose = 4;
|
||||
conf.log_pipe = 0;
|
||||
conf.log_pipe_file = NULL;
|
||||
conf.syslog = 0;
|
||||
conf.eeprom_file = NULL;
|
||||
conf.eeprom_size = 1024;
|
||||
|
||||
while (fgets(buf, 1024, fptr)) {
|
||||
if (buf[0] != '#' && buf[0] != 10 && buf[0] != 13) {
|
||||
while (buf[strlen(buf)-1] == 10 || buf[strlen(buf)-1] == 13) {
|
||||
buf[strlen(buf)-1] = 0;
|
||||
}
|
||||
|
||||
if (!strncmp(buf, "verbose=", 8)) {
|
||||
char *verbose = NULL;
|
||||
if (_config_parse_string(&(buf[8]), "verbose", &verbose)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
} else {
|
||||
if (!strncmp(verbose, "err", 3)) {
|
||||
conf.verbose = 3;
|
||||
} else if (!strncmp(verbose, "warn", 4)) {
|
||||
conf.verbose = 4;
|
||||
} else if (!strncmp(verbose, "notice", 6)) {
|
||||
conf.verbose = 5;
|
||||
} else if (!strncmp(verbose, "info", 4)) {
|
||||
conf.verbose = 6;
|
||||
} else if (!strncmp(verbose, "debug", 5)) {
|
||||
conf.verbose = 7;
|
||||
} else {
|
||||
logError("Invalid value for verbose in configuration.\n");
|
||||
fclose(fptr);
|
||||
free(verbose);
|
||||
return -1;
|
||||
}
|
||||
free(verbose);
|
||||
}
|
||||
} else if (!strncmp(buf, "log_file=", 9)) {
|
||||
if (_config_parse_int(&(buf[9]), "log_file", &conf.log_file)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
} else {
|
||||
if (conf.log_file != 0 && conf.log_file != 1) {
|
||||
logError("log_file must be 1 or 0 in configuration.\n");
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(buf, "log_filepath=", 13)) {
|
||||
if (_config_parse_string(&(buf[13]), "log_filepath", &conf.log_filepath)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
} else if (!strncmp(buf, "log_pipe=", 9)) {
|
||||
if (_config_parse_int(&(buf[9]), "log_pipe", &conf.log_pipe)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
} else {
|
||||
if (conf.log_pipe != 0 && conf.log_pipe != 1) {
|
||||
logError("log_pipe must be 1 or 0 in configuration.\n");
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(buf, "log_pipe_file=", 14)) {
|
||||
if (_config_parse_string(&(buf[14]), "log_pipe_file", &conf.log_pipe_file)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
} else if (!strncmp(buf, "syslog=", 7)) {
|
||||
if (_config_parse_int(&(buf[7]), "syslog", &conf.syslog)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
} else {
|
||||
if (conf.syslog != 0 && conf.syslog != 1) {
|
||||
logError("syslog must be 1 or 0 in configuration.\n");
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(buf, "eeprom_file=", 12)) {
|
||||
if (_config_parse_string(&(buf[12]), "eeprom_file", &conf.eeprom_file)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
} else if (!strncmp(buf, "eeprom_size=", 12)) {
|
||||
if (_config_parse_int(&(buf[12]), "eeprom_size", &conf.eeprom_size)) {
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
} else {
|
||||
if (conf.eeprom_size <= 0) {
|
||||
logError("eeprom_size value must be greater than 0 in configuration.\n");
|
||||
fclose(fptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logWarning("Unknown config option \"%s\".\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fptr);
|
||||
|
||||
if (!conf.eeprom_file) {
|
||||
logError("No eeprom_file found in configuration.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conf.log_file && !conf.log_filepath) {
|
||||
logError("log_filepath must be set if you enable log_file in configuration.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (conf.log_pipe && !conf.log_pipe_file) {
|
||||
logError("log_pipe_file must be set if you enable log_pipe in configuration.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void config_cleanup(void)
|
||||
{
|
||||
if (conf.eeprom_file) {
|
||||
free(conf.eeprom_file);
|
||||
}
|
||||
if (conf.log_pipe_file) {
|
||||
free(conf.log_pipe_file);
|
||||
}
|
||||
}
|
||||
|
||||
int _config_create(const char *config_file)
|
||||
{
|
||||
FILE *myFile;
|
||||
int ret;
|
||||
|
||||
const char default_conf[] = "# Logging verbosity: debug,info,notice,warn,err\n" \
|
||||
"verbose=debug\n" \
|
||||
"# Enable logging to a file.\n" \
|
||||
"log_file=0\n" \
|
||||
"# Log file path.\n" \
|
||||
"log_filepath=/tmp/mysgw.log\n" \
|
||||
"# Enable logging to a named pipe.\n" \
|
||||
"# Use this option to view your gateway's log messages\n" \
|
||||
"# from the log_pipe_file defined bellow.\n" \
|
||||
"# To do so, run the following command on another terminal:\n" \
|
||||
"# cat \"log_pipe_file\"\n" \
|
||||
"log_pipe=0\n" \
|
||||
"log_pipe_file=/tmp/mysgw.pipe\n" \
|
||||
"# Enable logging to syslog.\n" \
|
||||
"syslog=0\n" \
|
||||
"eeprom_file=/etc/mysensors.eeprom\n" \
|
||||
"eeprom_size=1024\n";
|
||||
|
||||
myFile = fopen(config_file, "w");
|
||||
if (!myFile) {
|
||||
logError("Unable to create config file %s.\n", config_file);
|
||||
return -1;
|
||||
}
|
||||
ret = fputs(default_conf, myFile);
|
||||
fclose(myFile);
|
||||
|
||||
return (ret > 0);
|
||||
}
|
||||
|
||||
int _config_parse_int(char *token, const char *name, int *value)
|
||||
{
|
||||
if (token) {
|
||||
*value = atoi(token);
|
||||
} else {
|
||||
logError("Empty %s value in configuration.\n", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _config_parse_string(char *token, const char *name, char **value)
|
||||
{
|
||||
if (token) {
|
||||
if (*value) {
|
||||
logError("Duplicate %s value in configuration.\n", name);
|
||||
return 1;
|
||||
}
|
||||
while (token[0] == ' ' || token[0] == '\t') {
|
||||
token++;
|
||||
}
|
||||
*value = strdup(token);
|
||||
if (!*value) {
|
||||
logError("Out of memory.\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
logError("Empty %s value in configuration.\n", name);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
45
drivers/Linux/config.h
Normal file
45
drivers/Linux/config.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct config {
|
||||
int verbose;
|
||||
int log_file;
|
||||
char *log_filepath;
|
||||
int log_pipe;
|
||||
char *log_pipe_file;
|
||||
int syslog;
|
||||
char *eeprom_file;
|
||||
int eeprom_size;
|
||||
} conf;
|
||||
|
||||
int config_parse(const char *config_file);
|
||||
void config_cleanup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -19,49 +19,201 @@
|
||||
|
||||
#include "log.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
// Default values
|
||||
static const int log_opts = LOG_CONS | LOG_PERROR; // print syslog to stderror
|
||||
static const int log_facility = LOG_USER;
|
||||
static const char *_log_level_colors[] = {
|
||||
"\x1b[1;5;91m", "\x1b[1;91m", "\x1b[91m", "\x1b[31m", "\x1b[33m", "\x1b[34m", "\x1b[32m", "\x1b[36m"
|
||||
};
|
||||
static const char *_log_level_names[] = {
|
||||
"EMERGENCY", "ALERT", "CRITICAL", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG"
|
||||
};
|
||||
static uint8_t _log_quiet = 0;
|
||||
static uint8_t _log_level = LOG_DEBUG;
|
||||
static uint8_t _log_syslog = 0;
|
||||
|
||||
static uint8_t log_open = 0;
|
||||
static uint8_t _log_pipe = 0;
|
||||
static char *_log_pipe_file = NULL;
|
||||
static int _log_pipe_fd = -1;
|
||||
|
||||
void logOpen(int options, int facility)
|
||||
static FILE *_log_file_fp = NULL;
|
||||
|
||||
void logSetQuiet(uint8_t enable)
|
||||
{
|
||||
openlog(NULL, options, facility);
|
||||
log_open = 1;
|
||||
_log_quiet = enable ? 1 : 0;
|
||||
}
|
||||
|
||||
void vlogInfo(const char *fmt, va_list args)
|
||||
void logSetLevel(int level)
|
||||
{
|
||||
if (!log_open) {
|
||||
logOpen(log_opts, log_facility);
|
||||
if (level < LOG_EMERG || level > LOG_DEBUG) {
|
||||
return;
|
||||
}
|
||||
|
||||
_log_level = level;
|
||||
}
|
||||
|
||||
void logSetSyslog(int options, int facility)
|
||||
{
|
||||
openlog(NULL, options, facility);
|
||||
_log_syslog = 1;
|
||||
}
|
||||
|
||||
int logSetPipe(char *pipe_file)
|
||||
{
|
||||
if (pipe_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_log_pipe_file = strdup(pipe_file);
|
||||
if (_log_pipe_file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = mkfifo(_log_pipe_file, 0666);
|
||||
if (ret == 0) {
|
||||
_log_pipe = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int logSetFile(char *file)
|
||||
{
|
||||
if (file == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_log_file_fp = fopen(file, "a");
|
||||
if (_log_file_fp == NULL) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void logClose(void)
|
||||
{
|
||||
if (_log_syslog) {
|
||||
closelog();
|
||||
_log_syslog = 0;
|
||||
}
|
||||
|
||||
if (_log_pipe) {
|
||||
if (_log_pipe_fd > 0) {
|
||||
close(_log_pipe_fd);
|
||||
}
|
||||
/* remove the FIFO */
|
||||
unlink(_log_pipe_file);
|
||||
_log_pipe = 0;
|
||||
}
|
||||
if (_log_pipe_file != NULL) {
|
||||
free(_log_pipe_file);
|
||||
_log_pipe_file = NULL;
|
||||
}
|
||||
|
||||
if (_log_file_fp != NULL) {
|
||||
fclose(_log_file_fp);
|
||||
_log_file_fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void vlog(int level, const char *fmt, va_list args)
|
||||
{
|
||||
if (_log_level < level) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_log_quiet || _log_file_fp != NULL) {
|
||||
/* Get current time */
|
||||
time_t t = time(NULL);
|
||||
struct tm *lt = localtime(&t);
|
||||
|
||||
char buf[16];
|
||||
buf[strftime(buf, sizeof(buf), "%b %d %H:%M:%S", lt)] = '\0';
|
||||
|
||||
#ifdef LOG_DISABLE_COLOR
|
||||
(void)_log_level_colors;
|
||||
if (!_log_quiet) {
|
||||
fprintf(stderr, "%s %-5s ", buf, _log_level_names[level]);
|
||||
vfprintf(stderr, fmt, args);
|
||||
}
|
||||
if (_log_file_fp != NULL) {
|
||||
vfprintf(_log_file_fp, "%s %-5s ", buf, _log_level_names[level]);
|
||||
vfprintf(_log_file_fp, fmt, args);
|
||||
}
|
||||
#else
|
||||
if (!_log_quiet) {
|
||||
fprintf(stderr, "%s %s%-5s\x1b[0m ", buf, _log_level_colors[level], _log_level_names[level]);
|
||||
vfprintf(stderr, fmt, args);
|
||||
}
|
||||
if (_log_file_fp != NULL) {
|
||||
fprintf(_log_file_fp, "%s %s%-5s\x1b[0m ", buf, _log_level_colors[level], _log_level_names[level]);
|
||||
vfprintf(_log_file_fp, fmt, args);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_log_syslog) {
|
||||
vsyslog(level, fmt, args);
|
||||
}
|
||||
|
||||
if (_log_pipe) {
|
||||
if (_log_pipe_fd < 0) {
|
||||
_log_pipe_fd = open(_log_pipe_file, O_WRONLY | O_NONBLOCK);
|
||||
}
|
||||
if (_log_pipe_fd > 0) {
|
||||
if (vdprintf(_log_pipe_fd, fmt, args) < 0) {
|
||||
close(_log_pipe_fd);
|
||||
_log_pipe_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
vsyslog(LOG_INFO, fmt, args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logInfo(const char *fmt, ...)
|
||||
logEmergency(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlogInfo(fmt, args);
|
||||
vlog(LOG_EMERG, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void vlogError(const char *fmt, va_list args)
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logAlert(const char *fmt, ...)
|
||||
{
|
||||
if (!log_open) {
|
||||
logOpen(log_opts, log_facility);
|
||||
}
|
||||
vsyslog(LOG_ERR, fmt, args);
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlog(LOG_ALERT, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logCritical(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlog(LOG_CRIT, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -73,60 +225,10 @@ logError(const char *fmt, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlogError(fmt, args);
|
||||
vlog(LOG_ERR, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void vlogNotice(const char *fmt, va_list args)
|
||||
{
|
||||
if (!log_open) {
|
||||
logOpen(log_opts, log_facility);
|
||||
}
|
||||
vsyslog(LOG_NOTICE, fmt, args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logNotice(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlogNotice(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void vlogDebug(const char *fmt, va_list args)
|
||||
{
|
||||
if (!log_open) {
|
||||
logOpen(log_opts, log_facility);
|
||||
}
|
||||
vsyslog(LOG_DEBUG, fmt, args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logDebug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlogDebug(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void vlogWarning(const char *fmt, va_list args)
|
||||
{
|
||||
if (!log_open) {
|
||||
logOpen(log_opts, log_facility);
|
||||
}
|
||||
vsyslog(LOG_WARNING, fmt, args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
@@ -136,6 +238,45 @@ logWarning(const char *fmt, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlogWarning(fmt, args);
|
||||
vlog(LOG_WARNING, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logNotice(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlog(LOG_NOTICE, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logInfo(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlog(LOG_INFO, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
logDebug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vlog(LOG_DEBUG, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -21,27 +21,36 @@
|
||||
#define LOG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void logOpen(int options, int facility);
|
||||
#define vlogError(...) vlog(LOG_ERR, __VA_ARGS__)
|
||||
#define vlogWarning(...) vlog(LOG_WARNING, __VA_ARGS__)
|
||||
#define vlogNotice(...) vlog(LOG_NOTICE, __VA_ARGS__)
|
||||
#define vlogInfo(...) vlog(LOG_INFO, __VA_ARGS__)
|
||||
#define vlogDebug(...) vlog(LOG_DEBUG, __VA_ARGS__)
|
||||
|
||||
extern void vlogInfo(const char *fmt, va_list args);
|
||||
extern void logInfo(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logSetQuiet(uint8_t enable);
|
||||
void logSetLevel(int level);
|
||||
void logSetSyslog(int options, int facility);
|
||||
int logSetPipe(char *pipe_file);
|
||||
int logSetFile(char *file);
|
||||
void logClose(void);
|
||||
|
||||
extern void vlogError(const char *fmt, va_list args);
|
||||
extern void logError(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
|
||||
extern void vlogNotice(const char *fmt, va_list args);
|
||||
extern void logNotice(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
|
||||
extern void vlogDebug(const char *fmt, va_list args);
|
||||
extern void logDebug(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
|
||||
extern void vlogWarning(const char *fmt, va_list args);
|
||||
extern void logWarning(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void vlog(int level, const char *fmt, va_list args);
|
||||
void logEmergency(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logAlert(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logCritical(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logError(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logWarning(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logNotice(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logInfo(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
void logDebug(const char *fmt, ...) __attribute__((format(printf,1,2)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -24,7 +24,7 @@
|
||||
// For more options run ./configure --help
|
||||
|
||||
// Config file
|
||||
//#define MY_LINUX_CONFIG_FILE "/etc/mysensors.dat"
|
||||
//#define MY_LINUX_CONFIG_FILE "/etc/mysensors.conf"
|
||||
|
||||
// How many clients should be able to connect to this gateway (default 1)
|
||||
#define MY_GATEWAY_MAX_CLIENTS 10
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -27,8 +27,9 @@
|
||||
#include <unistd.h>
|
||||
#include "SoftEeprom.h"
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
|
||||
static SoftEeprom eeprom = SoftEeprom(MY_LINUX_CONFIG_FILE, 1024); // ATMega328 has 1024 bytes
|
||||
static SoftEeprom eeprom;
|
||||
static FILE *randomFp = NULL;
|
||||
|
||||
bool hwInit(void)
|
||||
@@ -43,6 +44,10 @@ bool hwInit(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (eeprom.init(conf.eeprom_file, conf.eeprom_size) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2017 Sensnology AB
|
||||
* Copyright (C) 2013-2018 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
#include "MySensorsCore.h"
|
||||
|
||||
void handle_sigint(int sig)
|
||||
@@ -48,7 +49,7 @@ void handle_sigint(int sig)
|
||||
MY_SERIALDEVICE.end();
|
||||
#endif
|
||||
|
||||
closelog();
|
||||
logClose();
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -104,17 +105,18 @@ void print_usage()
|
||||
{
|
||||
printf("Usage: mysgw [options]\n\n" \
|
||||
"Options:\n" \
|
||||
" -c, --config-file Config file. [" MY_LINUX_CONFIG_FILE "]\n" \
|
||||
" -h, --help Display a short summary of all program options.\n" \
|
||||
" -d, --debug Enable debug.\n" \
|
||||
" -b, --background Run as a background process.\n"
|
||||
" --gen-soft-hmac-key Generate and print a soft hmac key.\n"
|
||||
" --gen-soft-serial-key Generate and print a soft serial key.\n"
|
||||
" --gen-aes-key Generate and print an aes encryption key.\n"
|
||||
" --print-soft-hmac-key Print the soft hmac key from the config file.\n"
|
||||
" --print-soft-serial-key Print the soft serial key from the config file.\n"
|
||||
" --print-aes-key Print the aes encryption key from the config file.\n"
|
||||
" --set-soft-hmac-key Write a soft hmac key to the config file.\n"
|
||||
" --set-soft-serial-key Write a soft serial key to the config file.\n"
|
||||
" -q, --quiet Quiet mode, disable log messages written to the terminal.\n" \
|
||||
" --daemon Run as a daemon.\n" \
|
||||
" --gen-soft-hmac-key Generate and print a soft hmac key.\n" \
|
||||
" --gen-soft-serial-key Generate and print a soft serial key.\n" \
|
||||
" --gen-aes-key Generate and print an aes encryption key.\n" \
|
||||
" --print-soft-hmac-key Print the soft hmac key from the config file.\n" \
|
||||
" --print-soft-serial-key Print the soft serial key from the config file.\n" \
|
||||
" --print-aes-key Print the aes encryption key from the config file.\n" \
|
||||
" --set-soft-hmac-key Write a soft hmac key to the config file.\n" \
|
||||
" --set-soft-serial-key Write a soft serial key to the config file.\n" \
|
||||
" --set-aes-key Write an aes encryption key to the config file.\n");
|
||||
}
|
||||
|
||||
@@ -338,19 +340,21 @@ void set_aes_key(char *key_str)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int opt, log_opts, debug = 0, foreground = 1;
|
||||
char *key = NULL;
|
||||
int opt, daemon = 0, quiet = 0;
|
||||
char *key = NULL, *config_file = NULL;
|
||||
|
||||
/* register the signal handler */
|
||||
signal(SIGINT, handle_sigint);
|
||||
signal(SIGTERM, handle_sigint);
|
||||
signal(SIGPIPE, handle_sigint);
|
||||
|
||||
hwRandomNumberInit();
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"config-file", required_argument, 0, 'c'},
|
||||
{"daemon", no_argument, 0, 'J'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{"background", no_argument, 0, 'b'},
|
||||
{"quiet", no_argument, 0, 'q'},
|
||||
{"gen-soft-hmac-key", no_argument, 0, 'A'},
|
||||
{"gen-soft-serial-key", no_argument, 0, 'B'},
|
||||
{"gen-aes-key", no_argument, 0, 'C'},
|
||||
@@ -364,16 +368,16 @@ int main(int argc, char *argv[])
|
||||
};
|
||||
|
||||
int long_index = 0;
|
||||
while ((opt = getopt_long(argc, argv,"hdbABCDEFGHI", long_options, &long_index )) != -1) {
|
||||
while ((opt = getopt_long(argc, argv,"chqABCDEFGHIJ", long_options, &long_index )) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
config_file = strdup(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
print_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'b':
|
||||
foreground = 0;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'A':
|
||||
generate_soft_sign_hmac_key();
|
||||
@@ -405,27 +409,46 @@ int main(int argc, char *argv[])
|
||||
key = strdup(optarg);
|
||||
set_aes_key(key);
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'J':
|
||||
daemon = 1;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
log_opts = LOG_CONS;
|
||||
if (foreground && isatty(STDIN_FILENO)) {
|
||||
// Also print syslog to stderror
|
||||
log_opts |= LOG_PERROR;
|
||||
}
|
||||
if (!debug) {
|
||||
// Ignore debug type messages
|
||||
setlogmask(LOG_UPTO (LOG_INFO));
|
||||
}
|
||||
logOpen(log_opts, LOG_USER);
|
||||
|
||||
if (!foreground && !debug) {
|
||||
if (daemon) {
|
||||
if (daemonize() != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
quiet = 1;
|
||||
}
|
||||
|
||||
if (config_parse(config_file?config_file:MY_LINUX_CONFIG_FILE) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (config_file) {
|
||||
free(config_file);
|
||||
}
|
||||
|
||||
logSetQuiet(quiet);
|
||||
logSetLevel(conf.verbose);
|
||||
|
||||
if (conf.log_file) {
|
||||
if (logSetFile(conf.log_filepath) != 0) {
|
||||
logError("Failed to open log file.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (conf.log_pipe) {
|
||||
if (logSetPipe(conf.log_pipe_file) != 0) {
|
||||
logError("Failed to open log pipe.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (conf.syslog) {
|
||||
logSetSyslog(LOG_CONS, LOG_USER);
|
||||
}
|
||||
|
||||
logInfo("Starting gateway...\n");
|
||||
|
||||
@@ -3,7 +3,7 @@ Description=MySensors Gateway daemon
|
||||
Requires=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=%gateway_dir%/mysgw
|
||||
ExecStart=%gateway_dir%/mysgw -q
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -17,7 +17,7 @@ PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
|
||||
DESC="MySensors Gateway"
|
||||
NAME=mysgw
|
||||
DAEMON=%gateway_dir%/$NAME
|
||||
DAEMON_ARGS="-b"
|
||||
DAEMON_ARGS="--daemon -q"
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
|
||||
Reference in New Issue
Block a user