From c2610e313a962bd8a190a5f81bcac18442f3e1e9 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Fri, 1 May 2020 20:02:51 -0400 Subject: [PATCH 1/7] Support for ESP32 --- System.cpp | 2 +- TransmissionProtocolUartBridge.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/System.cpp b/System.cpp index d3048dd..f93013c 100644 --- a/System.cpp +++ b/System.cpp @@ -36,7 +36,7 @@ void System::sleep(uint32_t duration) { } void System::exit() { -#if defined(ESP8266) +#if defined(ESP8266) || defined(ESP32) ESP.restart(); #elif defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_MEGA2560) asm volatile (" jmp 0"); diff --git a/TransmissionProtocolUartBridge.h b/TransmissionProtocolUartBridge.h index 0388653..59a6b07 100644 --- a/TransmissionProtocolUartBridge.h +++ b/TransmissionProtocolUartBridge.h @@ -15,7 +15,7 @@ #include -#if defined(ESP8266) +#if defined(ESP8266) || defined(ESP32) #include #include #endif @@ -178,7 +178,7 @@ class TransmissionProtocolUartBridge { } void resetChip() { -#if defined(ESP8266) +#if defined(ESP8266) || defined(ESP32) stream->print(F("OK RESET\n")); delay(500); ESP.restart(); From b180f048612634ca9977d22dfedbccb35d4ff939 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Fri, 1 May 2020 20:03:15 -0400 Subject: [PATCH 2/7] Support for PlatformIO --- .gitignore | 7 +++++++ platformio.ini | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 platformio.ini diff --git a/.gitignore b/.gitignore index 9f11b75..626b6f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,8 @@ .idea/ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/extensions.json +.vscode/launch.json +.vscode/ipch +.history diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..26b44d3 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,34 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +src_dir = . + + + +[common_env_data] +build_flags = + -Wall + -Wno-reorder + -Wno-parentheses + +[env:heltec_wifi_kit_32] +platform = espressif32 +board = heltec_wifi_kit_32 +framework = arduino + +build_flags = + ${common_env_data.build_flags} + +;lib_deps = +; RadioHead + +src_filter=+<*.h> +<*.cpp> -<.git/> -<.svn/> - - +monitor_speed=115200 From 61704293dcee0fddf866cf6067366463a1420451 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Fri, 1 May 2020 20:03:42 -0400 Subject: [PATCH 3/7] Move inline function to .cpp to prevent compilation error --- global_defines.cpp | 14 ++++++++++++++ global_defines.h | 12 ++---------- 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 global_defines.cpp diff --git a/global_defines.cpp b/global_defines.cpp new file mode 100644 index 0000000..e5012c1 --- /dev/null +++ b/global_defines.cpp @@ -0,0 +1,14 @@ +#include + +#include "global_defines.h" + +void printDeviceAddress(device_address *address) { + for (uint8_t i = 0; i < sizeof(device_address); i++) { + if (i == sizeof(device_address) - 1) { + Serial.print(address->bytes[i]); + } else { + Serial.print(address->bytes[i]); + Serial.print(", "); + } + } +} diff --git a/global_defines.h b/global_defines.h index ec885f6..b661e59 100644 --- a/global_defines.h +++ b/global_defines.h @@ -31,15 +31,7 @@ struct device_address { } }; -void printDeviceAddress(device_address *address) { - for (uint8_t i = 0; i < sizeof(device_address); i++) { - if (i == sizeof(device_address) - 1) { - Serial.print(address->bytes[i]); - } else { - Serial.print(address->bytes[i]); - Serial.print(", "); - } - } -} + +extern void printDeviceAddress(device_address *address); #endif //ARDUINO_MQTTSN_CLIENT_GLOBAL_DEFINES_H From 056bd4c1297b29cf7d54af3b55a61abb3d206551 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Fri, 1 May 2020 20:04:42 -0400 Subject: [PATCH 4/7] Zero fill size was incorrect - use size of object vs. size of pointer --- mqttsn_messages.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mqttsn_messages.h b/mqttsn_messages.h index faeb051..526b5e5 100644 --- a/mqttsn_messages.h +++ b/mqttsn_messages.h @@ -195,7 +195,7 @@ struct msg_willtopic : public message_header { char will_topic[252]; msg_willtopic(const char *willtopic, int8_t qos, bool retain) { - memset(this, 0, sizeof(this)); + memset(this, 0, sizeof(*this)); length = 3 + strlen(willtopic) + 1; type = MQTTSN_WILLTOPIC; if (retain) { @@ -215,7 +215,7 @@ struct msg_willmsg : public message_header { uint8_t willmsg[253]; msg_willmsg(const uint8_t *s_data, uint8_t s_data_len) { - memset(this, 0, sizeof(this)); + memset(this, 0, sizeof(*this)); this->length = ((uint8_t) 2) + s_data_len; memcpy(&willmsg, s_data, s_data_len); } @@ -279,7 +279,7 @@ struct msg_publish : public message_header { msg_publish(bool dup, int8_t qos, bool retain, bool short_topic, uint16_t topic_id, uint16_t msg_id, const uint8_t *s_data, uint8_t s_data_len) : topic_id(topic_id), message_id(msg_id) { - memset(this, 0, sizeof(this)); + memset(this, 0, sizeof(*this)); this->length = ((uint8_t) 7) + s_data_len; this->type = MQTTSN_PUBLISH; this->flags = 0x0; @@ -349,7 +349,7 @@ struct msg_subscribe_shorttopic : public msg_subscribe { uint16_t topic_id; msg_subscribe_shorttopic(bool short_topic, uint16_t topic_id, uint16_t msg_id, uint8_t qos, bool dup) { - memset(this, 0, sizeof(this)); + memset(this, 0, sizeof(*this)); this->length = 7; this->type = MQTTSN_SUBSCRIBE; @@ -382,7 +382,7 @@ struct msg_subscribe_topicname : public msg_subscribe { char topic_name[250]; msg_subscribe_topicname(const char *topic_name, uint16_t msg_id, uint8_t qos, bool dup) { - memset(this, 0, sizeof(this)); + memset(this, 0, sizeof(*this)); this->length = (uint8_t) (5 + strlen(topic_name) + 1); this->type = MQTTSN_SUBSCRIBE; if (dup) { From b4e4d2ad976bb150f639c65faf04ec38998f31ad Mon Sep 17 00:00:00 2001 From: joelkoz Date: Fri, 1 May 2020 20:05:03 -0400 Subject: [PATCH 5/7] Fix compilation error --- RHDatagramSocket.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RHDatagramSocket.h b/RHDatagramSocket.h index d16bb2f..a2b64f5 100644 --- a/RHDatagramSocket.h +++ b/RHDatagramSocket.h @@ -7,6 +7,8 @@ #ifndef ARDUINO_MQTT_SN_CLIENT_RHDATAGRAMSOCKET_H #define ARDUINO_MQTT_SN_CLIENT_RHDATAGRAMSOCKET_H +#include + #include "MqttSnMessageHandler.h" #include "SocketInterface.h" From d58eeaf66f5f763b0291f108f4c9caa8e1b86d05 Mon Sep 17 00:00:00 2001 From: joelkoz Date: Fri, 1 May 2020 20:05:39 -0400 Subject: [PATCH 6/7] Add optional parameters to connect() to allow clients to better react to missing gateways --- MqttSnClient.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/MqttSnClient.h b/MqttSnClient.h index 9d0e7aa..082732c 100644 --- a/MqttSnClient.h +++ b/MqttSnClient.h @@ -23,7 +23,7 @@ struct topic_registration { uint8_t granted_qos; }; -#ifdef ESP8266 +#if defined(ESP8266) || defined(ESP32) #include #define MQTT_SN_CALLBACK_SIGNATURE std::function callback #else @@ -105,13 +105,12 @@ class MqttSnClient { this->callback = callback; } - bool connect(device_address *address, const char *client_id, uint16_t duration) { - // global verwalten - uint8_t retries = 2; + bool connect(device_address *address, const char *client_id, uint16_t duration, uint8_t retries = 2, uint8_t timeout = 5, uint8_t retry_pause = 10) { + memcpy(&this->gw_address, address, sizeof(device_address)); for (uint8_t tries = 0; tries < retries; tries++) { - system.set_heartbeat(5 * 1000); + system.set_heartbeat(timeout * 1000); mqttSnMessageHandler.send_connect(address, client_id, duration); this->set_await_message(MQTTSN_CONNACK); while (!mqttsn_connected) { @@ -129,7 +128,7 @@ class MqttSnClient { return false; } } - system.sleep((tries + 1) * 10 * 1000); + system.sleep((tries + 1) * retry_pause * 1000); } // timeout - take another gateway return false; From 9490c42242c1c3c450b73a3e23a7ea54792b1aaf Mon Sep 17 00:00:00 2001 From: joelkoz Date: Mon, 4 May 2020 20:26:49 -0400 Subject: [PATCH 7/7] Added RHReliableDatagramSocket Added RHReliableDatagramSocket to support corresponding protocol on server side. --- MqttSnClient.h | 3 + RHReliableDatagramSocket.h | 130 +++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 RHReliableDatagramSocket.h diff --git a/MqttSnClient.h b/MqttSnClient.h index 082732c..0320293 100644 --- a/MqttSnClient.h +++ b/MqttSnClient.h @@ -76,6 +76,7 @@ class MqttSnClient { void notify_socket_disconnected() { this->socket_disconnected = true; + this->mqttsn_connected = false; } void set_await_message(message_type msg_type) { @@ -107,6 +108,7 @@ class MqttSnClient { bool connect(device_address *address, const char *client_id, uint16_t duration, uint8_t retries = 2, uint8_t timeout = 5, uint8_t retry_pause = 10) { + socket_disconnected = false; memcpy(&this->gw_address, address, sizeof(device_address)); for (uint8_t tries = 0; tries < retries; tries++) { @@ -274,6 +276,7 @@ class MqttSnClient { } void notify_socket_connected() { + Serial.println("\nSocket disconnected\n"); this->socket_disconnected = false; } diff --git a/RHReliableDatagramSocket.h b/RHReliableDatagramSocket.h new file mode 100644 index 0000000..7f574cc --- /dev/null +++ b/RHReliableDatagramSocket.h @@ -0,0 +1,130 @@ +/* +* The MIT License (MIT) +* +* Copyright (C) 2018 Gabriel Nikol +*/ + +#ifndef ARDUINO_MQTT_SN_CLIENT_RHDRELIABLEATAGRAMSOCKET_H +#define ARDUINO_MQTT_SN_CLIENT_RHRELIABLEDATAGRAMSOCKET_H + +#include + +#include "MqttSnMessageHandler.h" +#include "SocketInterface.h" + +class RHReliableDatagramSocket : SocketInterface { +private: + RHReliableDatagram &rhDatagram; + + device_address own_address; + device_address broadcast_address; + + bool reliable = true; +public: + RHReliableDatagramSocket(RHReliableDatagram &rhDatagram) : rhDatagram(rhDatagram) {}; + + bool begin() override { + own_address = device_address(rhDatagram.thisAddress(), 0, 0, 0, 0, 0); + broadcast_address = device_address(RH_BROADCAST_ADDRESS, 0, 0, 0, 0, 0); + return rhDatagram.init(); + } + + device_address *getBroadcastAddress() override { + return &broadcast_address; + } + + device_address *getAddress() override { + return &own_address; + } + + uint8_t getMaximumMessageLength() override { + return RH_MAX_MESSAGE_LEN; + } + + bool send(device_address *destination, uint8_t *bytes, uint16_t bytes_len) override { + return send(destination, bytes, bytes_len, UINT8_MAX); + } + + bool send(device_address *destination, uint8_t *bytes, uint16_t bytes_len, uint8_t signal_strength) { + bool sendOk; + + if (reliable) { + sendOk = rhDatagram.sendtoWait(bytes, bytes_len, destination->bytes[0]); + } + else { + sendOk = rhDatagram.sendto(bytes, bytes_len, destination->bytes[0]); + } + rhDatagram.waitPacketSent(); + rhDatagram.available(); // put it back to receive mode + return sendOk; + } + + + + bool receive(device_address *source, uint8_t *bytes, uint16_t bytes_len) { + uint8_t len = bytes_len; + if (reliable) { + bool ok = rhDatagram.recvfromAck(bytes, &len, &(source->bytes[0])); + return ok; + } + else { + return rhDatagram.recvfrom(bytes, &len, &(source->bytes[0])); + } + } + + + /** + * Sets whether or not to use RadioHead's "reliable" acknowledged protocol, or its + * normal one. The default is "not reliable" + */ + void setReliableProtocol(bool isReliable) { this->reliable = isReliable; } + + bool isReliable() { return reliable; } + + + bool loop() override { + + if (rhDatagram.available()) { + + device_address receive_address; + memset(&receive_address, 0x0, sizeof(device_address)); + + uint8_t receive_buffer[RH_MAX_MESSAGE_LEN]; + memset(&receive_buffer, 0x0, RH_MAX_MESSAGE_LEN); + + uint8_t receive_buffer_len = sizeof(receive_buffer); + + if (receive(&receive_address, receive_buffer, receive_buffer_len)) { + + if (mqttSnMessageHandler != nullptr) { + mqttSnMessageHandler->receiveData(&receive_address, receive_buffer); + } + + if (transmissionProtocolUartBridge != nullptr) { + transmissionProtocolUartBridge->receiveData(&receive_address, receive_buffer, receive_buffer_len); + } + + } + } + + return true; + } + + template + void setMqttSnMessageHandler( + MqttSnMessageHandler *mqttSnMessageHandler) { + this->mqttSnMessageHandler = mqttSnMessageHandler; + }; + + template + void setTransmissionProtocolUartBridge( + TransmissionProtocolUartBridge *transmissionProtocolUartBridge) { + this->transmissionProtocolUartBridge = transmissionProtocolUartBridge; + }; + +private: + MqttSnMessageHandler *mqttSnMessageHandler = nullptr; + TransmissionProtocolUartBridge *transmissionProtocolUartBridge = nullptr; +}; + +#endif //ARDUINO_MQTT_SN_CLIENT_RHRELIABLEDATAGRAMSOCKET_H