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:
Marcelo Aquino
2018-03-23 07:00:34 -03:00
committed by Mikael Falkvidd
parent 06f8d2b7e5
commit 2175c993ef
14 changed files with 681 additions and 176 deletions

View File

@@ -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
View File

@@ -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.

View File

@@ -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;

View File

@@ -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
View 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
View 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

View File

@@ -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);
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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");

View File

@@ -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

View File

@@ -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