Merge development branch
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
// global variables
|
||||
extern MyMessage _msgTmp;
|
||||
|
||||
|
||||
#if defined(MY_CONTROLLER_IP_ADDRESS)
|
||||
IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
|
||||
#endif
|
||||
@@ -30,7 +29,7 @@ extern MyMessage _msgTmp;
|
||||
#if defined(MY_IP_ADDRESS)
|
||||
IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
|
||||
#endif
|
||||
byte _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
|
||||
uint8_t _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
|
||||
uint16_t _ethernetGatewayPort = MY_PORT;
|
||||
MyMessage _ethernetMsg;
|
||||
|
||||
@@ -38,8 +37,8 @@ MyMessage _ethernetMsg;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char string[MY_GATEWAY_MAX_RECEIVE_LENGTH];
|
||||
uint8_t idx;
|
||||
char string[MY_GATEWAY_MAX_RECEIVE_LENGTH];
|
||||
uint8_t idx;
|
||||
} inputBuffer;
|
||||
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
@@ -52,25 +51,30 @@ typedef struct
|
||||
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
|
||||
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
|
||||
#endif
|
||||
static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
|
||||
#endif
|
||||
|
||||
#if defined(MY_USE_UDP)
|
||||
EthernetUDP _ethernetServer;
|
||||
#elif defined(MY_GATEWAY_LINUX)
|
||||
EthernetServer _ethernetServer(_ethernetGatewayPort, MY_GATEWAY_MAX_CLIENTS);
|
||||
#elif defined(MY_GATEWAY_CLIENT_MODE)
|
||||
// Nothing to do here
|
||||
#else
|
||||
EthernetServer _ethernetServer(_ethernetGatewayPort);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
#if defined(MY_GATEWAY_CLIENT_MODE)
|
||||
static EthernetClient client = EthernetClient();
|
||||
static inputBuffer inputString;
|
||||
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)
|
||||
static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS];
|
||||
static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
|
||||
static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS];
|
||||
#else
|
||||
static EthernetClient client = EthernetClient();
|
||||
static inputBuffer inputString;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MY_IP_ADDRESS
|
||||
void gatewayTransportRenewIP();
|
||||
#endif
|
||||
@@ -80,25 +84,23 @@ typedef struct
|
||||
#ifdef MY_W5100_SPI_EN
|
||||
void _w5100_spi_en(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
// Pull up pin
|
||||
pinMode(MY_W5100_SPI_EN, INPUT);
|
||||
digitalWrite(MY_W5100_SPI_EN, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ground pin
|
||||
pinMode(MY_W5100_SPI_EN, OUTPUT);
|
||||
digitalWrite(MY_W5100_SPI_EN, LOW);
|
||||
}
|
||||
if (enable)
|
||||
{
|
||||
// Pull up pin
|
||||
pinMode(MY_W5100_SPI_EN, INPUT);
|
||||
digitalWrite(MY_W5100_SPI_EN, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ground pin
|
||||
pinMode(MY_W5100_SPI_EN, OUTPUT);
|
||||
digitalWrite(MY_W5100_SPI_EN, LOW);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define _w5100_spi_en(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
bool gatewayTransportInit() {
|
||||
_w5100_spi_en(true);
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
@@ -121,7 +123,8 @@ bool gatewayTransportInit() {
|
||||
MY_SERIALDEVICE.print(F("IP: "));
|
||||
MY_SERIALDEVICE.println(WiFi.localIP());
|
||||
#endif
|
||||
|
||||
#elif defined(MY_GATEWAY_LINUX)
|
||||
// Nothing to do here
|
||||
#else
|
||||
#ifdef MY_IP_ADDRESS
|
||||
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
|
||||
@@ -137,13 +140,32 @@ bool gatewayTransportInit() {
|
||||
MY_SERIALDEVICE.println(Ethernet.localIP());
|
||||
// give the Ethernet interface a second to initialize
|
||||
delay(1000);
|
||||
#endif
|
||||
#endif /* MY_GATEWAY_ESP8266 */
|
||||
|
||||
#ifdef MY_USE_UDP
|
||||
_ethernetServer.begin(_ethernetGatewayPort);
|
||||
#elif defined(MY_GATEWAY_CLIENT_MODE)
|
||||
#if defined(MY_CONTROLLER_URL_ADDRESS)
|
||||
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
|
||||
#else
|
||||
if (client.connect(_ethernetControllerIP, MY_PORT)) {
|
||||
#endif
|
||||
debug(PSTR("Eth: connect\n"));
|
||||
_w5100_spi_en(false);
|
||||
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set("Gateway startup complete."));
|
||||
_w5100_spi_en(true);
|
||||
presentNode();
|
||||
} else {
|
||||
client.stop();
|
||||
debug(PSTR("Eth: Failed to connect\n"));
|
||||
}
|
||||
#else
|
||||
// we have to use pointers due to the constructor of EthernetServer
|
||||
_ethernetServer.begin();
|
||||
#if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
|
||||
_ethernetServer.begin(_ethernetGatewayIP);
|
||||
#else
|
||||
// we have to use pointers due to the constructor of EthernetServer
|
||||
_ethernetServer.begin();
|
||||
#endif
|
||||
#endif /* USE_UDP */
|
||||
_w5100_spi_en(false);
|
||||
return true;
|
||||
@@ -151,31 +173,43 @@ bool gatewayTransportInit() {
|
||||
|
||||
bool gatewayTransportSend(MyMessage &message)
|
||||
{
|
||||
bool ret = true;
|
||||
int nbytes = 0;
|
||||
char *_ethernetMsg = protocolFormat(message);
|
||||
|
||||
setIndication(INDICATION_GW_TX);
|
||||
setIndication(INDICATION_GW_TX);
|
||||
|
||||
_w5100_spi_en(true);
|
||||
#if defined(MY_CONTROLLER_IP_ADDRESS)
|
||||
#if defined(MY_GATEWAY_CLIENT_MODE)
|
||||
#if defined(MY_USE_UDP)
|
||||
_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
|
||||
#if defined(MY_CONTROLLER_URL_ADDRESS)
|
||||
_ethernetServer.beginPacket(MY_CONTROLLER_URL_ADDRESS, MY_PORT);
|
||||
#else
|
||||
_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
|
||||
#endif
|
||||
_ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
|
||||
// returns 1 if the packet was sent successfully
|
||||
ret = _ethernetServer.endPacket();
|
||||
nbytes = _ethernetServer.endPacket();
|
||||
#else
|
||||
EthernetClient client;
|
||||
if (!client.connected()) {
|
||||
client.stop();
|
||||
#if defined(MY_CONTROLLER_URL_ADDRESS)
|
||||
if (client.connected() || client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
|
||||
#else
|
||||
if (client.connected() || client.connect(_ethernetControllerIP, MY_PORT)) {
|
||||
#endif
|
||||
client.write(_ethernetMsg, strlen(_ethernetMsg));
|
||||
}
|
||||
else {
|
||||
// connecting to the server failed!
|
||||
ret = false;
|
||||
}
|
||||
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
|
||||
#else
|
||||
if (client.connect(_ethernetControllerIP, MY_PORT)) {
|
||||
#endif
|
||||
debug(PSTR("Eth: connect\n"));
|
||||
_w5100_spi_en(false);
|
||||
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set("Gateway startup complete."));
|
||||
_w5100_spi_en(true);
|
||||
presentNode();
|
||||
} else {
|
||||
// connecting to the server failed!
|
||||
debug(PSTR("Eth: Failed to connect\n"));
|
||||
_w5100_spi_en(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
nbytes = client.write(_ethernetMsg, strlen(_ethernetMsg));
|
||||
#endif
|
||||
#else
|
||||
// Send message to connected clients
|
||||
@@ -184,20 +218,18 @@ bool gatewayTransportSend(MyMessage &message)
|
||||
{
|
||||
if (clients[i] && clients[i].connected())
|
||||
{
|
||||
clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
|
||||
nbytes += clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
|
||||
}
|
||||
}
|
||||
#else
|
||||
_ethernetServer.write(_ethernetMsg);
|
||||
nbytes = _ethernetServer.write(_ethernetMsg);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MY_GATEWAY_CLIENT_MODE */
|
||||
_w5100_spi_en(false);
|
||||
return ret;
|
||||
|
||||
return (nbytes > 0);
|
||||
}
|
||||
|
||||
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE)
|
||||
bool _readFromClient(uint8_t i) {
|
||||
while (clients[i].connected() && clients[i].available()) {
|
||||
char inChar = clients[i].read();
|
||||
@@ -267,27 +299,54 @@ bool gatewayTransportAvailable()
|
||||
#endif
|
||||
|
||||
#ifdef MY_USE_UDP
|
||||
|
||||
int packet_size = _ethernetServer.parsePacket();
|
||||
|
||||
if (packet_size) {
|
||||
//debug(PSTR("UDP packet available. Size:%d\n"), packet_size);
|
||||
setIndication(INDICATION_GW_RX);
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
_ethernetServer.read(inputString[0].string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
|
||||
inputString[0].string[packet_size] = 0;
|
||||
debug(PSTR("UDP packet received: %s\n"), inputString[0].string);
|
||||
return protocolParse(_ethernetMsg, inputString[0].string);
|
||||
const bool ok = protocolParse(_ethernetMsg, inputString[0].string);
|
||||
#else
|
||||
_ethernetServer.read(inputString.string, MY_GATEWAY_MAX_RECEIVE_LENGTH);
|
||||
inputString.string[packet_size] = 0;
|
||||
debug(PSTR("UDP packet received: %s\n"), inputString.string);
|
||||
_w5100_spi_en(false);
|
||||
return protocolParse(_ethernetMsg, inputString.string);
|
||||
const bool ok = protocolParse(_ethernetMsg, inputString.string);
|
||||
#endif
|
||||
if (ok)
|
||||
{
|
||||
setIndication(INDICATION_GW_RX);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
#elif defined(MY_GATEWAY_CLIENT_MODE)
|
||||
if (!client.connected()) {
|
||||
client.stop();
|
||||
#if defined(MY_CONTROLLER_URL_ADDRESS)
|
||||
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
|
||||
#else
|
||||
if (client.connect(_ethernetControllerIP, MY_PORT)) {
|
||||
#endif
|
||||
debug(PSTR("Eth: connect\n"));
|
||||
_w5100_spi_en(false);
|
||||
gatewayTransportSend(buildGw(_msgTmp, I_GATEWAY_READY).set("Gateway startup complete."));
|
||||
_w5100_spi_en(true);
|
||||
presentNode();
|
||||
} else {
|
||||
debug(PSTR("Eth: Failed to connect\n"));
|
||||
_w5100_spi_en(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (_readFromClient()) {
|
||||
setIndication(INDICATION_GW_RX);
|
||||
_w5100_spi_en(false);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
#if defined(MY_GATEWAY_ESP8266)
|
||||
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)
|
||||
// ESP8266: Go over list of clients and stop any that are no longer connected.
|
||||
// If the server has a new client connection it will be assigned to a free slot.
|
||||
bool allSlotsOccupied = true;
|
||||
@@ -320,7 +379,7 @@ bool gatewayTransportAvailable()
|
||||
// Loop over clients connect and read available data
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
|
||||
if (_readFromClient(i)) {
|
||||
setIndication(INDICATION_GW_RX);
|
||||
setIndication(INDICATION_GW_RX);
|
||||
_w5100_spi_en(false);
|
||||
return true;
|
||||
}
|
||||
@@ -346,13 +405,13 @@ bool gatewayTransportAvailable()
|
||||
client.stop();
|
||||
} else {
|
||||
if (_readFromClient()) {
|
||||
setIndication(INDICATION_GW_RX);
|
||||
setIndication(INDICATION_GW_RX);
|
||||
_w5100_spi_en(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* MY_GATEWAY_ESP8266 */
|
||||
#endif
|
||||
_w5100_spi_en(false);
|
||||
return false;
|
||||
@@ -364,8 +423,7 @@ MyMessage& gatewayTransportReceive()
|
||||
return _ethernetMsg;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266)
|
||||
#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_LINUX)
|
||||
void gatewayTransportRenewIP()
|
||||
{
|
||||
/* renew/rebind IP address
|
||||
@@ -389,4 +447,4 @@ void gatewayTransportRenewIP()
|
||||
_w5100_spi_en(false);
|
||||
next_time = now + MY_IP_RENEWAL_INTERVAL;
|
||||
}
|
||||
#endif /* IP_ADDRESS_DHCP */
|
||||
#endif
|
||||
|
||||
@@ -32,8 +32,10 @@
|
||||
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
|
||||
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
|
||||
#endif
|
||||
#elif defined(MY_GATEWAY_LINUX)
|
||||
// Nothing to do here
|
||||
#else
|
||||
byte _MQTT_clientMAC[] = { MY_MAC_ADDRESS };
|
||||
uint8_t _MQTT_clientMAC[] = { MY_MAC_ADDRESS };
|
||||
#endif
|
||||
|
||||
#if defined(MY_IP_ADDRESS)
|
||||
@@ -46,98 +48,20 @@ static bool _MQTT_connecting = true;
|
||||
static bool _MQTT_available = false;
|
||||
static MyMessage _MQTT_msg;
|
||||
|
||||
uint8_t protocolH2i(char c) {
|
||||
uint8_t i = 0;
|
||||
if (c <= '9')
|
||||
i += c - '0';
|
||||
else if (c >= 'a')
|
||||
i += c - 'a' + 10;
|
||||
else
|
||||
i += c - 'A' + 10;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
bool gatewayTransportSend(MyMessage &message) {
|
||||
if (!_MQTT_client.connected())
|
||||
return false;
|
||||
setIndication(INDICATION_GW_TX);
|
||||
char _fmtBuffer[MY_GATEWAY_MAX_SEND_LENGTH];
|
||||
char _convBuffer[MAX_PAYLOAD * 2 + 1];
|
||||
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR(MY_MQTT_PUBLISH_TOPIC_PREFIX "/%d/%d/%d/%d/%d"), message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type);
|
||||
debug(PSTR("Sending message on topic: %s\n"), _fmtBuffer);
|
||||
return _MQTT_client.publish(_fmtBuffer, message.getString(_convBuffer));
|
||||
char *topic = protocolFormatMQTTTopic(MY_MQTT_PUBLISH_TOPIC_PREFIX, message);
|
||||
debug(PSTR("Sending message on topic: %s\n"), topic);
|
||||
return _MQTT_client.publish(topic, message.getString(_convBuffer));
|
||||
}
|
||||
|
||||
void incomingMQTT(char* topic, byte* payload, unsigned int length) {
|
||||
void incomingMQTT(char* topic, uint8_t* payload, unsigned int length) {
|
||||
debug(PSTR("Message arrived on topic: %s\n"), topic);
|
||||
char *str, *p;
|
||||
uint8_t i = 0;
|
||||
uint8_t bvalue[MAX_PAYLOAD];
|
||||
uint8_t blen = 0;
|
||||
uint8_t command = 0;
|
||||
for (str = strtok_r(topic, "/", &p); str && i <= 5;
|
||||
str = strtok_r(NULL, "/", &p)) {
|
||||
switch (i) {
|
||||
case 0: {
|
||||
// Topic prefix
|
||||
if (strcmp(str, MY_MQTT_SUBSCRIBE_TOPIC_PREFIX) != 0) {
|
||||
// Message not for us or malformed!
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
// Node id
|
||||
_MQTT_msg.destination = atoi(str);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// Sensor id
|
||||
_MQTT_msg.sensor = atoi(str);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
// Command type
|
||||
command = atoi(str);
|
||||
mSetCommand(_MQTT_msg, command);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// Ack flag
|
||||
mSetRequestAck(_MQTT_msg, atoi(str) ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
// Sub type
|
||||
_MQTT_msg.type = atoi(str);
|
||||
// Add payload
|
||||
if (command == C_STREAM) {
|
||||
blen = 0;
|
||||
uint8_t val;
|
||||
while (*payload) {
|
||||
val = protocolH2i(*payload++) << 4;
|
||||
val += protocolH2i(*payload++);
|
||||
bvalue[blen] = val;
|
||||
blen++;
|
||||
}
|
||||
_MQTT_msg.set(bvalue, blen);
|
||||
}
|
||||
else {
|
||||
char* ca;
|
||||
ca = (char *)payload;
|
||||
ca += length;
|
||||
*ca = '\0';
|
||||
_MQTT_msg.set((const char*)payload);
|
||||
}
|
||||
_MQTT_available = true;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
_MQTT_available = protocolMQTTParse(_MQTT_msg, topic, payload, length);
|
||||
}
|
||||
|
||||
|
||||
bool reconnectMQTT() {
|
||||
debug(PSTR("Attempting MQTT connection...\n"));
|
||||
// Attempt to connect
|
||||
@@ -168,6 +92,10 @@ bool gatewayTransportConnect() {
|
||||
}
|
||||
MY_SERIALDEVICE.print("IP: ");
|
||||
MY_SERIALDEVICE.println(WiFi.localIP());
|
||||
#elif defined(MY_GATEWAY_LINUX)
|
||||
#if defined(MY_IP_ADDRESS)
|
||||
//TODO
|
||||
#endif
|
||||
#else
|
||||
#ifdef MY_IP_ADDRESS
|
||||
Ethernet.begin(_MQTT_clientMAC, _MQTT_clientIp);
|
||||
@@ -215,10 +143,7 @@ bool gatewayTransportInit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool gatewayTransportAvailable() {
|
||||
|
||||
if (_MQTT_connecting)
|
||||
return false;
|
||||
|
||||
@@ -239,6 +164,3 @@ MyMessage & gatewayTransportReceive() {
|
||||
_MQTT_available = false;
|
||||
return _MQTT_msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
|
||||
#include "MyConfig.h"
|
||||
#include "MyProtocol.h"
|
||||
#include "MyGatewayTransport.h"
|
||||
@@ -31,7 +30,6 @@ char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incom
|
||||
uint8_t _serialInputPos;
|
||||
MyMessage _serialMsg;
|
||||
|
||||
|
||||
bool gatewayTransportSend(MyMessage &message) {
|
||||
setIndication(INDICATION_GW_TX);
|
||||
MY_SERIALDEVICE.print(protocolFormat(message));
|
||||
@@ -47,7 +45,6 @@ bool gatewayTransportInit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool gatewayTransportAvailable() {
|
||||
while (MY_SERIALDEVICE.available()) {
|
||||
// get the new byte:
|
||||
@@ -58,7 +55,11 @@ bool gatewayTransportAvailable() {
|
||||
if (inChar == '\n') {
|
||||
_serialInputString[_serialInputPos] = 0;
|
||||
bool ok = protocolParse(_serialMsg, _serialInputString);
|
||||
_serialInputPos = 0;
|
||||
if (ok)
|
||||
{
|
||||
setIndication(INDICATION_GW_RX);
|
||||
}
|
||||
_serialInputPos = 0;
|
||||
return ok;
|
||||
} else {
|
||||
// add it to the inputString:
|
||||
|
||||
@@ -59,7 +59,13 @@ do { \
|
||||
// Define these as macros to save valuable space
|
||||
|
||||
#define hwDigitalWrite(__pin, __value) (digitalWrite(__pin, __value))
|
||||
#define hwInit() MY_SERIALDEVICE.begin(MY_BAUD_RATE)
|
||||
|
||||
#if defined(MY_DISABLED_SERIAL)
|
||||
#define hwInit()
|
||||
#else
|
||||
#define hwInit() MY_SERIALDEVICE.begin(MY_BAUD_RATE)
|
||||
#endif
|
||||
|
||||
#define hwWatchdogReset() wdt_reset()
|
||||
#define hwReboot() wdt_enable(WDTO_15MS); while (1)
|
||||
#define hwMillis() millis()
|
||||
|
||||
+7
-1
@@ -35,7 +35,13 @@
|
||||
// Define these as macros to save valuable space
|
||||
|
||||
#define hwDigitalWrite(__pin, __value) (digitalWrite(__pin, __value))
|
||||
#define hwInit() MY_SERIALDEVICE.begin(MY_BAUD_RATE); MY_SERIALDEVICE.setDebugOutput(true)
|
||||
|
||||
#if defined(MY_DISABLED_SERIAL)
|
||||
#define hwInit()
|
||||
#else
|
||||
#define hwInit() MY_SERIALDEVICE.begin(MY_BAUD_RATE, SERIAL_8N1, MY_ESP8266_SERIAL_MODE, 1); MY_SERIALDEVICE.setDebugOutput(true)
|
||||
#endif
|
||||
|
||||
#define hwWatchdogReset() wdt_reset()
|
||||
#define hwReboot() ESP.restart()
|
||||
#define hwMillis() millis()
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/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.
|
||||
*/
|
||||
|
||||
#include "MyHwLinuxGeneric.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include "log.h"
|
||||
|
||||
static const char* CONFIG_FILE = MY_LINUX_CONFIG_FILE;
|
||||
static const size_t _length = 1024; // ATMega328 has 1024 bytes
|
||||
static uint8_t _config[_length];
|
||||
|
||||
bool CheckConfigFile()
|
||||
{
|
||||
struct stat fileInfo;
|
||||
|
||||
if (stat(CONFIG_FILE, &fileInfo) != 0) {
|
||||
//File does not exist. Create it.
|
||||
debug("Config file %s does not exist, creating new config file.\n", CONFIG_FILE);
|
||||
std::ofstream myFile(CONFIG_FILE, std::ios::out | std::ios::binary);
|
||||
if (!myFile) {
|
||||
debug("Unable to create config file %s.\n", CONFIG_FILE);
|
||||
return false;
|
||||
}
|
||||
myFile.write((const char*)_config, _length);
|
||||
myFile.close();
|
||||
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
|
||||
debug("Config file %s is not the correct size of %i. Please remove the file and a new one will be created.\n", CONFIG_FILE, _length);
|
||||
return false;
|
||||
} else {
|
||||
//Read config into local memory.
|
||||
std::ifstream myFile(CONFIG_FILE, std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
debug("Unable to open config to file %s for reading.\n", CONFIG_FILE);
|
||||
return false;
|
||||
}
|
||||
myFile.read((char*)_config, _length);
|
||||
myFile.close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void hwInit()
|
||||
{
|
||||
for (size_t i = 0; i < _length; i++) {
|
||||
_config[i] = 0xFF;
|
||||
}
|
||||
|
||||
if (!CheckConfigFile()) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef MY_GATEWAY_SERIAL
|
||||
MY_SERIALDEVICE.begin(MY_BAUD_RATE);
|
||||
#ifdef MY_LINUX_SERIAL_GROUPNAME
|
||||
if (!MY_SERIALDEVICE.setGroupPerm(MY_LINUX_SERIAL_GROUPNAME)) {
|
||||
debug("Unable to change permission for serial port device.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void hwReadConfigBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(buf, _config+offs, length);
|
||||
}
|
||||
}
|
||||
|
||||
void hwWriteConfigBlock(void* buf, void* addr, size_t length)
|
||||
{
|
||||
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
|
||||
|
||||
if (length && offs + length <= _length) {
|
||||
memcpy(_config+offs, buf, length);
|
||||
|
||||
std::ofstream myFile(CONFIG_FILE, std::ios::out | std::ios::in | std::ios::binary);
|
||||
if (!myFile) {
|
||||
debug("Unable to write config to file %s.\n", CONFIG_FILE);
|
||||
return;
|
||||
}
|
||||
myFile.seekp(offs);
|
||||
myFile.write((const char*)buf, length);
|
||||
myFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t hwReadConfig(int adr)
|
||||
{
|
||||
uint8_t value = 0xFF;
|
||||
hwReadConfigBlock(&value, reinterpret_cast<void*>(adr), 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
void hwWriteConfig(int adr, uint8_t value)
|
||||
{
|
||||
uint8_t curr = hwReadConfig(adr);
|
||||
if (curr != value) {
|
||||
hwWriteConfigBlock(&value, reinterpret_cast<void*>(adr), 1);
|
||||
}
|
||||
}
|
||||
|
||||
void hwRandomNumberInit()
|
||||
{
|
||||
randomSeed(time(NULL));
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(unsigned long ms)
|
||||
{
|
||||
(void)ms;
|
||||
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms)
|
||||
{
|
||||
(void)interrupt;
|
||||
(void)mode;
|
||||
(void)ms;
|
||||
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
// Not supported!
|
||||
int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms)
|
||||
{
|
||||
(void)interrupt1;
|
||||
(void)mode1;
|
||||
(void)interrupt2;
|
||||
(void)mode2;
|
||||
(void)ms;
|
||||
|
||||
return MY_SLEEP_NOT_POSSIBLE;
|
||||
}
|
||||
|
||||
uint16_t hwCPUVoltage()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t hwCPUFrequency()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t hwFreeMem()
|
||||
{
|
||||
// TODO: Not supported!
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
void hwDebugPrint(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
mys_log_v(LOG_DEBUG, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* 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 Marcelo Aquino <marceloaqno@gmail.org>
|
||||
* Copyright (C) 2016 Marcelo Aquino
|
||||
* Full contributor list: https://github.com/mysensors/MySensors/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 MyHwLinuxGeneric_h
|
||||
#define MyHwLinuxGeneric_h
|
||||
|
||||
#include <cstdlib>
|
||||
#include <pthread.h>
|
||||
#include "MyHw.h"
|
||||
#include "SerialPort.h"
|
||||
|
||||
#ifdef MY_IS_SERIAL_PTY
|
||||
SerialPort Serial = SerialPort(MY_LINUX_SERIAL_PTY, true);
|
||||
#else
|
||||
SerialPort Serial = SerialPort(MY_LINUX_SERIAL_PORT);
|
||||
#endif
|
||||
|
||||
#define MY_SERIALDEVICE Serial
|
||||
|
||||
// Define these as macros (do nothing)
|
||||
#define hwDigitalWrite(__pin, __value)
|
||||
#define hwWatchdogReset()
|
||||
#define hwReboot()
|
||||
#define hwMillis() millis()
|
||||
|
||||
void hwInit();
|
||||
void hwReadConfigBlock(void* buf, void* adr, size_t length);
|
||||
void hwWriteConfigBlock(void* buf, void* adr, size_t length);
|
||||
uint8_t hwReadConfig(int adr);
|
||||
void hwWriteConfig(int adr, uint8_t value);
|
||||
void hwRandomNumberInit();
|
||||
|
||||
#ifdef MY_RF24_IRQ_PIN
|
||||
static pthread_mutex_t hw_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static __inline__ void __hwUnlock(const uint8_t *__s) {
|
||||
pthread_mutex_unlock(&hw_mutex);
|
||||
(void)__s;
|
||||
}
|
||||
|
||||
static __inline__ void __hwLock() {
|
||||
pthread_mutex_lock(&hw_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DOXYGEN)
|
||||
#define ATOMIC_BLOCK_CLEANUP
|
||||
#elif defined(MY_RF24_IRQ_PIN)
|
||||
#define ATOMIC_BLOCK_CLEANUP uint8_t __atomic_loop \
|
||||
__attribute__((__cleanup__( __hwUnlock ))) = 1
|
||||
#else
|
||||
#define ATOMIC_BLOCK_CLEANUP
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
#if defined(DOXYGEN)
|
||||
#define ATOMIC_BLOCK
|
||||
#elif defined(MY_RF24_IRQ_PIN)
|
||||
#define ATOMIC_BLOCK for ( ATOMIC_BLOCK_CLEANUP, __hwLock(); \
|
||||
__atomic_loop ; __atomic_loop = 0 )
|
||||
#else
|
||||
#define ATOMIC_BLOCK
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
#ifndef DOXYGEN
|
||||
#define MY_CRITICAL_SECTION ATOMIC_BLOCK
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
// Initialize library and handle sketch functions like we want to
|
||||
|
||||
#include <stdio.h>
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#include "log.h"
|
||||
#include "MySensorsCore.h"
|
||||
|
||||
void handle_sigint(int sig)
|
||||
{
|
||||
if (sig == SIGINT) {
|
||||
mys_log(LOG_NOTICE, "Received SIGINT\n\n");
|
||||
} else if (sig == SIGTERM) {
|
||||
mys_log(LOG_NOTICE, "Received SIGTERM\n\n");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MY_RF24_IRQ_PIN
|
||||
detachInterrupt(MY_RF24_IRQ_PIN);
|
||||
#endif
|
||||
|
||||
#if defined(MY_GATEWAY_SERIAL)
|
||||
MY_SERIALDEVICE.end();
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int daemonize(void)
|
||||
{
|
||||
pid_t pid, sid;
|
||||
|
||||
/* Fork off the parent process */
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
mys_log(LOG_ERR, "fork: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* If we got a good PID, then we can exit the parent process. */
|
||||
if (pid > 0) {
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* At this point we are executing as the child process */
|
||||
|
||||
/* Change the file mode mask */
|
||||
umask(0);
|
||||
|
||||
/* Create a new SID for the child process */
|
||||
sid = setsid();
|
||||
if (sid < 0) {
|
||||
mys_log(LOG_ERR, "setsid: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Change the current working directory. This prevents the current
|
||||
directory from being locked; hence not being able to remove it. */
|
||||
if ((chdir("/")) < 0) {
|
||||
mys_log(LOG_ERR, "chdir(\"/\"): %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
freopen( "/dev/null", "r", stdin);
|
||||
freopen( "/dev/null", "r", stdout);
|
||||
freopen( "/dev/null", "r", stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_usage()
|
||||
{
|
||||
printf("Usage: mysGateway [options]\n\n" \
|
||||
"Options:\n" \
|
||||
" -h Display a short summary of all program options.\n" \
|
||||
" -d Enable debug.\n" \
|
||||
" -b Become a daemon.\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int opt, log_opts, debug = 0, foreground = 1;
|
||||
|
||||
/* register the signal handler */
|
||||
signal(SIGINT, handle_sigint);
|
||||
signal(SIGTERM, handle_sigint);
|
||||
|
||||
while ((opt = getopt(argc, argv, "hdb")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
exit(0);
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'b':
|
||||
foreground = 0;
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
log_opts = LOG_CONS;
|
||||
if (foreground && isatty(STDIN_FILENO)) {
|
||||
// Also print syslog to stderror
|
||||
log_opts |= LOG_PERROR;
|
||||
}
|
||||
if (!debug) {
|
||||
setlogmask(LOG_UPTO (LOG_INFO));
|
||||
}
|
||||
openlog(NULL, log_opts, LOG_USER);
|
||||
|
||||
if (!foreground && !debug) {
|
||||
if (daemonize() != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
mys_log(LOG_INFO, "Starting gateway...\n");
|
||||
mys_log(LOG_INFO, "Protocol version - %s\n", MYSENSORS_LIBRARY_VERSION);
|
||||
|
||||
_begin(); // Startup MySensors library
|
||||
|
||||
for (;;) {
|
||||
_process(); // Process incoming data
|
||||
if (loop) loop(); // Call sketch loop
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+4
-4
@@ -21,7 +21,7 @@
|
||||
#include "MyMessage.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
MyMessage::MyMessage()
|
||||
{
|
||||
@@ -117,7 +117,7 @@ char* MyMessage::getString(char *buffer) const {
|
||||
} else if (payloadType == P_ULONG32) {
|
||||
ultoa(ulValue, buffer, 10);
|
||||
} else if (payloadType == P_FLOAT32) {
|
||||
dtostrf(fValue,2,min(fPrecision, 8),buffer);
|
||||
dtostrf(fValue,2,min(fPrecision, (uint8_t)8),buffer);
|
||||
} else if (payloadType == P_CUSTOM) {
|
||||
return getCustomString(buffer);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ MyMessage& MyMessage::setDestination(uint8_t _destination) {
|
||||
|
||||
// Set payload
|
||||
MyMessage& MyMessage::set(void* value, uint8_t length) {
|
||||
uint8_t payloadLength = value == NULL ? 0 : min(length, MAX_PAYLOAD);
|
||||
uint8_t payloadLength = value == NULL ? 0 : min(length, (uint8_t)MAX_PAYLOAD);
|
||||
miSetLength(payloadLength);
|
||||
miSetPayloadType(P_CUSTOM);
|
||||
memcpy(data, value, payloadLength);
|
||||
@@ -218,7 +218,7 @@ MyMessage& MyMessage::set(void* value, uint8_t length) {
|
||||
}
|
||||
|
||||
MyMessage& MyMessage::set(const char* value) {
|
||||
uint8_t length = value == NULL ? 0 : min(strlen(value), MAX_PAYLOAD);
|
||||
uint8_t length = value == NULL ? 0 : min(strlen(value), (size_t)MAX_PAYLOAD);
|
||||
miSetLength(length);
|
||||
miSetPayloadType(P_STRING);
|
||||
if (length) {
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <Arduino.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "MyConfig.h"
|
||||
#include "MyTransport.h"
|
||||
#include "MyProtocol.h"
|
||||
#include <string.h>
|
||||
|
||||
uint8_t protocolH2i(char c);
|
||||
|
||||
@@ -32,7 +33,6 @@ bool protocolParse(MyMessage &message, char *inputString) {
|
||||
uint8_t blen = 0;
|
||||
int i = 0;
|
||||
uint8_t command = 0;
|
||||
uint8_t ack = 0;
|
||||
|
||||
// Extract command data coming on serial line
|
||||
for (str = strtok_r(inputString, ";", &p); // split using semicolon
|
||||
@@ -51,7 +51,7 @@ bool protocolParse(MyMessage &message, char *inputString) {
|
||||
mSetCommand(message, command);
|
||||
break;
|
||||
case 3: // Should we request ack from destination?
|
||||
ack = atoi(str);
|
||||
mSetRequestAck(message, atoi(str)?1:0);
|
||||
break;
|
||||
case 4: // Data type
|
||||
message.type = atoi(str);
|
||||
@@ -86,8 +86,7 @@ bool protocolParse(MyMessage &message, char *inputString) {
|
||||
|
||||
message.sender = GATEWAY_ADDRESS;
|
||||
message.last = GATEWAY_ADDRESS;
|
||||
mSetRequestAck(message, ack?1:0);
|
||||
mSetAck(message, false);
|
||||
mSetAck(message, false);
|
||||
if (command == C_STREAM)
|
||||
message.set(bvalue, blen);
|
||||
else
|
||||
@@ -100,6 +99,95 @@ char * protocolFormat(MyMessage &message) {
|
||||
return _fmtBuffer;
|
||||
}
|
||||
|
||||
char * protocolFormatMQTTTopic(const char* prefix, MyMessage &message) {
|
||||
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR("%s/%d/%d/%d/%d/%d"), prefix, message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type);
|
||||
return _fmtBuffer;
|
||||
}
|
||||
|
||||
char * protocolFormatMQTTSubscribe(const char* prefix) {
|
||||
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR("%s/+/+/+/+/+"), prefix);
|
||||
return _fmtBuffer;
|
||||
}
|
||||
|
||||
#ifdef MY_GATEWAY_MQTT_CLIENT
|
||||
bool protocolMQTTParse(MyMessage &message, char* topic, uint8_t* payload, unsigned int length) {
|
||||
char *str, *p;
|
||||
uint8_t i = 0;
|
||||
uint8_t bvalue[MAX_PAYLOAD];
|
||||
uint8_t blen = 0;
|
||||
uint8_t command = 0;
|
||||
|
||||
for (str = strtok_r(topic, "/", &p); str && i <= 5;
|
||||
str = strtok_r(NULL, "/", &p)) {
|
||||
switch (i) {
|
||||
case 0: {
|
||||
// Topic prefix
|
||||
if (strcmp(str, MY_MQTT_SUBSCRIBE_TOPIC_PREFIX) != 0) {
|
||||
// Message not for us or malformed!
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
// Node id
|
||||
message.destination = atoi(str);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// Sensor id
|
||||
message.sensor = atoi(str);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
// Command type
|
||||
command = atoi(str);
|
||||
mSetCommand(message, command);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// Ack flag
|
||||
mSetRequestAck(message, atoi(str)?1:0);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
// Sub type
|
||||
message.type = atoi(str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i != 6)
|
||||
return false;
|
||||
|
||||
message.sender = GATEWAY_ADDRESS;
|
||||
message.last = GATEWAY_ADDRESS;
|
||||
mSetAck(message, false);
|
||||
|
||||
// Add payload
|
||||
if (command == C_STREAM) {
|
||||
blen = 0;
|
||||
uint8_t val;
|
||||
while (*payload) {
|
||||
val = protocolH2i(*payload++) << 4;
|
||||
val += protocolH2i(*payload++);
|
||||
bvalue[blen] = val;
|
||||
blen++;
|
||||
}
|
||||
message.set(bvalue, blen);
|
||||
} else {
|
||||
char* ca;
|
||||
ca = (char *) payload;
|
||||
ca += length;
|
||||
*ca = '\0';
|
||||
message.set((const char*) payload);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t protocolH2i(char c) {
|
||||
uint8_t i = 0;
|
||||
if (c <= '9')
|
||||
@@ -110,5 +198,3 @@ uint8_t protocolH2i(char c) {
|
||||
i += c - 'A' + 10;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +51,10 @@ void _process() {
|
||||
transportProcess();
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
// To avoid high cpu usage
|
||||
usleep(10000); // 10ms
|
||||
#endif
|
||||
}
|
||||
|
||||
void _infiniteLoop() {
|
||||
@@ -61,17 +65,17 @@ void _infiniteLoop() {
|
||||
#if defined (MY_DEFAULT_TX_LED_PIN) || defined(MY_DEFAULT_RX_LED_PIN) || defined(MY_DEFAULT_ERR_LED_PIN)
|
||||
ledsProcess();
|
||||
#endif
|
||||
#if defined(__linux__)
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void _begin() {
|
||||
|
||||
if (preHwInit)
|
||||
preHwInit();
|
||||
|
||||
#if !defined(MY_DISABLED_SERIAL)
|
||||
hwInit();
|
||||
#endif
|
||||
hwInit();
|
||||
|
||||
debug(PSTR("MCO:BGN:INIT " MY_NODE_TYPE ",CP=" MY_CAPABILITIES ",VER=" MYSENSORS_LIBRARY_VERSION "\n"));
|
||||
|
||||
|
||||
@@ -37,22 +37,6 @@
|
||||
*
|
||||
* MySensorsCore debug log messages:
|
||||
*
|
||||
<<<<<<< HEAD
|
||||
* |E| SYS | SUB | Message | Comment
|
||||
* |-|------|-------|-------------------------------------------|----------------------------------------------------------------------------
|
||||
* | | MCO | BGN | INIT %%s,CP=%%s,LIB=%%s | Core initialization, capabilities (CP), library version (VER)
|
||||
* | | MCO | BGN | BFR | Callback before()
|
||||
* | | MCO | BGN | STP | Callback setup()
|
||||
* | | MCO | BGN | INIT OK,ID=%%d,PAR=%%d,DIS=%%d,REG=%%d | Core initialized, parent ID (PAR), distance to GW (DIS), registration (REG)
|
||||
* | | MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter)
|
||||
* |!| MCO | BGN | TSP FAIL | Transport initialisation failed
|
||||
* | | MCO | REG | REQ | Registration request
|
||||
* | | MCO | REG | NOT NEEDED | No registration needed (i.e. GW)
|
||||
* |!| MCO | SND | NODE NOT REG | Node is not registered, cannot send message
|
||||
* | | MCO | PIM | NODE REG=%%d | Registration response received, registration status (REG)
|
||||
* | | MCO | PIM | ROUTE N=%%d,R=%%d | Routing table, messages to node (N) are routed via node (R)
|
||||
* | | MCO | NLK | NODE LOCKED. UNLOCK: GND PIN %%d AND RESET| Node locked during booting, see signing chapter for additional information
|
||||
=======
|
||||
* |E| SYS | SUB | Message | Comment
|
||||
* |-|------|-------|-----------------------------------------------|----------------------------------------------------------------------------
|
||||
* | | MCO | BGN | INIT %%s,CP=%%s,LIB=%%s | Core initialization, capabilities (CP), library version (VER)
|
||||
@@ -73,7 +57,6 @@
|
||||
* |!| MCO | SLP | REP | Sleeping not possible, repeater feature enabled
|
||||
* | | MCO | NLK | NODE LOCKED. UNLOCK: GND PIN %%d AND RESET | Node locked during booting, see signing chapter for additional information
|
||||
* | | MCO | NLK | TPD | Powerdown transport
|
||||
>>>>>>> development
|
||||
*
|
||||
*
|
||||
* @brief API declaration for MySensorsCore
|
||||
|
||||
@@ -583,6 +583,8 @@ void transportProcessMessage(void) {
|
||||
|
||||
// Is message addressed to this node?
|
||||
if (destination == _nc.nodeId) {
|
||||
// prevent buffer overflow by limiting max. possible message length (5 bits=31 bytes max) to MAX_PAYLOAD (25 bytes)
|
||||
mSetLength(_msg, min(mGetLength(_msg),(uint8_t)MAX_PAYLOAD));
|
||||
// null terminate data
|
||||
_msg.data[msgLength] = 0u;
|
||||
// Check if sender requests an ack back.
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
|
||||
#include "MyConfig.h"
|
||||
#include "MyTransport.h"
|
||||
|
||||
#include "drivers/RF24/RF24.h"
|
||||
|
||||
#include "drivers/CircularBuffer/CircularBuffer.h"
|
||||
|
||||
#if defined(MY_RF24_ENABLE_ENCRYPTION)
|
||||
|
||||
@@ -57,12 +57,7 @@
|
||||
#include "MyTransport.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
#include "MyTransport.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user