Skip to content

Support for RadioHead's RHReliableDatagram on ESP32 #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
.idea/
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/extensions.json
.vscode/launch.json
.vscode/ipch
.history
14 changes: 8 additions & 6 deletions MqttSnClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct topic_registration {
uint8_t granted_qos;
};

#ifdef ESP8266
#if defined(ESP8266) || defined(ESP32)
#include <functional>
#define MQTT_SN_CALLBACK_SIGNATURE std::function<void(char*, uint8_t*, uint16_t, bool retain)> callback
#else
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -105,13 +106,13 @@ 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) {

socket_disconnected = false;
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) {
Expand All @@ -129,7 +130,7 @@ class MqttSnClient {
return false;
}
}
system.sleep((tries + 1) * 10 * 1000);
system.sleep((tries + 1) * retry_pause * 1000);
}
// timeout - take another gateway
return false;
Expand Down Expand Up @@ -275,6 +276,7 @@ class MqttSnClient {
}

void notify_socket_connected() {
Serial.println("\nSocket disconnected\n");
this->socket_disconnected = false;
}

Expand Down
2 changes: 2 additions & 0 deletions RHDatagramSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef ARDUINO_MQTT_SN_CLIENT_RHDATAGRAMSOCKET_H
#define ARDUINO_MQTT_SN_CLIENT_RHDATAGRAMSOCKET_H

#include <RHDatagram.h>

#include "MqttSnMessageHandler.h"
#include "SocketInterface.h"

Expand Down
130 changes: 130 additions & 0 deletions RHReliableDatagramSocket.h
Original file line number Diff line number Diff line change
@@ -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 <RHReliableDatagram.h>

#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<class RHReliableDatagramSocket>
void setMqttSnMessageHandler(
MqttSnMessageHandler<RHReliableDatagramSocket> *mqttSnMessageHandler) {
this->mqttSnMessageHandler = mqttSnMessageHandler;
};

template<class RHReliableDatagramSocket>
void setTransmissionProtocolUartBridge(
TransmissionProtocolUartBridge<RHReliableDatagramSocket> *transmissionProtocolUartBridge) {
this->transmissionProtocolUartBridge = transmissionProtocolUartBridge;
};

private:
MqttSnMessageHandler<RHReliableDatagramSocket> *mqttSnMessageHandler = nullptr;
TransmissionProtocolUartBridge<RHReliableDatagramSocket> *transmissionProtocolUartBridge = nullptr;
};

#endif //ARDUINO_MQTT_SN_CLIENT_RHRELIABLEDATAGRAMSOCKET_H
2 changes: 1 addition & 1 deletion System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions TransmissionProtocolUartBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <Stream.h>


#if defined(ESP8266)
#if defined(ESP8266) || defined(ESP32)
#include <cerrno>
#include <climits>
#endif
Expand Down Expand Up @@ -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();
Expand Down
14 changes: 14 additions & 0 deletions global_defines.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <Arduino.h>

#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(", ");
}
}
}
12 changes: 2 additions & 10 deletions global_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 5 additions & 5 deletions mqttsn_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
34 changes: 34 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
@@ -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/> -<examples/> -<test/>
monitor_speed=115200