Skip to content

Commit

Permalink
fix: not having an mqtt server running will no longer break the runtime
Browse files Browse the repository at this point in the history
Previously, the board would stop creating totp codes, and eventually hang,
if the mqtt server was suddently stopped or if there wasn't a running mqtt server to connect.
This happens when the connection attempt timeout is longer than the MQTT_RECONNECT_INTERVAL.
Now, connections aren't going to be attempted if MQTT_SERVER and MQTT_PORT config properties
aren't set. Moreoever, if the MQTT server stops, the board no longer hangs in an infinite loop.
  • Loading branch information
AllanOricil committed May 5, 2024
1 parent 2e21013 commit 4c7f24f
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define KEYS_FILE_PATH "/keys.txt"

// MQTT
#define MQTT_RECONNECT_INTERVAL 5000
#define MQTT_RECONNECT_INTERVAL 60000
#define MQTT_MAX_PAYLOAD_SIZE 1024
#define MQTT_WRITE_NEW_SECRET_TOPIC "esp32-totp-write-new-secret"

Expand Down
127 changes: 85 additions & 42 deletions src/mqtt.cpp
Original file line number Diff line number Diff line change
@@ -1,71 +1,114 @@
#include <WiFi.h>
#include <PubSubClient.h>
#include <stdbool.h>
#include "constants.h"

struct PayloadData {
#ifndef MQTT_USERNAME
#warning "MQTT_USERNAME is not defined! Please define MQTT_USERNAME."
#else
#pragma message "MQTT_USERNAME is set to: " MQTT_USERNAME
#endif

#ifndef MQTT_PASSWORD
#warning "MQTT_PASSWORD is not defined! Please define MQTT_PASSWORD."
#else
#pragma message "MQTT_PASSWORD is set to: " MQTT_PASSWORD
#endif

#ifndef MQTT_SERVER
#warning "MQTT_SERVER is not defined! Please define MQTT_SERVER."
#elif defined(MQTT_PORT)
#pragma message "MQTT_SERVER is set to: " MQTT_SERVER
#pragma message "MQTT_PORT is set to: " MQTT_PORT
WiFiClient espClient;
PubSubClient client(espClient);
#else
#warning "MQTT_SERVER is defined but MQTT_PORT is not defined! Please define MQTT_PORT."
#endif

struct PayloadData{
byte payload[MQTT_MAX_PAYLOAD_SIZE];
unsigned int length;
};

WiFiClient espClient;
PubSubClient client(espClient);
bool isMqttConfigured = false;

char mqttServer[] = MQTT_SERVER;
volatile bool processMqttMessage = false;
volatile PayloadData globalPayload = {{0}, 0};
unsigned long lastReconnectAttempt = 0;


void print_mqtt_topic_message(char *topic, byte *payload, unsigned int length){
// NOTE: Print topic
Serial.print("MQTT Message arrived on topic: ");
Serial.println(topic);

void print_mqtt_topic_message(char* topic, byte* payload, unsigned int length) {
// NOTE: Print topic
Serial.print("MQTT Message arrived on topic: ");
Serial.println(topic);

// NOTE: Print payload
Serial.println("With Payload:");
char message[length+1];
memcpy(message, payload, length);
message[length] = '\0';

Serial.println(message);
// NOTE: Print payload
Serial.println("With Payload:");
char message[length + 1];
memcpy(message, payload, length);
message[length] = '\0';

Serial.println(message);
}

// NOTE: store received message in memory to process it later
void on_mqtt_message_received(char* topic, byte* payload, unsigned int length) {
void on_mqtt_message_received(char *topic, byte *payload, unsigned int length){
print_mqtt_topic_message(topic, payload, length);
if(length <= MQTT_MAX_PAYLOAD_SIZE) {
if(length <= MQTT_MAX_PAYLOAD_SIZE){
processMqttMessage = true;
byte nonVolatilePayload[MQTT_MAX_PAYLOAD_SIZE];
memcpy(nonVolatilePayload, payload, length);
for(unsigned int i = 0; i < length; i++) {
globalPayload.payload[i] = nonVolatilePayload[i];
for (unsigned int i = 0; i < length; i++){
globalPayload.payload[i] = nonVolatilePayload[i];
}
globalPayload.length = length;
}
}

void init_mqtt(){
client.setServer(mqttServer, MQTT_PORT);
client.setCallback(on_mqtt_message_received);

bool connect(const char *topic){
if(strlen(MQTT_USERNAME) && strlen(MQTT_PASSWORD)){
client.connect(topic, MQTT_USERNAME, MQTT_PASSWORD);
} else {
client.connect(topic);
}

return client.connected();
}

void connect_to_mqtt(){
unsigned long currentMillis = millis();
// NOTE: connect to MQTT topics every 5000 ms
static unsigned long lastMqttReconnectAttempt = 0;
if (!client.connected() && (currentMillis - lastMqttReconnectAttempt > MQTT_RECONNECT_INTERVAL)) {
lastMqttReconnectAttempt = currentMillis;
Serial.print("Connecting to MQTT...");
if (client.connect("esp32-mfa-totp-generator")) {
Serial.println("connected");
client.subscribe(MQTT_WRITE_NEW_SECRET_TOPIC);
Serial.println("subscribed to esp32-totp-write-new-secret topic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.printf("will try again in %d ms\n", MQTT_RECONNECT_INTERVAL);
}
} else {
client.loop();
}
void connect_to_topic(const char * topic){
if(connect(topic)){
Serial.println("Connected");
client.subscribe(topic);
Serial.printf("Subscribed to %s\n", topic);
lastReconnectAttempt = 0;
} else {
Serial.printf("Failed, rc=%d. Will try again in %d ms\n", client.state(), MQTT_RECONNECT_INTERVAL);
}
}

void connect_to_mqtt(){
if(isMqttConfigured){
if(!client.connected()){
unsigned long currentMillis = millis();
// NOTE: try to connect to MQTT topics every 5000 ms
if (currentMillis - lastReconnectAttempt > MQTT_RECONNECT_INTERVAL) {
lastReconnectAttempt = currentMillis;
connect_to_topic(MQTT_WRITE_NEW_SECRET_TOPIC);
}
} else {
client.loop();
}
}
}

void init_mqtt(){
if(strlen(MQTT_SERVER) && strlen(MQTT_PORT)){
Serial.println("Configuring MQTT client");
unsigned long mqtt_port = strtoul(MQTT_PORT, NULL, 10);
client.setServer(MQTT_SERVER, mqtt_port);
client.setCallback(on_mqtt_message_received);
isMqttConfigured = true;
}
}

0 comments on commit 4c7f24f

Please sign in to comment.