Rewrite comments and added hudge payload test
This commit is contained in:
@@ -1,14 +1,6 @@
|
|||||||
#include "TinyMqtt.h"
|
#include "TinyMqtt.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
void outstring(const char* prefix, const char*p, uint16_t len)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
Serial << prefix << "='";
|
|
||||||
while(len--) Serial << (char)*p++;
|
|
||||||
Serial << '\'' << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
MqttBroker::MqttBroker(uint16_t port)
|
MqttBroker::MqttBroker(uint16_t port)
|
||||||
{
|
{
|
||||||
server = new TcpServer(port);
|
server = new TcpServer(port);
|
||||||
@@ -447,11 +439,9 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
|
|||||||
if (mqtt_flags & FlagWill) // Will topic
|
if (mqtt_flags & FlagWill) // Will topic
|
||||||
{
|
{
|
||||||
mesg->getString(payload, len); // Will Topic
|
mesg->getString(payload, len); // Will Topic
|
||||||
outstring("WillTopic", payload, len);
|
|
||||||
payload += len;
|
payload += len;
|
||||||
|
|
||||||
mesg->getString(payload, len); // Will Message
|
mesg->getString(payload, len); // Will Message
|
||||||
outstring("WillMessage", payload, len);
|
|
||||||
payload += len;
|
payload += len;
|
||||||
}
|
}
|
||||||
// FIXME forgetting credential is allowed (security hole)
|
// FIXME forgetting credential is allowed (security hole)
|
||||||
@@ -468,7 +458,9 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
|
|||||||
payload += len;
|
payload += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TINY_MQTT_DEBUG
|
||||||
Serial << "Connected client:" << clientId.c_str() << ", keep alive=" << keep_alive << '.' << endl;
|
Serial << "Connected client:" << clientId.c_str() << ", keep alive=" << keep_alive << '.' << endl;
|
||||||
|
#endif
|
||||||
bclose = false;
|
bclose = false;
|
||||||
mqtt_connected=true;
|
mqtt_connected=true;
|
||||||
{
|
{
|
||||||
@@ -522,7 +514,6 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
|
|||||||
{
|
{
|
||||||
mesg->getString(payload, len); // Topic
|
mesg->getString(payload, len); // Topic
|
||||||
debug( " topic (" << std::string(payload, len) << ')');
|
debug( " topic (" << std::string(payload, len) << ')');
|
||||||
outstring(" un/subscribes", payload, len);
|
|
||||||
// subscribe(Topic(payload, len));
|
// subscribe(Topic(payload, len));
|
||||||
Topic topic(payload, len);
|
Topic topic(payload, len);
|
||||||
payload += len;
|
payload += len;
|
||||||
@@ -602,10 +593,12 @@ if (mesg->type() != MqttMessage::Type::PingReq && mesg->type() != MqttMessage::T
|
|||||||
};
|
};
|
||||||
if (bclose)
|
if (bclose)
|
||||||
{
|
{
|
||||||
|
#ifdef TINY_MQTT_DEBUG
|
||||||
Serial << "*************** Error msg 0x" << _HEX(mesg->type());
|
Serial << "*************** Error msg 0x" << _HEX(mesg->type());
|
||||||
mesg->hexdump("-------ERROR ------");
|
mesg->hexdump("-------ERROR ------");
|
||||||
dump();
|
dump();
|
||||||
Serial << endl;
|
Serial << endl;
|
||||||
|
#endif
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -722,8 +715,10 @@ void MqttMessage::incoming(char in_byte)
|
|||||||
break;
|
break;
|
||||||
case Complete:
|
case Complete:
|
||||||
default:
|
default:
|
||||||
|
#ifdef TINY_MQTT_DEBUG
|
||||||
Serial << "Spurious " << _HEX(in_byte) << endl;
|
Serial << "Spurious " << _HEX(in_byte) << endl;
|
||||||
hexdump("spurious");
|
hexdump("spurious");
|
||||||
|
#endif
|
||||||
reset();
|
reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -778,6 +773,8 @@ MqttError MqttMessage::sendTo(MqttClient* client)
|
|||||||
|
|
||||||
void MqttMessage::hexdump(const char* prefix) const
|
void MqttMessage::hexdump(const char* prefix) const
|
||||||
{
|
{
|
||||||
|
(void)prefix;
|
||||||
|
#ifdef TINY_MQTT_DEBUG
|
||||||
uint16_t addr=0;
|
uint16_t addr=0;
|
||||||
const int bytes_per_row = 8;
|
const int bytes_per_row = 8;
|
||||||
const char* hex_to_str = " | ";
|
const char* hex_to_str = " | ";
|
||||||
@@ -813,4 +810,5 @@ void MqttMessage::hexdump(const char* prefix) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
Serial << endl;
|
Serial << endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
// #define TINY_MQTT_DEBUG
|
// #define TINY_MQTT_DEBUG
|
||||||
|
|
||||||
#ifdef TINY_MQTT_DEBUG
|
#ifdef TINY_MQTT_DEBUG
|
||||||
#define debug(what) { Serial << __LINE__ << ' ' << what << endl; delay(100); }
|
#define debug(what) { Serial << (int)__LINE__ << ' ' << what << endl; delay(100); }
|
||||||
#else
|
#else
|
||||||
#define debug(what) {}
|
#define debug(what) {}
|
||||||
#endif
|
#endif
|
||||||
@@ -160,6 +160,8 @@ class MqttClient
|
|||||||
void connect(MqttBroker* parent);
|
void connect(MqttBroker* parent);
|
||||||
void connect(std::string broker, uint16_t port, uint16_t keep_alive = 10);
|
void connect(std::string broker, uint16_t port, uint16_t keep_alive = 10);
|
||||||
|
|
||||||
|
// TODO it seems that connected returns true in tcp mode even if
|
||||||
|
// no negociation occured (only if tcp link is established)
|
||||||
bool connected() { return
|
bool connected() { return
|
||||||
(parent!=nullptr and client==nullptr) or
|
(parent!=nullptr and client==nullptr) or
|
||||||
(client and client->connected()); }
|
(client and client->connected()); }
|
||||||
@@ -198,6 +200,8 @@ class MqttClient
|
|||||||
|
|
||||||
void dump(std::string indent="")
|
void dump(std::string indent="")
|
||||||
{
|
{
|
||||||
|
(void)indent;
|
||||||
|
#ifdef TINY_MQTT_DEBUG
|
||||||
uint32_t ms=millis();
|
uint32_t ms=millis();
|
||||||
Serial << indent << "+-- " << '\'' << clientId.c_str() << "' " << (connected() ? " ON " : " OFF");
|
Serial << indent << "+-- " << '\'' << clientId.c_str() << "' " << (connected() ? " ON " : " OFF");
|
||||||
Serial << ", alive=" << alive << '/' << ms << ", ka=" << keep_alive << ' ';
|
Serial << ", alive=" << alive << '/' << ms << ", ka=" << keep_alive << ' ';
|
||||||
@@ -207,6 +211,7 @@ class MqttClient
|
|||||||
bool c = false;
|
bool c = false;
|
||||||
Serial << " [";
|
Serial << " [";
|
||||||
for(auto s: subscriptions)
|
for(auto s: subscriptions)
|
||||||
|
(void)indent;
|
||||||
{
|
{
|
||||||
if (c) Serial << ", ";
|
if (c) Serial << ", ";
|
||||||
Serial << s.str().c_str();
|
Serial << s.str().c_str();
|
||||||
@@ -215,6 +220,7 @@ class MqttClient
|
|||||||
Serial << ']';
|
Serial << ']';
|
||||||
}
|
}
|
||||||
Serial << endl;
|
Serial << endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static long counter; // Number of processed messages
|
static long counter; // Number of processed messages
|
||||||
@@ -235,7 +241,7 @@ class MqttClient
|
|||||||
MqttError publishIfSubscribed(const Topic& topic, MqttMessage& msg);
|
MqttError publishIfSubscribed(const Topic& topic, MqttMessage& msg);
|
||||||
|
|
||||||
void clientAlive(uint32_t more_seconds);
|
void clientAlive(uint32_t more_seconds);
|
||||||
void processMessage(const MqttMessage* message);
|
void processMessage(MqttMessage* message);
|
||||||
|
|
||||||
bool mqtt_connected = false;
|
bool mqtt_connected = false;
|
||||||
char mqtt_flags;
|
char mqtt_flags;
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
# See https://github.com/bxparks/EpoxyDuino for documentation about this
|
# See https://github.com/bxparks/EpoxyDuino for documentation about this
|
||||||
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
|
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
|
||||||
|
|
||||||
|
EXTRA_CXXFLAGS=-g3 -O0
|
||||||
|
|
||||||
|
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
||||||
|
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
||||||
|
|
||||||
APP_NAME := local-tests
|
APP_NAME := local-tests
|
||||||
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP
|
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP
|
||||||
ARDUINO_LIB_DIRS := ../../../EspMock/libraries
|
ARDUINO_LIB_DIRS := ../../../EspMock/libraries
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ test(local_publish_should_be_dispatched)
|
|||||||
publisher.publish("a/c");
|
publisher.publish("a/c");
|
||||||
|
|
||||||
assertEqual(published.size(), (size_t)1); // 1 client has received something
|
assertEqual(published.size(), (size_t)1); // 1 client has received something
|
||||||
assertTrue(published[""]["a/b"] == 1);
|
assertEqual(published[""]["a/b"], 1);
|
||||||
assertTrue(published[""]["a/c"] == 2);
|
assertEqual(published[""]["a/c"], 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
test(local_publish_should_be_dispatched_to_local_clients)
|
test(local_publish_should_be_dispatched_to_local_clients)
|
||||||
@@ -91,10 +91,10 @@ test(local_publish_should_be_dispatched_to_local_clients)
|
|||||||
publisher.publish("a/c");
|
publisher.publish("a/c");
|
||||||
|
|
||||||
assertEqual(published.size(), (size_t)2); // 2 clients have received something
|
assertEqual(published.size(), (size_t)2); // 2 clients have received something
|
||||||
assertTrue(published["A"]["a/b"] == 1);
|
assertEqual(published["A"]["a/b"], 1);
|
||||||
assertTrue(published["A"]["a/c"] == 1);
|
assertEqual(published["A"]["a/c"], 1);
|
||||||
assertTrue(published["B"]["a/b"] == 1);
|
assertEqual(published["B"]["a/b"], 1);
|
||||||
assertTrue(published["B"]["a/c"] == 0);
|
assertEqual(published["B"]["a/c"], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
test(local_unsubscribe)
|
test(local_unsubscribe)
|
||||||
@@ -114,7 +114,7 @@ test(local_unsubscribe)
|
|||||||
publisher.publish("a/b");
|
publisher.publish("a/b");
|
||||||
publisher.publish("a/b");
|
publisher.publish("a/b");
|
||||||
|
|
||||||
assertTrue(published[""]["a/b"] == 1); // Only one publish has been received
|
assertEqual(published[""]["a/b"], 1); // Only one publish has been received
|
||||||
}
|
}
|
||||||
|
|
||||||
test(local_nocallback_when_destroyed)
|
test(local_nocallback_when_destroyed)
|
||||||
|
|||||||
@@ -19,6 +19,18 @@ std::map<std::string, std::map<Topic, int>> published; // map[client_id] => map
|
|||||||
char* lastPayload = nullptr;
|
char* lastPayload = nullptr;
|
||||||
size_t lastLength;
|
size_t lastLength;
|
||||||
|
|
||||||
|
void start_servers(int n, bool early_accept = true)
|
||||||
|
{
|
||||||
|
ESP8266WiFiClass::resetInstances();
|
||||||
|
ESP8266WiFiClass::earlyAccept = early_accept;
|
||||||
|
while(n)
|
||||||
|
{
|
||||||
|
ESP8266WiFiClass::selectInstance(n--);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin("fake_ssid", "fake_pwd");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length)
|
void onPublish(const MqttClient* srce, const Topic& topic, const char* payload, size_t length)
|
||||||
{
|
{
|
||||||
if (srce)
|
if (srce)
|
||||||
@@ -41,43 +53,90 @@ test(network_single_broker_begin)
|
|||||||
|
|
||||||
test(network_client_to_broker_connexion)
|
test(network_client_to_broker_connexion)
|
||||||
{
|
{
|
||||||
|
start_servers(2, true);
|
||||||
|
|
||||||
assertEqual(WiFi.status(), WL_CONNECTED);
|
assertEqual(WiFi.status(), WL_CONNECTED);
|
||||||
|
|
||||||
MqttBroker broker(1883);
|
MqttBroker broker(1883);
|
||||||
broker.begin();
|
broker.begin();
|
||||||
|
IPAddress broker_ip = WiFi.localIP();
|
||||||
|
|
||||||
Serial << "TODO IP = " << WiFi.localIP() << endl;
|
ESP8266WiFiClass::selectInstance(2);
|
||||||
|
|
||||||
MqttClient client;
|
MqttClient client;
|
||||||
client.connect(WiFi.localIP().toString().c_str(), 1883);
|
client.connect(broker_ip.toString().c_str(), 1883);
|
||||||
broker.loop();
|
broker.loop();
|
||||||
|
|
||||||
assertEqual(broker.clientsCount(), (size_t)1);
|
assertTrue(broker.clientsCount() == 1);
|
||||||
|
assertTrue(client.connected());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
test(network_one_client_one_broker_publish_and_subscribe_through_network)
|
||||||
test(network_one_broker_one_client)
|
|
||||||
{
|
{
|
||||||
|
start_servers(2, true);
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(WiFi.status(), WL_CONNECTED);
|
assertEqual(WiFi.status(), WL_CONNECTED);
|
||||||
|
|
||||||
MqttBroker broker(1883);
|
MqttBroker broker(1883);
|
||||||
broker.begin();
|
broker.begin();
|
||||||
|
IPAddress ip_broker = WiFi.localIP();
|
||||||
|
|
||||||
Serial << "TODO IP = " << WiFi.localIP() << endl;
|
// We have a 2nd ESP in order to test through wifi (opposed to local)
|
||||||
|
ESP8266WiFiClass::selectInstance(2);
|
||||||
MqttClient client;
|
MqttClient client;
|
||||||
client.connect(WiFi.localIP().toString().c_str(), 1883);
|
client.connect(ip_broker.toString().c_str(), 1883);
|
||||||
|
broker.loop();
|
||||||
|
assertTrue(client.connected());
|
||||||
|
|
||||||
client.setCallback(onPublish);
|
client.setCallback(onPublish);
|
||||||
client.subscribe("a/b");
|
client.subscribe("a/b");
|
||||||
client.publish("a/b", "ab");
|
client.publish("a/b", "ab");
|
||||||
// client.loop();
|
|
||||||
|
for (int i =0; i<2; i++)
|
||||||
|
{
|
||||||
|
client.loop();
|
||||||
|
broker.loop();
|
||||||
|
}
|
||||||
|
|
||||||
assertEqual(published.size(), (size_t)1);
|
assertEqual(published.size(), (size_t)1);
|
||||||
|
assertEqual((int)lastLength, (int)2); // sizeof(ab)
|
||||||
|
}
|
||||||
|
|
||||||
|
test(network_one_client_one_broker_hudge_publish_and_subscribe_through_network)
|
||||||
|
{
|
||||||
|
start_servers(2, true);
|
||||||
|
published.clear();
|
||||||
|
assertEqual(WiFi.status(), WL_CONNECTED);
|
||||||
|
|
||||||
|
MqttBroker broker(1883);
|
||||||
|
broker.begin();
|
||||||
|
IPAddress ip_broker = WiFi.localIP();
|
||||||
|
|
||||||
|
// We have a 2nd ESP in order to test through wifi (opposed to local)
|
||||||
|
ESP8266WiFiClass::selectInstance(2);
|
||||||
|
MqttClient client;
|
||||||
|
client.connect(ip_broker.toString().c_str(), 1883);
|
||||||
|
broker.loop();
|
||||||
|
assertTrue(client.connected());
|
||||||
|
|
||||||
|
std::string sent;
|
||||||
|
|
||||||
|
for(int i=0; i<200; i++)
|
||||||
|
sent += char('0'+i%10);
|
||||||
|
|
||||||
|
client.setCallback(onPublish);
|
||||||
|
client.subscribe("a/b");
|
||||||
|
client.publish("a/b", sent.c_str());
|
||||||
|
|
||||||
|
for (int i =0; i<2; i++)
|
||||||
|
{
|
||||||
|
client.loop();
|
||||||
|
broker.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(published.size(), (size_t)1);
|
||||||
|
assertEqual((unsigned int)lastLength, (unsigned int)sent.size());
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
test(network_client_should_unregister_when_destroyed)
|
test(network_client_should_unregister_when_destroyed)
|
||||||
{
|
{
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.clientsCount(), (size_t)0);
|
||||||
@@ -88,6 +147,11 @@ test(network_client_should_unregister_when_destroyed)
|
|||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.clientsCount(), (size_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// THESE TESTS ARE IN LOCAL MODE
|
||||||
|
// WE HAVE TO CONVERT THEM TO WIFI MODE (pass through virtual TCP link)
|
||||||
|
|
||||||
test(network_connect)
|
test(network_connect)
|
||||||
{
|
{
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.clientsCount(), (size_t)0);
|
||||||
@@ -219,12 +283,12 @@ test(network_hudge_payload)
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// setup() and loop()
|
// setup() and loop()
|
||||||
void setup() {
|
void setup() {
|
||||||
delay(1000);
|
/* delay(1000);
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
while(!Serial);
|
while(!Serial);
|
||||||
|
|
||||||
Serial.println("=============[ FAKE NETWORK TinyMqtt TESTS ]========================");
|
Serial.println("=============[ FAKE NETWORK TinyMqtt TESTS ]========================");
|
||||||
|
*/
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.begin("network", "password");
|
WiFi.begin("network", "password");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user