Skip to content

Commit 09103e9

Browse files
committed
Add run time options to RPi gateway
1 parent b4f4e28 commit 09103e9

13 files changed

+178
-77
lines changed

Diff for: configure

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Installation options:
2828
2929
MySensors options:
3030
--my-debug=[enable|disable]
31-
Enables or disables debugging. [enable]
31+
Enables or disables MySensors core debugging. [enable]
3232
--my-config-file=<FILE> Config file path. [/etc/mysensors.dat]
3333
--my-gateway=[none|ethernet|serial|mqtt]
3434
Gateway type, set to none to disable gateway feature. [ethernet]

Diff for: core/MyGatewayTransportSerial.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
* version 2 as published by the Free Software Foundation.
1818
*/
1919

20-
2120
#include "MyConfig.h"
2221
#include "MyProtocol.h"
2322
#include "MyGatewayTransport.h"
@@ -31,7 +30,6 @@ char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incom
3130
int _serialInputPos;
3231
MyMessage _serialMsg;
3332

34-
3533
bool gatewayTransportSend(MyMessage &message) {
3634
setIndication(INDICATION_GW_TX);
3735
MY_SERIALDEVICE.print(protocolFormat(message));
@@ -47,7 +45,6 @@ bool gatewayTransportInit() {
4745
return true;
4846
}
4947

50-
5148
bool gatewayTransportAvailable() {
5249
while (MY_SERIALDEVICE.available()) {
5350
// get the new byte:

Diff for: core/MyHwLinuxGeneric.cpp

+15-9
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
#include <iostream>
2525
#include <fstream>
2626
#include <sys/stat.h>
27+
#include "log.h"
2728

2829
static const char* CONFIG_FILE = MY_LINUX_CONFIG_FILE;
2930
static const size_t _length = 1024; // ATMega328 has 1024 bytes
3031
static uint8_t _config[_length];
3132

32-
bool CheckConfigFile() {
33+
bool CheckConfigFile()
34+
{
3335
struct stat fileInfo;
3436

3537
if (stat(CONFIG_FILE, &fileInfo) != 0) {
@@ -152,27 +154,31 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
152154
return -2;
153155
}
154156

155-
uint16_t hwCPUVoltage() {
157+
uint16_t hwCPUVoltage()
158+
{
156159
// TODO: Not supported!
157160
return 0;
158161
}
159162

160-
uint16_t hwCPUFrequency() {
163+
uint16_t hwCPUFrequency()
164+
{
161165
// TODO: Not supported!
162166
return 0;
163167
}
164168

165-
uint16_t hwFreeMem() {
169+
uint16_t hwFreeMem()
170+
{
166171
// TODO: Not supported!
167172
return 0;
168173
}
169174

170175
#ifdef MY_DEBUG
171-
void hwDebugPrint(const char *fmt, ... )
176+
void hwDebugPrint(const char *fmt, ...)
172177
{
173-
va_list arglist;
174-
va_start(arglist, fmt);
175-
vprintf(fmt, arglist);
176-
va_end(arglist);
178+
va_list args;
179+
180+
va_start(args, fmt);
181+
mys_log_v(LOG_DEBUG, fmt, args);
182+
va_end(args);
177183
}
178184
#endif

Diff for: core/MyMainLinux.cpp

+91-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
// Initialize library and handle sketch functions like we want to
22

3-
#include <iostream>
3+
#include <stdio.h>
44
#include <csignal>
55
#include <cstdlib>
6+
#include <unistd.h>
7+
#include <fcntl.h>
8+
#include <syslog.h>
9+
#include <errno.h>
10+
#include "log.h"
611
#include "MySensorsCore.h"
712

8-
/*
9-
* handler for SIGINT signal
10-
*/
1113
void handle_sigint(int sig)
1214
{
1315
if (sig == SIGINT) {
14-
std::cout << "Received SIGINT\n" << std::endl;
16+
mys_log(LOG_NOTICE, "Received SIGINT\n\n");
1517
} else if (sig == SIGTERM) {
16-
std::cout << "Received SIGTERM\n" << std::endl;
18+
mys_log(LOG_NOTICE, "Received SIGTERM\n\n");
19+
} else {
20+
return;
1721
}
1822

1923
#ifdef MY_RF24_IRQ_PIN
@@ -27,11 +31,91 @@ void handle_sigint(int sig)
2731
exit(0);
2832
}
2933

30-
int main(void) {
34+
static int daemonize(void)
35+
{
36+
pid_t pid, sid;
37+
38+
/* Fork off the parent process */
39+
pid = fork();
40+
if (pid < 0) {
41+
mys_log(LOG_ERR, "fork: %s", strerror(errno));
42+
return -1;
43+
}
44+
/* If we got a good PID, then we can exit the parent process. */
45+
if (pid > 0) {
46+
exit(EXIT_SUCCESS);
47+
}
48+
49+
/* At this point we are executing as the child process */
50+
51+
/* Change the file mode mask */
52+
umask(0);
53+
54+
/* Create a new SID for the child process */
55+
sid = setsid();
56+
if (sid < 0) {
57+
mys_log(LOG_ERR, "setsid: %s", strerror(errno));
58+
return -1;
59+
}
60+
61+
/* Change the current working directory. This prevents the current
62+
directory from being locked; hence not being able to remove it. */
63+
if ((chdir("/")) < 0) {
64+
mys_log(LOG_ERR, "chdir(\"/\"): %s", strerror(errno));
65+
return -1;
66+
}
67+
68+
freopen( "/dev/null", "r", stdin);
69+
freopen( "/dev/null", "r", stdout);
70+
freopen( "/dev/null", "r", stderr);
71+
72+
return 0;
73+
}
74+
75+
int main(int argc, char *argv[])
76+
{
77+
int opt, log_opts, debug = 0, foreground = 1;
78+
3179
/* register the signal handler */
3280
signal(SIGINT, handle_sigint);
3381
signal(SIGTERM, handle_sigint);
3482

83+
while ((opt = getopt(argc, argv, "hdb")) != -1) {
84+
switch (opt) {
85+
case 'h':
86+
printf("Usage: mysGateway [options]\n\n" \
87+
"Options:\n" \
88+
"-h Display a short summary of all program options.\n" \
89+
"-d Enable debug.\n" \
90+
"-b Become a daemon.\n");
91+
exit(0);
92+
case 'd':
93+
debug = 1;
94+
break;
95+
case 'b':
96+
foreground = 0;
97+
break;
98+
}
99+
}
100+
101+
log_opts = LOG_CONS;
102+
if (foreground && isatty(STDIN_FILENO)) {
103+
log_opts |= LOG_PERROR;
104+
}
105+
if (!debug) {
106+
setlogmask(LOG_UPTO (LOG_INFO));
107+
}
108+
openlog(NULL, log_opts, LOG_USER);
109+
110+
if (!foreground && !debug) {
111+
if (daemonize() != 0) {
112+
exit(EXIT_FAILURE);
113+
}
114+
}
115+
116+
mys_log(LOG_INFO, "Starting gateway...\n");
117+
mys_log(LOG_INFO, "Protocol version - %s\n", MYSENSORS_LIBRARY_VERSION);
118+
35119
_begin(); // Startup MySensors library
36120

37121
for (;;) {

Diff for: drivers/Linux/EthernetClient.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <sys/time.h>
3030
#include <netinet/tcp.h>
3131
#include <errno.h>
32+
#include "log.h"
3233
#include "EthernetClient.h"
3334

3435
EthernetClient::EthernetClient() : _sock(-1) {
@@ -50,37 +51,37 @@ int EthernetClient::connect(const char* host, uint16_t port) {
5051

5152
sprintf(port_str, "%hu", port);
5253
if ((rv = getaddrinfo(host, port_str, &hints, &servinfo)) != 0) {
53-
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
54+
mys_log(LOG_ERR, "getaddrinfo: %s\n", gai_strerror(rv));
5455
return -1;
5556
}
5657

5758
// loop through all the results and connect to the first we can
5859
for (p = servinfo; p != NULL; p = p->ai_next) {
5960
if ((sockfd = socket(p->ai_family, p->ai_socktype,
6061
p->ai_protocol)) == -1) {
61-
perror("socket");
62+
mys_log(LOG_ERR, "socket: %s\n", strerror(errno));
6263
continue;
6364
}
6465

6566
if (::connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
6667
close(sockfd);
67-
perror("connect");
68+
mys_log(LOG_ERR, "connect: %s\n", strerror(errno));
6869
continue;
6970
}
7071

7172
break;
7273
}
7374

7475
if (p == NULL) {
75-
fprintf(stderr, "failed to connect\n");
76+
mys_log(LOG_ERR, "failed to connect\n");
7677
return -1;
7778
}
7879

7980
_sock = sockfd;
8081

8182
void *addr = &(((struct sockaddr_in*)p->ai_addr)->sin_addr);
8283
inet_ntop(p->ai_family, addr, s, sizeof s);
83-
ETHERNETCLIENT_DEBUG("connected to %s\n", s);
84+
mys_log(LOG_DEBUG, "connected to %s\n", s);
8485

8586
freeaddrinfo(servinfo); // all done with this structure
8687

@@ -106,7 +107,7 @@ size_t EthernetClient::write(const uint8_t *buf, size_t size) {
106107
while (size > 0) {
107108
rc = send(_sock, buf + bytes, size, MSG_NOSIGNAL | MSG_DONTWAIT);
108109
if (rc == -1) {
109-
perror("send");
110+
mys_log(LOG_ERR, "send: %s\n", strerror(errno));
110111
close(_sock);
111112
_sock = -1;
112113
break;

Diff for: drivers/Linux/EthernetClient.h

-7
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@
3737
#define ETHERNETCLIENT_W5100_CLOSE_WAIT 0x1C
3838
#define ETHERNETCLIENT_W5100_LAST_ACK 0x1D
3939

40-
// debug
41-
#if defined(ETHERNETCLIENT_VERBOSE)
42-
#define ETHERNETCLIENT_DEBUG(x,...) debug(x, ##__VA_ARGS__) //!< debug
43-
#else
44-
#define ETHERNETCLIENT_DEBUG(x,...) //!< debug NULL
45-
#endif
46-
4740
/**
4841
* EthernetClient class
4942
*/

Diff for: drivers/Linux/EthernetServer.cpp

+12-11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <unistd.h>
2929
#include <errno.h>
3030
#include <fcntl.h>
31+
#include "log.h"
3132
#include "EthernetClient.h"
3233
#include "EthernetServer.h"
3334

@@ -56,40 +57,40 @@ void EthernetServer::begin(IPAddress address)
5657

5758
sprintf(portstr, "%d", port);
5859
if ((rv = getaddrinfo(address.toString().c_str(), portstr, &hints, &servinfo)) != 0) {
59-
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
60+
mys_log(LOG_ERR, "getaddrinfo: %s\n", gai_strerror(rv));
6061
return;
6162
}
6263

6364
// loop through all the results and bind to the first we can
6465
for (p = servinfo; p != NULL; p = p->ai_next) {
6566
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
66-
perror("socket");
67+
mys_log(LOG_ERR, "socket: %s\n", strerror(errno));
6768
continue;
6869
}
6970

7071
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
71-
perror("setsockopt");
72+
mys_log(LOG_ERR, "setsockopt: %s\n", strerror(errno));
7273
freeaddrinfo(servinfo);
7374
return;
7475
}
7576

7677
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
7778
close(sockfd);
78-
perror("bind");
79+
mys_log(LOG_ERR, "bind: %s\n", strerror(errno));
7980
continue;
8081
}
8182

8283
break;
8384
}
8485

8586
if (p == NULL) {
86-
fprintf(stderr, "failed to bind\n");
87+
mys_log(LOG_ERR, "failed to bind\n");
8788
freeaddrinfo(servinfo);
8889
return;
8990
}
9091

9192
if (listen(sockfd, ETHERNETSERVER_BACKLOG) == -1) {
92-
perror("listen");
93+
mys_log(LOG_ERR, "listen: %s\n", strerror(errno));
9394
freeaddrinfo(servinfo);
9495
return;
9596
}
@@ -101,7 +102,7 @@ void EthernetServer::begin(IPAddress address)
101102
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
102103
void *addr = &(ipv4->sin_addr);
103104
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
104-
ETHERNETSERVER_DEBUG("Listening for connections on %s:%s\n", ipstr, portstr);
105+
mys_log(LOG_DEBUG, "Listening for connections on %s:%s\n", ipstr, portstr);
105106
}
106107

107108
bool EthernetServer::hasClient()
@@ -141,7 +142,7 @@ size_t EthernetServer::write(const uint8_t *buffer, size_t size)
141142
client.stop();
142143
clients[i] = clients.back();
143144
clients.pop_back();
144-
ETHERNETSERVER_DEBUG("Client disconnected.");
145+
mys_log(LOG_DEBUG, "Client disconnected.");
145146
}
146147
}
147148

@@ -191,7 +192,7 @@ void EthernetServer::_accept()
191192
}
192193
}
193194
if (no_free_slots) {
194-
ETHERNETSERVER_DEBUG("Max number of ethernet clients reached.");
195+
mys_log(LOG_DEBUG, "Max number of ethernet clients reached.");
195196
return;
196197
}
197198
}
@@ -200,7 +201,7 @@ void EthernetServer::_accept()
200201
new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
201202
if (new_fd == -1) {
202203
if (errno != EAGAIN && errno != EWOULDBLOCK) {
203-
perror("accept");
204+
mys_log(LOG_ERR, "accept: %s\n", strerror(errno));
204205
}
205206
return;
206207
}
@@ -210,5 +211,5 @@ void EthernetServer::_accept()
210211

211212
void *addr = &(((struct sockaddr_in*)&client_addr)->sin_addr);
212213
inet_ntop(client_addr.ss_family, addr, ipstr, sizeof ipstr);
213-
ETHERNETSERVER_DEBUG("New connection from %s\n", ipstr);
214+
mys_log(LOG_DEBUG, "New connection from %s\n", ipstr);
214215
}

Diff for: drivers/Linux/EthernetServer.h

-7
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@
3434
#define ETHERNETSERVER_BACKLOG 10 //!< Maximum length to which the queue of pending connections may grow.
3535
#endif
3636

37-
// debug
38-
#if defined(ETHERNETSERVER_VERBOSE)
39-
#define ETHERNETSERVER_DEBUG(x,...) printf(x, ##__VA_ARGS__) //!< debug
40-
#else
41-
#define ETHERNETSERVER_DEBUG(x,...) //!< debug NULL
42-
#endif
43-
4437
class EthernetClient;
4538

4639
/**

0 commit comments

Comments
 (0)