Some code clean, and buffer overflow prevention (2) (#126)
* Remove trailing whitespaces
* RFM69toMQTT: Add the emitting nodeID to the topic, +
- And remove radio.receiveDone() that is unecessary.
- Send the ACK before the publish to MQTT, to be faster
- Prevent buffer overflow, Terminate the data with a "\0"
- Fix issue with the sender doesn't end its string with "\0"
and rely only on DATALEN.
* Change topic subjectGTWRFM69toMQTT to be distinct from the commands
+ comments
* MQTTtoRFM69: deduplicate the code
- Check once and only once if the topic is good.
- Have or not RCV_ marked doesn't change the structure, as
valueRCV is correctly set anyway
+ realign
* MQTTtoRFM69: Limit the size of the data
- Cut the packet to the limit of what can transmit RFM69
- and terminate the string
* RFM69toMQTT: ACK MQTT message on subjectGTWRFM69toMQTT now contains the nodeID
* RFM69: Publish to MQTT the RSSI on transmit and ACK
This commit is contained in:
1 parent
d9e2e1d482
commit
254e616f31
2 files changed
+83
-65
No files matched your search
+66
-52
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
OpenMQTTGateway - ESP8266 or Arduino program for home automation
|
||||
/*
|
||||
OpenMQTTGateway - ESP8266 or Arduino program for home automation
|
||||
|
||||
Act as a wifi or ethernet gateway between your RF/infrared IR signal and a MQTT broker
|
||||
Act as a wifi or ethernet gateway between your RF/infrared IR signal and a MQTT broker
|
||||
Send and receiving command by MQTT
|
||||
|
||||
|
||||
This gateway enables to:
|
||||
- receive MQTT data from a topic and send RF signal corresponding to the received MQTT data with an RFM69 module
|
||||
- publish MQTT data to a different topic related to received signal from an RFM69 module
|
||||
@@ -12,9 +12,9 @@
|
||||
Library and code by Felix Rusu - felix@lowpowerlab.com
|
||||
Modification of the code nanohab from bbx10 https://github.com/bbx10/nanohab
|
||||
Copyright: (c)Florian ROBERT
|
||||
|
||||
|
||||
This file is part of OpenMQTTGateway.
|
||||
|
||||
|
||||
OpenMQTTGateway is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -103,7 +103,7 @@ void setupRFM69(void) {
|
||||
{
|
||||
trc(F("RFM69 initialization failed"));
|
||||
}
|
||||
|
||||
|
||||
if (GC_IS_RFM69HCW) {
|
||||
radio.setHighPower(); // Only for RFM69HCW & HW!
|
||||
}
|
||||
@@ -138,32 +138,52 @@ void setupRFM69(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef subjectRFM69toMQTTrssi
|
||||
void publishRSSI(int16_t rssi) {
|
||||
// Send the value of the rssi to MQTT
|
||||
char buff[sizeof(subjectRFM69toMQTTrssi)+4];
|
||||
sprintf(buff, "%s/%d", subjectRFM69toMQTTrssi, radio.SENDERID);
|
||||
char buff_rssi[5];
|
||||
sprintf(buff_rssi, "%d", radio.RSSI);
|
||||
boolean result = client.publish(buff, buff_rssi);
|
||||
}
|
||||
#else
|
||||
#define publishRSSI(input)
|
||||
#endif
|
||||
|
||||
boolean RFM69toMQTT(void) {
|
||||
//check if something was received (could be an interrupt from the radio)
|
||||
if (radio.receiveDone())
|
||||
{
|
||||
|
||||
uint8_t data[RF69_MAX_DATA_LEN];
|
||||
uint8_t data[RF69_MAX_DATA_LEN+1]; // For the null character
|
||||
uint8_t SENDERID = radio.SENDERID;
|
||||
uint8_t DATALEN = radio.DATALEN;
|
||||
uint16_t RSSI = radio.RSSI;
|
||||
|
||||
//save packet because it may be overwritten
|
||||
memcpy(data, (void *)radio.DATA, radio.DATALEN);
|
||||
client.publish(subjectRFM69toMQTT,(char *)data);
|
||||
|
||||
trc(F("Data received"));
|
||||
trc((const char *)data);
|
||||
memcpy(data, (void *)radio.DATA, DATALEN);
|
||||
data[DATALEN] = '\0'; // Terminate the string
|
||||
|
||||
// Ack as soon as possible
|
||||
//check if sender wanted an ACK
|
||||
if (radio.ACKRequested())
|
||||
{
|
||||
radio.sendACK();
|
||||
}
|
||||
radio.receiveDone(); //put radio in RX mode
|
||||
//updateClients(senderId, rssi, (const char *)data);
|
||||
|
||||
trc(F("Data received"));
|
||||
trc((const char *)data);
|
||||
|
||||
char buff[sizeof(subjectRFM69toMQTT)+4];
|
||||
sprintf(buff, "%s/%d", subjectRFM69toMQTT, SENDERID);
|
||||
client.publish(buff,(char *)data);
|
||||
|
||||
publishRSSI(RSSI);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
} else {
|
||||
radio.receiveDone(); //put radio in RX mode
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -172,53 +192,48 @@ boolean MQTTtoRFM69(char * topicOri, char * datacallback) {
|
||||
int loops;
|
||||
uint32_t startMillis;
|
||||
static uint32_t deltaMillis = 0;
|
||||
// RF DATA ANALYSIS
|
||||
//We look into the subject to see if a special RF protocol is defined
|
||||
|
||||
bool good_topic = true;
|
||||
for (int i=0; i<strlen(subjectMQTTtoRFM69); i++) {
|
||||
if (topicOri[i] != subjectMQTTtoRFM69[i])
|
||||
good_topic = false;
|
||||
}
|
||||
if (!good_topic) {
|
||||
Serial.println("Wrong topic");
|
||||
return false;
|
||||
}
|
||||
trc(F("MQTTtoRFM69"));
|
||||
|
||||
char data[RF69_MAX_DATA_LEN+1];
|
||||
memcpy(data, (void *)datacallback, RF69_MAX_DATA_LEN);
|
||||
data[RF69_MAX_DATA_LEN] = '\0';
|
||||
|
||||
//We look into the subject to see if a special RF protocol is defined
|
||||
String topic = topicOri;
|
||||
int valueRCV = defaultRFM69ReceiverId; //default receiver id value
|
||||
int pos = topic.lastIndexOf(RFM69receiverKey);
|
||||
int pos = topic.lastIndexOf(RFM69receiverKey);
|
||||
if (pos != -1){
|
||||
pos = pos + +strlen(RFM69receiverKey);
|
||||
valueRCV = (topic.substring(pos,pos + 3)).toInt();
|
||||
trc(F("RFM69 receiver ID:"));
|
||||
trc(String(valueRCV));
|
||||
}
|
||||
if ((topic == subjectMQTTtoRFM69) && (valueRCV == defaultRFM69ReceiverId)){
|
||||
trc(F("MQTTtoRFM69 default"));
|
||||
loops = 10;
|
||||
startMillis = millis();
|
||||
while (loops--) {
|
||||
if(radio.sendWithRetry(valueRCV, datacallback, strlen(datacallback)+1)) {
|
||||
if(radio.sendWithRetry(valueRCV, data, strlen(data))) {
|
||||
deltaMillis = millis() - startMillis;
|
||||
Serial.print(" OK ");
|
||||
Serial.println(deltaMillis);
|
||||
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFM69toMQTT, datacallback);
|
||||
if (result)trc(F("Ack published"));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Serial.print("!");
|
||||
}
|
||||
delay(50);
|
||||
}
|
||||
if (loops <= 0) {
|
||||
deltaMillis = 0;
|
||||
trc(F("RFM69 sending failed"));
|
||||
return false;
|
||||
}
|
||||
} else if (valueRCV != defaultRFM69ReceiverId) {
|
||||
trc(F("MQTTtoRFM69 user parameters"));
|
||||
loops = 10;
|
||||
startMillis = millis();
|
||||
while (loops--) {
|
||||
if(radio.sendWithRetry(valueRCV, datacallback, strlen(datacallback)+1)) {
|
||||
deltaMillis = millis() - startMillis;
|
||||
Serial.print(" OK ");
|
||||
Serial.println(deltaMillis);
|
||||
// Acknowledgement to the GTWRF topic
|
||||
boolean result = client.publish(subjectGTWRFM69toMQTT, datacallback);
|
||||
if (result)trc(F("Ack published"));
|
||||
char buff[sizeof(subjectGTWRFM69toMQTT)+4];
|
||||
sprintf(buff, "%s/%d", subjectGTWRFM69toMQTT, radio.SENDERID);
|
||||
boolean result = client.publish(buff, data);
|
||||
if (result)trc(F("Ack published"));
|
||||
|
||||
publishRSSI(radio.RSSI);
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -228,9 +243,8 @@ if ((topic == subjectMQTTtoRFM69) && (valueRCV == defaultRFM69ReceiverId)){
|
||||
}
|
||||
if (loops <= 0) {
|
||||
deltaMillis = 0;
|
||||
trc(F("RFM69 sending failed"));
|
||||
return false;
|
||||
trc(F("RFM69 sending failed"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+17
-13
@@ -1,15 +1,15 @@
|
||||
/*
|
||||
OpenMQTTGateway - ESP8266 or Arduino program for home automation
|
||||
/*
|
||||
OpenMQTTGateway - ESP8266 or Arduino program for home automation
|
||||
|
||||
Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker
|
||||
Act as a wifi or ethernet gateway between your 433mhz/infrared IR signal and a MQTT broker
|
||||
Send and receiving command by MQTT
|
||||
|
||||
|
||||
This files enables to set your parameter for the radiofrequency gateways (ZgatewayRF and ZgatewayRF2) with RCswitch and newremoteswitch library
|
||||
|
||||
|
||||
Copyright: (c)Florian ROBERT
|
||||
|
||||
|
||||
This file is part of OpenMQTTGateway.
|
||||
|
||||
|
||||
OpenMQTTGateway is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -25,12 +25,18 @@
|
||||
*/
|
||||
|
||||
/*----------------------RFM69 topics & parameters -------------------------*/
|
||||
// Topic where the message from RFM69 will be published by the gateway,
|
||||
// appended with the nodeID of the sender
|
||||
#define subjectRFM69toMQTT "home/RFM69toMQTT"
|
||||
#define subjectRFM69toMQTTrssi "home/RFM69toMQTT/rssi"
|
||||
// Upon reception of a packed, the RSSI of that packet will be publish to this topic,
|
||||
// appended with the nodeID of the sender
|
||||
#define subjectRFM69toMQTTrssi "home/RFM69toMQTT/rssi" // Comment this if you don't want the RSSI to be published.
|
||||
#define subjectRFM69toMQTTsender "home/RFM69toMQTT/sender"
|
||||
// Topic subscribed by the gateway. Messages received will be sent to RFM69
|
||||
#define subjectMQTTtoRFM69 "home/commands/MQTTtoRFM69"
|
||||
#define RFM69receiverKey "RCV_" // receiver id will be defined if a subject contains RFM69receiverKey followed by a value of 3 digits
|
||||
#define subjectGTWRFM69toMQTT "home/RFM69toMQTT"
|
||||
// On reception of an ack from RFM69, the message that has been sent is published here
|
||||
#define subjectGTWRFM69toMQTT "home/RFM69toMQTT/acked"
|
||||
#define defaultRFM69ReceiverId 99
|
||||
|
||||
// Default values
|
||||
@@ -48,9 +54,9 @@ const char PROGMEM RFM69AP_NAME[] = "RFM69-AP";
|
||||
#define IS_RFM69HCW true // set to 'true' if you are using an RFM69HCW module
|
||||
#define POWER_LEVEL 31
|
||||
|
||||
/*-------------------PIN DEFINITIONS----------------------*/
|
||||
/*-------------------PIN DEFINITIONS----------------------*/
|
||||
#ifdef ESP8266
|
||||
#define RFM69_CS D1
|
||||
#define RFM69_CS D1
|
||||
#define RFM69_IRQ D8 // GPIO15/D8
|
||||
#define RFM69_IRQN digitalPinToInterrupt(RFM69_IRQ)
|
||||
#define RFM69_RST D4 // GPIO02/D4
|
||||
@@ -61,5 +67,3 @@ const char PROGMEM RFM69AP_NAME[] = "RFM69-AP";
|
||||
#define RFM69_IRQN digitalPinToInterrupt(RFM69_IRQ)
|
||||
#define RFM69_RST 9
|
||||
#endif
|
||||
|
||||
|
||||
Reference in new issue
Block a user