Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8105ee224 | ||
|
|
670d67c024 | ||
|
|
3c3b19882f | ||
|
|
8c55356bd9 | ||
|
|
82d3b913bb | ||
|
|
8b62b5a3b7 | ||
|
|
3a2db664a8 | ||
|
|
0c454bfe3a | ||
|
|
d517cf2627 | ||
|
|
b8022f58a4 | ||
|
|
09e3a3e45f | ||
|
|
f17ece3376 | ||
|
|
0db07df27b | ||
|
|
292592c3dd | ||
|
|
1f267c135b |
2
.github/workflows/aunit.yml
vendored
2
.github/workflows/aunit.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd ..
|
cd ..
|
||||||
git clone https://github.com/hsaturn/TinyConsole
|
git clone https://github.com/hsaturn/TinyConsole
|
||||||
git clone https://github.com/bxparks/EpoxyDuino
|
git clone https://github.com/hsaturn/EpoxyDuino
|
||||||
git clone https://github.com/bxparks/AceRoutine
|
git clone https://github.com/bxparks/AceRoutine
|
||||||
git clone https://github.com/bxparks/AUnit
|
git clone https://github.com/bxparks/AUnit
|
||||||
git clone https://github.com/bxparks/AceCommon
|
git clone https://github.com/bxparks/AceCommon
|
||||||
|
|||||||
120
src/TinyMqtt.cpp
120
src/TinyMqtt.cpp
@@ -17,19 +17,28 @@ int TinyMqtt::debug=2;
|
|||||||
|
|
||||||
MqttBroker::MqttBroker(uint16_t port)
|
MqttBroker::MqttBroker(uint16_t port)
|
||||||
{
|
{
|
||||||
server = std::unique_ptr<TcpServer>(new TcpServer(port));
|
server.reset(new TcpServer(port));
|
||||||
#ifdef TINY_MQTT_ASYNC
|
#ifdef TINY_MQTT_ASYNC
|
||||||
server->onClient(onClient, this);
|
server->onClient(onClient, this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MqttBroker::~MqttBroker()
|
||||||
|
{
|
||||||
|
while(clients.size())
|
||||||
|
{
|
||||||
|
delete clients[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// private constructor used by broker only
|
// private constructor used by broker only
|
||||||
MqttClient::MqttClient(MqttBroker* local_broker, TcpClient* new_client)
|
MqttClient::MqttClient(MqttBroker* local_broker, TcpClient* new_client)
|
||||||
{
|
{
|
||||||
|
dclass;
|
||||||
connect(local_broker);
|
connect(local_broker);
|
||||||
debug("MqttClient private with broker");
|
debug("MqttClient private with broker");
|
||||||
#ifdef TINY_MQTT_ASYNC
|
#ifdef TINY_MQTT_ASYNC
|
||||||
tcp_client = new_client;
|
tcp_client.reset(new_client);
|
||||||
tcp_client->onData(onData, this);
|
tcp_client->onData(onData, this);
|
||||||
// client->onConnect() TODO
|
// client->onConnect() TODO
|
||||||
// client->onDisconnect() TODO
|
// client->onDisconnect() TODO
|
||||||
@@ -42,13 +51,16 @@ MqttClient::MqttClient(MqttBroker* local_broker, TcpClient* new_client)
|
|||||||
MqttClient::MqttClient(MqttBroker* local_broker, const std::string& id)
|
MqttClient::MqttClient(MqttBroker* local_broker, const std::string& id)
|
||||||
: local_broker(local_broker), clientId(id)
|
: local_broker(local_broker), clientId(id)
|
||||||
{
|
{
|
||||||
|
dclass;
|
||||||
alive = 0;
|
alive = 0;
|
||||||
|
keep_alive = 0;
|
||||||
|
|
||||||
if (local_broker) local_broker->addClient(this);
|
if (local_broker) local_broker->addClient(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttClient::~MqttClient()
|
MqttClient::~MqttClient()
|
||||||
{
|
{
|
||||||
|
dtor;
|
||||||
close();
|
close();
|
||||||
debug("*** MqttClient delete()");
|
debug("*** MqttClient delete()");
|
||||||
}
|
}
|
||||||
@@ -108,12 +120,6 @@ void MqttClient::connect(std::string broker, uint16_t port, uint16_t ka)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttBroker::addClient(TcpClient* client)
|
|
||||||
{
|
|
||||||
debug("MqttBroker::addClient");
|
|
||||||
clients.insert(std::unique_ptr<MqttClient>(new MqttClient(this, client)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MqttBroker::connect(const std::string& host, uint16_t port)
|
void MqttBroker::connect(const std::string& host, uint16_t port)
|
||||||
{
|
{
|
||||||
debug("MqttBroker::connect");
|
debug("MqttBroker::connect");
|
||||||
@@ -125,6 +131,12 @@ void MqttBroker::connect(const std::string& host, uint16_t port)
|
|||||||
void MqttBroker::removeClient(MqttClient* remove)
|
void MqttBroker::removeClient(MqttClient* remove)
|
||||||
{
|
{
|
||||||
local_clients.erase(remove);
|
local_clients.erase(remove);
|
||||||
|
for(auto it = clients.begin(); it!=clients.end(); it++)
|
||||||
|
if (*it == remove)
|
||||||
|
{
|
||||||
|
clients.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttBroker::onClient(void* broker_ptr, TcpClient* client)
|
void MqttBroker::onClient(void* broker_ptr, TcpClient* client)
|
||||||
@@ -132,13 +144,14 @@ void MqttBroker::onClient(void* broker_ptr, TcpClient* client)
|
|||||||
debug("MqttBroker::onClient");
|
debug("MqttBroker::onClient");
|
||||||
MqttBroker* broker = static_cast<MqttBroker*>(broker_ptr);
|
MqttBroker* broker = static_cast<MqttBroker*>(broker_ptr);
|
||||||
|
|
||||||
broker->addClient(client);
|
broker->clients.push_back(new MqttClient(broker, client));
|
||||||
debug("New client");
|
debug("New client");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MqttBroker::loop()
|
void MqttBroker::loop()
|
||||||
{
|
{
|
||||||
#ifndef TINY_MQTT_ASYNC
|
#ifndef TINY_MQTT_ASYNC
|
||||||
|
if (not server) return;
|
||||||
WiFiClient client = server->available();
|
WiFiClient client = server->available();
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
@@ -153,18 +166,31 @@ void MqttBroker::loop()
|
|||||||
remote_broker->loop();
|
remote_broker->loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 200 bytes shorter than for(auto& client: clients) !
|
// keep track on size because loop can remove a client from containers
|
||||||
for(auto it=clients.begin(); it!=clients.end(); it++)
|
// loop on remote clients (connected through network)
|
||||||
|
auto size = clients.size();
|
||||||
|
for(auto it = clients.begin(); it!=clients.end(); it++)
|
||||||
{
|
{
|
||||||
it->get()->loop();
|
MqttClient* client = *it;
|
||||||
if (not it->get()->connected())
|
if (client->connected())
|
||||||
{
|
{
|
||||||
clients.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(const auto& client: local_clients)
|
|
||||||
client->loop();
|
client->loop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug("Client " << client->id().c_str() << " Disconnected, local_broker=" << (dbg_ptr)client->local_broker);
|
||||||
|
// Note: deleting a client not added by the broker itself will probably crash later.
|
||||||
|
}
|
||||||
|
if (size != clients.size()) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop on local clients (on same device as the broker's)
|
||||||
|
size = local_clients.size();
|
||||||
|
for(auto& client: local_clients)
|
||||||
|
{
|
||||||
|
client->loop();
|
||||||
|
if (local_clients.size() != size) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttError MqttBroker::subscribe(const Topic& topic, uint8_t qos)
|
MqttError MqttBroker::subscribe(const Topic& topic, uint8_t qos)
|
||||||
@@ -179,39 +205,29 @@ MqttError MqttBroker::subscribe(const Topic& topic, uint8_t qos)
|
|||||||
|
|
||||||
MqttError MqttBroker::publish(const MqttClient* source, const Topic& topic, MqttMessage& msg) const
|
MqttError MqttBroker::publish(const MqttClient* source, const Topic& topic, MqttMessage& msg) const
|
||||||
{
|
{
|
||||||
MqttError retval = MqttOk;
|
MqttError retval = MqttOk; // TODO here retval is badly computed
|
||||||
|
|
||||||
debug("MqttBroker::publish");
|
debug("MqttBroker::publish");
|
||||||
int clt_num = 0;
|
|
||||||
|
if (remote_broker == nullptr or source == remote_broker) // external broker -> internal clients
|
||||||
|
{
|
||||||
for(auto& client: clients)
|
for(auto& client: clients)
|
||||||
{
|
{
|
||||||
debug (" broker:" << (remote_broker && remote_broker->connected() ? "linked" : "alone")
|
retval = client->publishIfSubscribed(topic, msg);
|
||||||
<< " srce=" << (source->isLocal() ? "loc" : "rem") << " clt#" << ++clt_num
|
}
|
||||||
<< ", local=" << client->isLocal() << ", con=" << client->connected());
|
for(auto& client: local_clients)
|
||||||
|
|
||||||
bool doit = false;
|
|
||||||
if (remote_broker && remote_broker->connected()) // this (MqttBroker) is connected (to a external broker)
|
|
||||||
{
|
{
|
||||||
// ext_broker -> clients or clients -> ext_broker
|
retval = client->publishIfSubscribed(topic, msg);
|
||||||
if (source == remote_broker) // external broker -> internal clients
|
}
|
||||||
doit = true;
|
}
|
||||||
else // external clients -> this broker
|
else
|
||||||
|
{
|
||||||
|
if (remote_broker && remote_broker->connected())
|
||||||
{
|
{
|
||||||
// As this broker is connected to another broker, simply forward the msg
|
|
||||||
MqttError ret = remote_broker->publishIfSubscribed(topic, msg);
|
MqttError ret = remote_broker->publishIfSubscribed(topic, msg);
|
||||||
if (ret != MqttOk) retval = ret;
|
if (ret != MqttOk) retval = ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Disconnected
|
|
||||||
{
|
|
||||||
doit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug(" doit=" << doit << ' ');
|
|
||||||
|
|
||||||
if (doit) retval = client->publishIfSubscribed(topic, msg);
|
|
||||||
debug("");
|
|
||||||
}
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +260,7 @@ void MqttClient::clientAlive()
|
|||||||
|
|
||||||
void MqttClient::loop()
|
void MqttClient::loop()
|
||||||
{
|
{
|
||||||
if (alive && (millis() >= alive))
|
if (keep_alive && (millis() >= alive))
|
||||||
{
|
{
|
||||||
if (local_broker)
|
if (local_broker)
|
||||||
{
|
{
|
||||||
@@ -326,7 +342,7 @@ void MqttClient::resubscribe()
|
|||||||
msg.add(0);
|
msg.add(0);
|
||||||
msg.add(0);
|
msg.add(0);
|
||||||
|
|
||||||
for(const auto& topic: subscriptions)
|
for(auto topic: subscriptions)
|
||||||
{
|
{
|
||||||
msg.add(topic);
|
msg.add(topic);
|
||||||
msg.add(0); // TODO qos
|
msg.add(0); // TODO qos
|
||||||
@@ -448,8 +464,9 @@ void MqttClient::processMessage(MqttMessage* mesg)
|
|||||||
payload += len;
|
payload += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(yellow << "Client " << clientId << " connected : keep alive=" << keep_alive << '.' << white);
|
#if TINY_MQTT_DEBUG
|
||||||
|
Console << yellow << "Client " << clientId << " connected : keep alive=" << keep_alive << '.' << white << endl;
|
||||||
|
#endif
|
||||||
bclose = false;
|
bclose = false;
|
||||||
mqtt_flags |= FlagConnected;
|
mqtt_flags |= FlagConnected;
|
||||||
{
|
{
|
||||||
@@ -545,7 +562,9 @@ void MqttClient::processMessage(MqttMessage* mesg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MqttMessage::Type::Publish:
|
case MqttMessage::Type::Publish:
|
||||||
debug("publish " << (mqtt_flags & FlagConnected) << '/' << (long) tcp_client.get());
|
#if TINY_MQTT_DEBUG
|
||||||
|
Console << "publish " << (mqtt_flags & FlagConnected) << '/' << (long) tcp_client.get() << endl;
|
||||||
|
#endif
|
||||||
if ((mqtt_flags & FlagConnected) or tcp_client == nullptr)
|
if ((mqtt_flags & FlagConnected) or tcp_client == nullptr)
|
||||||
{
|
{
|
||||||
uint8_t qos = mesg->flags();
|
uint8_t qos = mesg->flags();
|
||||||
@@ -553,7 +572,9 @@ void MqttClient::processMessage(MqttMessage* mesg)
|
|||||||
mesg->getString(payload, len);
|
mesg->getString(payload, len);
|
||||||
Topic published(payload, len);
|
Topic published(payload, len);
|
||||||
payload += len;
|
payload += len;
|
||||||
debug("Received Publish (" << published.str().c_str() << ") size=" << (int)len);
|
#if TINY_MQTT_DEBUG
|
||||||
|
Console << "Received Publish (" << published.str().c_str() << ") size=" << (int)len << endl;
|
||||||
|
#endif
|
||||||
// << '(' << std::string(payload, len).c_str() << ')' << " msglen=" << mesg->length() << endl;
|
// << '(' << std::string(payload, len).c_str() << ')' << " msglen=" << mesg->length() << endl;
|
||||||
if (qos) payload+=2; // ignore packet identifier if any
|
if (qos) payload+=2; // ignore packet identifier if any
|
||||||
len=mesg->end()-payload;
|
len=mesg->end()-payload;
|
||||||
@@ -705,7 +726,10 @@ MqttError MqttClient::publishIfSubscribed(const Topic& topic, MqttMessage& msg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
processMessage(&msg);
|
processMessage(&msg);
|
||||||
debug("Should call the callback ?");
|
|
||||||
|
#if TINY_MQTT_DEBUG
|
||||||
|
Console << "Should call the callback ?\n";
|
||||||
|
#endif
|
||||||
// callback(this, topic, nullptr, 0); // TODO Payload
|
// callback(this, topic, nullptr, 0); // TODO Payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#include <rpcWiFi.h>
|
#include <rpcWiFi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <memory>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "StringIndexer.h"
|
#include "StringIndexer.h"
|
||||||
@@ -52,11 +52,20 @@
|
|||||||
static int debug;
|
static int debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define debug(what) { if (TinyMqtt::debug>=1) Console << (int)__LINE__ << ' ' << what << TinyConsole::white << endl; delay(10); }
|
#define debug(what) { if (TinyMqtt::debug>=1) Console << (int)__LINE__ << ' ' << what << TinyConsole::white << endl; delay(100); }
|
||||||
#else
|
#else
|
||||||
#define debug(what) {}
|
#define debug(what) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <TinyConsole.h>
|
||||||
|
#if 0
|
||||||
|
#define dclass { Console << __LINE__ << ':' << __PRETTY_FUNCTION__ << ", this=" << (long)this << endl; }
|
||||||
|
#define dtor { Console << __LINE__ << ": ~" << __PRETTY_FUNCTION__ << ", this=" << (long)this << endl; }
|
||||||
|
#else
|
||||||
|
#define dclass
|
||||||
|
#define dtor
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TINY_MQTT_ASYNC
|
#ifdef TINY_MQTT_ASYNC
|
||||||
using TcpClient = AsyncClient;
|
using TcpClient = AsyncClient;
|
||||||
using TcpServer = AsyncServer;
|
using TcpServer = AsyncServer;
|
||||||
@@ -188,7 +197,7 @@ class MqttClient
|
|||||||
/** Constructor. Broker is the adress of a local broker if not null
|
/** Constructor. Broker is the adress of a local broker if not null
|
||||||
If you want to connect elsewhere, leave broker null and use connect() **/
|
If you want to connect elsewhere, leave broker null and use connect() **/
|
||||||
MqttClient(MqttBroker* broker = nullptr, const std::string& id = TINY_MQTT_DEFAULT_CLIENT_ID);
|
MqttClient(MqttBroker* broker = nullptr, const std::string& id = TINY_MQTT_DEFAULT_CLIENT_ID);
|
||||||
MqttClient(const std::string& id) : MqttClient(nullptr, id){}
|
MqttClient(const std::string& id) : MqttClient(nullptr, id){ dclass; }
|
||||||
|
|
||||||
~MqttClient();
|
~MqttClient();
|
||||||
|
|
||||||
@@ -320,28 +329,25 @@ class MqttBroker
|
|||||||
public:
|
public:
|
||||||
// TODO limit max number of clients
|
// TODO limit max number of clients
|
||||||
MqttBroker(uint16_t port);
|
MqttBroker(uint16_t port);
|
||||||
|
~MqttBroker();
|
||||||
|
|
||||||
void begin() { server->begin(); }
|
void begin() { if (server) server->begin(); }
|
||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
void connect(const std::string& host, uint16_t port=1883);
|
void connect(const std::string& host, uint16_t port=1883);
|
||||||
bool connected() const { return state == Connected; }
|
bool connected() const { return state == Connected; }
|
||||||
|
|
||||||
|
size_t clientsCount() const { return clients.size(); }
|
||||||
|
|
||||||
void dump(std::string indent="")
|
void dump(std::string indent="")
|
||||||
{
|
{
|
||||||
for(const auto& client: clients)
|
for(auto& client: clients)
|
||||||
client->dump(indent);
|
client->dump(indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
using Clients = std::set<std::unique_ptr<MqttClient>>;
|
|
||||||
using LocalClients = std::set<MqttClient*>;
|
|
||||||
|
|
||||||
const Clients& getClients() const { return clients; }
|
|
||||||
const LocalClients& getLocalClients() const { return local_clients; }
|
|
||||||
|
|
||||||
size_t clientsCount() const { return clients.size(); }
|
|
||||||
size_t localClientsCount() const { return local_clients.size(); }
|
size_t localClientsCount() const { return local_clients.size(); }
|
||||||
|
using Clients = std::vector<MqttClient*>;
|
||||||
|
const Clients& getClients() const { return clients; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class MqttClient;
|
friend class MqttClient;
|
||||||
@@ -358,14 +364,13 @@ class MqttBroker
|
|||||||
|
|
||||||
MqttError subscribe(const Topic& topic, uint8_t qos);
|
MqttError subscribe(const Topic& topic, uint8_t qos);
|
||||||
|
|
||||||
|
// For clients that are added not by the broker itself (local clients)
|
||||||
void addClient(MqttClient* local) { local_clients.insert(local); }
|
void addClient(MqttClient* local) { local_clients.insert(local); }
|
||||||
void addClient(TcpClient* client);
|
void removeClient(MqttClient* client);
|
||||||
|
|
||||||
void removeClient(MqttClient* local);
|
|
||||||
|
|
||||||
bool compareString(const char* good, const char* str, uint8_t str_len) const;
|
bool compareString(const char* good, const char* str, uint8_t str_len) const;
|
||||||
Clients clients;
|
Clients clients;
|
||||||
LocalClients local_clients;
|
std::set<MqttClient*> local_clients;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<TcpServer> server;
|
std::unique_ptr<TcpServer> server;
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
// Implementation of C++14's make_unique for C++11 compilers.
|
|
||||||
//
|
|
||||||
// This has been tested with:
|
|
||||||
// - MSVC 11.0 (Visual Studio 2012)
|
|
||||||
// - gcc 4.6.3
|
|
||||||
// - Xcode 4.4 (with clang "4.0")
|
|
||||||
//
|
|
||||||
// It is based off an implementation proposed by Stephan T. Lavavej for
|
|
||||||
// inclusion in the C++14 standard:
|
|
||||||
// http://isocpp.org/files/papers/N3656.txt
|
|
||||||
// Where appropriate, it borrows the use of MSVC's _VARIADIC_EXPAND_0X macro
|
|
||||||
// machinery to compensate for lack of variadic templates.
|
|
||||||
//
|
|
||||||
// This file injects make_unique into the std namespace, which I acknowledge is
|
|
||||||
// technically forbidden ([C++11: 17.6.4.2.2.1/1]), but is necessary in order
|
|
||||||
// to have syntax compatibility with C++14.
|
|
||||||
//
|
|
||||||
// I perform compiler version checking for MSVC, gcc, and clang to ensure that
|
|
||||||
// we don't add make_unique if it is already there (instead, we include
|
|
||||||
// <memory> to get the compiler-provided one). You can override the compiler
|
|
||||||
// version checking by defining the symbol COMPILER_SUPPORTS_MAKE_UNIQUE.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// ===============================================================================
|
|
||||||
// This file is released into the public domain. See LICENCE for more information.
|
|
||||||
// ===============================================================================
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// If user hasn't specified COMPILER_SUPPORTS_MAKE_UNIQUE then try to figure out
|
|
||||||
// based on compiler version if std::make_unique is provided.
|
|
||||||
#if !defined(COMPILER_SUPPORTS_MAKE_UNIQUE)
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
// std::make_unique was added in MSVC 12.0
|
|
||||||
#if _MSC_VER >= 1800 // MSVC 12.0 (Visual Studio 2013)
|
|
||||||
#define COMPILER_SUPPORTS_MAKE_UNIQUE
|
|
||||||
#endif
|
|
||||||
#elif defined(__clang__)
|
|
||||||
// std::make_unique was added in clang 3.4, but not until Xcode 6.
|
|
||||||
// Annoyingly, Apple makes the clang version defines match the version
|
|
||||||
// of Xcode, not the version of clang.
|
|
||||||
#define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
|
|
||||||
#if defined(__APPLE__) && CLANG_VERSION >= 60000
|
|
||||||
#define COMPILER_SUPPORTS_MAKE_UNIQUE
|
|
||||||
#elif !defined(__APPLE__) && CLANG_VERSION >= 30400
|
|
||||||
#define COMPILER_SUPPORTS_MAKE_UNIQUE
|
|
||||||
#endif
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
// std::make_unique was added in gcc 4.9, for standards versions greater
|
|
||||||
// than -std=c++11.
|
|
||||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
|
||||||
#if GCC_VERSION >= 40900 && __cplusplus > 201103L
|
|
||||||
#define COMPILER_SUPPORTS_MAKE_UNIQUE
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(COMPILER_SUPPORTS_MAKE_UNIQUE)
|
|
||||||
|
|
||||||
// If the compiler supports std::make_unique, then pull in <memory> to get it.
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Otherwise, the compiler doesn't provide it, so implement it ourselves.
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
|
|
||||||
template<class _Ty> struct _Unique_if {
|
|
||||||
typedef unique_ptr<_Ty> _Single_object;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class _Ty> struct _Unique_if<_Ty[]> {
|
|
||||||
typedef unique_ptr<_Ty[]> _Unknown_bound;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class _Ty, size_t N> struct _Unique_if<_Ty[N]> {
|
|
||||||
typedef void _Known_bound;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// template< class T, class... Args >
|
|
||||||
// unique_ptr<T> make_unique( Args&&... args);
|
|
||||||
//
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
|
||||||
|
|
||||||
// Macro machinery because MSVC 11.0 doesn't support variadic templates.
|
|
||||||
// The _VARIADIC_EXPAND_0X stuff is defined in <xstddef>
|
|
||||||
#define _MAKE_UNIQUE( \
|
|
||||||
TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \
|
|
||||||
template<class _Ty COMMA LIST(_CLASS_TYPE)> inline \
|
|
||||||
typename _Unique_if<_Ty>::_Single_object make_unique(LIST(_TYPE_REFREF_ARG)) \
|
|
||||||
{ \
|
|
||||||
return unique_ptr<_Ty>(new _Ty(LIST(_FORWARD_ARG))); \
|
|
||||||
} \
|
|
||||||
|
|
||||||
_VARIADIC_EXPAND_0X(_MAKE_UNIQUE, , , , )
|
|
||||||
#undef _MAKE_UNIQUE
|
|
||||||
|
|
||||||
#else // not MSVC 11.0 or earlier
|
|
||||||
|
|
||||||
template<class _Ty, class... Args>
|
|
||||||
typename _Unique_if<_Ty>::_Single_object
|
|
||||||
make_unique(Args&&... args) {
|
|
||||||
return unique_ptr<_Ty>(new _Ty(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// template< class T >
|
|
||||||
// unique_ptr<T> make_unique( std::size_t size );
|
|
||||||
|
|
||||||
template<class _Ty>
|
|
||||||
typename _Unique_if<_Ty>::_Unknown_bound
|
|
||||||
make_unique(size_t n) {
|
|
||||||
typedef typename remove_extent<_Ty>::type U;
|
|
||||||
return unique_ptr<_Ty>(new U[n]());
|
|
||||||
}
|
|
||||||
|
|
||||||
// template< class T, class... Args >
|
|
||||||
// /* unspecified */ make_unique( Args&&... args ) = delete;
|
|
||||||
|
|
||||||
// MSVC 11.0 doesn't support deleted functions, so the best we can do
|
|
||||||
// is simply not define the function.
|
|
||||||
#if !(defined(_MSC_VER) && (_MSC_VER < 1800))
|
|
||||||
|
|
||||||
template<class T, class... Args>
|
|
||||||
typename _Unique_if<T>::_Known_bound
|
|
||||||
make_unique(Args&&...) = delete;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
#endif // !COMPILER_SUPPORTS_MAKE_UNIQUE
|
|
||||||
|
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
SUB=n
|
SUB=
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
set -e; \
|
@set -e; \
|
||||||
for i in ${SUB}*-tests/Makefile; do \
|
for i in ${SUB}*-tests/Makefile; do \
|
||||||
echo '==== Making:' $$(dirname $$i); \
|
echo '==== Making:' $$(dirname $$i); \
|
||||||
$(MAKE) -C $$(dirname $$i) -j; \
|
$(MAKE) -C $$(dirname $$i) -j; \
|
||||||
done
|
done
|
||||||
|
|
||||||
debugtest:
|
debugtest:
|
||||||
set -e; \
|
@set -e; \
|
||||||
$(MAKE) clean; \
|
$(MAKE) clean; \
|
||||||
$(MAKE) -C debug-mode -j; \
|
$(MAKE) -C debug-mode -j; \
|
||||||
debug-mode/debug-tests.out
|
debug-mode/debug-tests.out
|
||||||
|
|
||||||
runtests: debugtest
|
runtests: debugtest
|
||||||
$(MAKE) clean
|
@$(MAKE) clean
|
||||||
$(MAKE) tests
|
@$(MAKE) tests
|
||||||
set -e; \
|
@set -e; \
|
||||||
for i in ${SUB}*-tests/Makefile; do \
|
for i in ${SUB}*-tests/Makefile; do \
|
||||||
echo '==== Running:' $$(dirname $$i); \
|
echo '==== Running:' $$(dirname $$i); \
|
||||||
$$(dirname $$i)/$$(dirname $$i).out; \
|
$$(dirname $$i)/$$(dirname $$i).out; \
|
||||||
done
|
done
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
set -e; \
|
@set -e; \
|
||||||
for i in ${SUB}*-tests/Makefile; do \
|
for i in ${SUB}*-tests/Makefile; do \
|
||||||
echo '==== Cleaning:' $$(dirname $$i); \
|
echo '==== Cleaning:' $$(dirname $$i); \
|
||||||
$(MAKE) -C $$(dirname $$i) clean; \
|
$(MAKE) -C $$(dirname $$i) clean; \
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
EXTRA_CXXFLAGS=-g3 -O0 -DTINY_MQTT_TESTS
|
EXTRA_CXXFLAGS=-g3 -O0 -DTINY_MQTT_TESTS
|
||||||
|
|
||||||
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
||||||
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -DEPOXY_TEST
|
||||||
|
|
||||||
APP_NAME := classbind-tests
|
APP_NAME := classbind-tests
|
||||||
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP TinyConsole
|
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP TinyConsole
|
||||||
|
|||||||
@@ -127,8 +127,9 @@ void reset_and_start_servers(int n, bool early_accept = true)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test(classbind_one_client_receives_the_message)
|
test(classbind_two_subscribers_binded_one_sender_wildcard)
|
||||||
{
|
{
|
||||||
|
EpoxyTest::set_millis(0);
|
||||||
reset_and_start_servers(2, true);
|
reset_and_start_servers(2, true);
|
||||||
assertEqual(WiFi.status(), WL_CONNECTED);
|
assertEqual(WiFi.status(), WL_CONNECTED);
|
||||||
|
|
||||||
@@ -138,7 +139,50 @@ test(classbind_one_client_receives_the_message)
|
|||||||
|
|
||||||
// We have a 2nd ESP in order to test through wifi (opposed to local)
|
// We have a 2nd ESP in order to test through wifi (opposed to local)
|
||||||
ESP8266WiFiClass::selectInstance(2);
|
ESP8266WiFiClass::selectInstance(2);
|
||||||
MqttClient client;
|
MqttClient mqtt_a(&broker, "mqtt_a");
|
||||||
|
MqttClient mqtt_b(&broker, "mqtt_a");
|
||||||
|
MqttClient mqtt_sender(&broker, "sender");
|
||||||
|
|
||||||
|
broker.loop();
|
||||||
|
|
||||||
|
assertTrue(mqtt_a.connected());
|
||||||
|
assertTrue(mqtt_b.connected());
|
||||||
|
|
||||||
|
TestReceiver receiver("receiver");
|
||||||
|
MqttClassBinder<TestReceiver>::onPublish(&mqtt_a, &receiver);
|
||||||
|
MqttClassBinder<TestReceiver>::onPublish(&mqtt_b, &receiver);
|
||||||
|
|
||||||
|
mqtt_a.subscribe("#");
|
||||||
|
mqtt_b.subscribe("#");
|
||||||
|
mqtt_sender.publish("a/b", "ab");
|
||||||
|
|
||||||
|
for (int i =0; i<10; i++)
|
||||||
|
{
|
||||||
|
EpoxyTest::add_millis(100);
|
||||||
|
mqtt_a.loop();
|
||||||
|
mqtt_b.loop();
|
||||||
|
mqtt_sender.loop();
|
||||||
|
broker.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(TestReceiver::messages["receiver"], 2);
|
||||||
|
assertEqual(unrouted, 0);
|
||||||
|
EpoxyTest::set_real_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
test(classbind_one_client_receives_the_message)
|
||||||
|
{
|
||||||
|
EpoxyTest::set_millis(0);
|
||||||
|
reset_and_start_servers(2, true);
|
||||||
|
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("sender");
|
||||||
client.connect(ip_broker.toString().c_str(), 1883);
|
client.connect(ip_broker.toString().c_str(), 1883);
|
||||||
broker.loop();
|
broker.loop();
|
||||||
assertTrue(client.connected());
|
assertTrue(client.connected());
|
||||||
@@ -151,12 +195,14 @@ test(classbind_one_client_receives_the_message)
|
|||||||
|
|
||||||
for (int i =0; i<10; i++)
|
for (int i =0; i<10; i++)
|
||||||
{
|
{
|
||||||
|
EpoxyTest::add_millis(100);
|
||||||
client.loop();
|
client.loop();
|
||||||
broker.loop();
|
broker.loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEqual(TestReceiver::messages["receiver"], 1);
|
assertEqual(TestReceiver::messages["receiver"], 1);
|
||||||
assertEqual(unrouted, 0);
|
assertEqual(unrouted, 0);
|
||||||
|
EpoxyTest::set_real_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
test(classbind_routes_should_be_empty_when_receiver_goes_out_of_scope)
|
test(classbind_routes_should_be_empty_when_receiver_goes_out_of_scope)
|
||||||
@@ -338,7 +384,7 @@ void setup() {
|
|||||||
while(!Serial);
|
while(!Serial);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Serial.println("=============[ FAKE NETWORK TinyMqtt TESTS ]========================");
|
Serial.println("=============[ CLASS BINDER TinyMqtt TESTS ]========================");
|
||||||
|
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.begin("network", "password");
|
WiFi.begin("network", "password");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# 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 -DTINY_MQTT_DEBUG
|
EXTRA_CXXFLAGS=-g3 -O0
|
||||||
|
|
||||||
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
||||||
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# 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 -DTINY_MQTT_DEFAULT_ALIVE=1
|
EXTRA_CXXFLAGS=-g3 -O0 -DTINY_MQTT_DEFAULT_ALIVE=1 -DEPOXY_TEST
|
||||||
|
|
||||||
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
||||||
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ test(local_client_should_unregister_when_destroyed)
|
|||||||
MqttBroker broker(1883);
|
MqttBroker broker(1883);
|
||||||
assertEqual(broker.localClientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
{
|
{
|
||||||
assertEqual(broker.localClientsCount(), (size_t)0); // Ensure client is not yet connected
|
|
||||||
MqttClient client(&broker);
|
MqttClient client(&broker);
|
||||||
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is now connected
|
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is now connected
|
||||||
}
|
}
|
||||||
@@ -42,52 +41,70 @@ test(local_client_should_unregister_when_destroyed)
|
|||||||
|
|
||||||
test(local_client_alive)
|
test(local_client_alive)
|
||||||
{
|
{
|
||||||
set_millis(0);
|
EpoxyTest::set_millis(0);
|
||||||
MqttBroker broker(1883);
|
MqttBroker broker(1883);
|
||||||
MqttClient client(&broker);
|
MqttClient client(&broker);
|
||||||
|
|
||||||
broker.loop();
|
broker.loop();
|
||||||
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is now connected
|
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is now connected
|
||||||
|
|
||||||
add_millis(TINY_MQTT_DEFAULT_ALIVE*1000/2);
|
EpoxyTest::add_millis(TINY_MQTT_DEFAULT_ALIVE*1000/2);
|
||||||
broker.loop();
|
broker.loop();
|
||||||
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is still connected
|
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is still connected
|
||||||
|
|
||||||
add_seconds(TINY_MQTT_DEFAULT_ALIVE*5);
|
EpoxyTest::add_seconds(TINY_MQTT_DEFAULT_ALIVE*5);
|
||||||
broker.loop();
|
broker.loop();
|
||||||
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is still connected
|
assertEqual(broker.localClientsCount(), (size_t)1); // Ensure client is still connected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test(local_wildcard_subscribe)
|
||||||
|
{
|
||||||
|
EpoxyTest::set_millis(0);
|
||||||
|
MqttBroker broker(1883);
|
||||||
|
MqttClient client(&broker, "client");
|
||||||
|
MqttClient sender(&broker, "sender");
|
||||||
|
broker.loop();
|
||||||
|
|
||||||
|
client.subscribe("#");
|
||||||
|
client.subscribe("test");
|
||||||
|
client.setCallback(onPublish);
|
||||||
|
assertEqual(broker.localClientsCount(), (size_t)2);
|
||||||
|
|
||||||
|
sender.publish("test", "value");
|
||||||
|
broker.loop();
|
||||||
|
|
||||||
|
assertEqual(published.size(), (size_t)1); // client has received something
|
||||||
|
}
|
||||||
|
|
||||||
|
test(local_client_do_not_disconnect_after_publishing)
|
||||||
|
{
|
||||||
|
EpoxyTest::set_millis(0);
|
||||||
|
MqttBroker broker(1883);
|
||||||
|
MqttClient client(&broker, "client");
|
||||||
|
MqttClient sender(&broker, "sender");
|
||||||
|
broker.loop();
|
||||||
|
|
||||||
|
client.subscribe("#");
|
||||||
|
client.subscribe("test");
|
||||||
|
client.setCallback(onPublish);
|
||||||
|
assertEqual(broker.localClientsCount(), (size_t)2);
|
||||||
|
|
||||||
|
sender.publish("test", "value");
|
||||||
|
broker.loop();
|
||||||
|
|
||||||
|
EpoxyTest::add_seconds(60);
|
||||||
|
client.loop();
|
||||||
|
sender.loop();
|
||||||
|
broker.loop();
|
||||||
|
|
||||||
|
assertEqual(broker.localClientsCount(), (size_t)2);
|
||||||
|
assertEqual(sender.connected(), true);
|
||||||
|
assertEqual(client.connected(), true);
|
||||||
|
|
||||||
|
assertEqual(published.size(), (size_t)1); // client has received something
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
test(local_connect)
|
|
||||||
{
|
|
||||||
assertEqual(broker.localClientsCount(), (size_t)0);
|
|
||||||
|
|
||||||
MqttClient client;
|
|
||||||
assertTrue(client.connected());
|
|
||||||
assertEqual(broker.localClientsCount(), (size_t)1);
|
|
||||||
}
|
|
||||||
|
|
||||||
test(local_publish_should_be_dispatched)
|
|
||||||
{
|
|
||||||
published.clear();
|
|
||||||
assertEqual(broker.localClientsCount(), (size_t)0);
|
|
||||||
|
|
||||||
MqttClient subscriber;
|
|
||||||
subscriber.subscribe("a/b");
|
|
||||||
subscriber.subscribe("a/c");
|
|
||||||
subscriber.setCallback(onPublish);
|
|
||||||
|
|
||||||
MqttClient publisher;
|
|
||||||
publisher.publish("a/b");
|
|
||||||
publisher.publish("a/c");
|
|
||||||
publisher.publish("a/c");
|
|
||||||
|
|
||||||
assertEqual(published.size(), (size_t)1); // 1 client has received something
|
|
||||||
assertEqual(published[""]["a/b"], 1);
|
|
||||||
assertEqual(published[""]["a/c"], 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
test(local_publish_should_be_dispatched_to_local_clients)
|
test(local_publish_should_be_dispatched_to_local_clients)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
EXTRA_CXXFLAGS=-g3 -O0
|
EXTRA_CXXFLAGS=-g3 -O0
|
||||||
|
|
||||||
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
# Remove flto flag from EpoxyDuino (too many <optimized out>)
|
||||||
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics
|
CXXFLAGS = -Wextra -Wall -std=gnu++11 -fno-exceptions -fno-threadsafe-statics -DEPOXY_TEST
|
||||||
|
|
||||||
APP_NAME := network-tests
|
APP_NAME := network-tests
|
||||||
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP TinyConsole
|
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP TinyConsole
|
||||||
|
|||||||
@@ -9,6 +9,16 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
uint32_t getClientKeepAlive(MqttBroker& broker)
|
||||||
|
{
|
||||||
|
if (broker.getClients().size() == 1)
|
||||||
|
for (auto& it : broker.getClients())
|
||||||
|
return it->keepAlive();
|
||||||
|
|
||||||
|
return 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TinyMqtt network unit tests.
|
* TinyMqtt network unit tests.
|
||||||
*
|
*
|
||||||
@@ -142,21 +152,12 @@ test(suback)
|
|||||||
assertEqual(MqttClient::counters[MqttMessage::Type::SubAck], 1);
|
assertEqual(MqttClient::counters[MqttMessage::Type::SubAck], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getClientKeepAlive(MqttBroker& broker)
|
|
||||||
{
|
|
||||||
if (broker.getClients().size() == 1)
|
|
||||||
for (auto& it : broker.getClients())
|
|
||||||
return it->keepAlive();
|
|
||||||
|
|
||||||
return 9999;
|
|
||||||
}
|
|
||||||
|
|
||||||
test(network_client_alive)
|
test(network_client_alive)
|
||||||
{
|
{
|
||||||
const uint32_t keep_alive=1;
|
const uint32_t keep_alive=1;
|
||||||
start_servers(2, true);
|
start_servers(2, true);
|
||||||
assertEqual(WiFi.status(), WL_CONNECTED);
|
assertEqual(WiFi.status(), WL_CONNECTED);
|
||||||
set_millis(0); // Enter simulated time
|
EpoxyTest::set_millis(0); // Enter simulated time
|
||||||
|
|
||||||
MqttBroker broker(1883);
|
MqttBroker broker(1883);
|
||||||
broker.begin();
|
broker.begin();
|
||||||
@@ -177,18 +178,18 @@ test(network_client_alive)
|
|||||||
|
|
||||||
// All is going well if we call client.loop()
|
// All is going well if we call client.loop()
|
||||||
// The client is able to send PingReq to the broker
|
// The client is able to send PingReq to the broker
|
||||||
add_seconds(keep_alive);
|
EpoxyTest::add_seconds(keep_alive);
|
||||||
client.loop();
|
client.loop();
|
||||||
broker.loop();
|
broker.loop();
|
||||||
assertEqual(broker.clientsCount(), (size_t)1);
|
assertEqual(broker.clientsCount(), (size_t)1);
|
||||||
|
|
||||||
// Now simulate that the client is frozen for
|
// Now simulate that the client is frozen for
|
||||||
// a too long time
|
// a too long time
|
||||||
add_seconds(TINY_MQTT_CLIENT_ALIVE_TOLERANCE*2);
|
EpoxyTest::add_seconds(TINY_MQTT_CLIENT_ALIVE_TOLERANCE*2);
|
||||||
broker.loop();
|
broker.loop();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.clientsCount(), (size_t)0);
|
||||||
|
|
||||||
set_real_time();
|
EpoxyTest::set_real_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
test(network_client_keep_alive_high)
|
test(network_client_keep_alive_high)
|
||||||
@@ -223,6 +224,7 @@ test(network_client_keep_alive_high)
|
|||||||
|
|
||||||
uint32_t ka = getClientKeepAlive(broker);
|
uint32_t ka = getClientKeepAlive(broker);
|
||||||
assertEqual(ka, keep_alive);
|
assertEqual(ka, keep_alive);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test(network_client_to_broker_connexion)
|
test(network_client_to_broker_connexion)
|
||||||
@@ -310,14 +312,14 @@ test(network_one_client_one_broker_hudge_publish_and_subscribe_through_network)
|
|||||||
assertEqual((unsigned int)lastLength, (unsigned int)sent.size());
|
assertEqual((unsigned int)lastLength, (unsigned int)sent.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
test(network_client_should_unregister_when_destroyed)
|
test(network_local_client_should_unregister_when_destroyed)
|
||||||
{
|
{
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.clientsCount(), (size_t)0);
|
||||||
{
|
{
|
||||||
MqttClient client(&broker);
|
MqttClient client(&broker);
|
||||||
assertEqual(broker.clientsCount(), (size_t)1);
|
assertEqual(broker.localClientsCount(), (size_t)1);
|
||||||
}
|
}
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -330,13 +332,13 @@ test(network_connect)
|
|||||||
|
|
||||||
MqttClient client(&broker);
|
MqttClient client(&broker);
|
||||||
assertTrue(client.connected());
|
assertTrue(client.connected());
|
||||||
assertEqual(broker.clientsCount(), (size_t)1);
|
assertEqual(broker.localClientsCount(), (size_t)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
test(network_publish_should_be_dispatched)
|
test(network_publish_should_be_dispatched)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker);
|
MqttClient subscriber(&broker);
|
||||||
subscriber.subscribe("a/b");
|
subscriber.subscribe("a/b");
|
||||||
@@ -437,11 +439,12 @@ test(network_small_payload)
|
|||||||
|
|
||||||
test(network_hudge_payload)
|
test(network_hudge_payload)
|
||||||
{
|
{
|
||||||
const char* payload="This payload is hudge, just because its length exceeds 127. Thus when encoding length, we have to encode it on two bytes at min. This should not prevent the message from being encoded and decoded successfully !";
|
// const char* payload="This payload is hudge, just because its length exceeds 127. Thus when encoding length, we have to encode it on two bytes at min. This should not prevent the message from being encoded and decoded successfully !";
|
||||||
|
const char* payload="This was decoded successfully !";
|
||||||
|
|
||||||
MqttClient subscriber(&broker);
|
MqttClient subscriber(&broker);
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
subscriber.subscribe("a/b"); // Note -> this does not send any byte .... (nowhere to send)
|
subscriber.subscribe("a/b"); // Note -> this does not send any byte .... (nowhere to send) TODO
|
||||||
|
|
||||||
MqttClient publisher(&broker);
|
MqttClient publisher(&broker);
|
||||||
publisher.publish("a/b", payload); // This publish is received
|
publisher.publish("a/b", payload); // This publish is received
|
||||||
@@ -450,11 +453,13 @@ test(network_hudge_payload)
|
|||||||
assertEqual(payload, lastPayload);
|
assertEqual(payload, lastPayload);
|
||||||
assertEqual(lastLength, strlen(payload));
|
assertEqual(lastLength, strlen(payload));
|
||||||
assertEqual(strcmp(payload, lastPayload), 0);
|
assertEqual(strcmp(payload, lastPayload), 0);
|
||||||
|
std::cout << "payload : " << payload << std::endl;
|
||||||
|
std::cout << "received: " << lastPayload << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
test(connack)
|
test(connack)
|
||||||
{
|
{
|
||||||
const bool view = false;
|
const bool view = true;
|
||||||
|
|
||||||
NetworkObserver check(
|
NetworkObserver check(
|
||||||
[this](const WiFiClient*, const uint8_t* buffer, size_t length)
|
[this](const WiFiClient*, const uint8_t* buffer, size_t length)
|
||||||
|
|||||||
@@ -32,27 +32,27 @@ void onPublish(const MqttClient* srce, const Topic& topic, const char* payload,
|
|||||||
|
|
||||||
test(nowifi_client_should_unregister_when_destroyed)
|
test(nowifi_client_should_unregister_when_destroyed)
|
||||||
{
|
{
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
{
|
{
|
||||||
MqttClient client(&broker);
|
MqttClient client(&broker);
|
||||||
assertEqual(broker.clientsCount(), (size_t)1);
|
assertEqual(broker.localClientsCount(), (size_t)1);
|
||||||
}
|
}
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
test(nowifi_connect)
|
test(nowifi_connect)
|
||||||
{
|
{
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient client(&broker);
|
MqttClient client(&broker);
|
||||||
assertTrue(client.connected());
|
assertTrue(client.connected());
|
||||||
assertEqual(broker.clientsCount(), (size_t)1);
|
assertEqual(broker.localClientsCount(), (size_t)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
test(nowifi_publish_should_be_dispatched)
|
test(nowifi_publish_should_be_dispatched)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker);
|
MqttClient subscriber(&broker);
|
||||||
subscriber.subscribe("a/b");
|
subscriber.subscribe("a/b");
|
||||||
@@ -72,7 +72,7 @@ test(nowifi_publish_should_be_dispatched)
|
|||||||
test(nowifi_publish_should_be_dispatched_to_clients)
|
test(nowifi_publish_should_be_dispatched_to_clients)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber_a(&broker, "A");
|
MqttClient subscriber_a(&broker, "A");
|
||||||
subscriber_a.setCallback(onPublish);
|
subscriber_a.setCallback(onPublish);
|
||||||
@@ -97,7 +97,7 @@ test(nowifi_publish_should_be_dispatched_to_clients)
|
|||||||
test(nowifi_subscribe_with_star_wildcard)
|
test(nowifi_subscribe_with_star_wildcard)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker, "A");
|
MqttClient subscriber(&broker, "A");
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
@@ -118,7 +118,7 @@ test(nowifi_subscribe_with_star_wildcard)
|
|||||||
test(nowifi_subscribe_with_plus_wildcard)
|
test(nowifi_subscribe_with_plus_wildcard)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker, "A");
|
MqttClient subscriber(&broker, "A");
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
@@ -139,7 +139,7 @@ test(nowifi_subscribe_with_plus_wildcard)
|
|||||||
test(nowifi_should_not_receive_sys_msg)
|
test(nowifi_should_not_receive_sys_msg)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker, "A");
|
MqttClient subscriber(&broker, "A");
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
@@ -154,7 +154,7 @@ test(nowifi_should_not_receive_sys_msg)
|
|||||||
test(nowifi_subscribe_with_mixed_wildcards)
|
test(nowifi_subscribe_with_mixed_wildcards)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker, "A");
|
MqttClient subscriber(&broker, "A");
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
@@ -173,7 +173,7 @@ test(nowifi_subscribe_with_mixed_wildcards)
|
|||||||
test(nowifi_unsubscribe_with_wildcards)
|
test(nowifi_unsubscribe_with_wildcards)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker, "A");
|
MqttClient subscriber(&broker, "A");
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
@@ -195,7 +195,7 @@ test(nowifi_unsubscribe_with_wildcards)
|
|||||||
test(nowifi_unsubscribe)
|
test(nowifi_unsubscribe)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient subscriber(&broker);
|
MqttClient subscriber(&broker);
|
||||||
subscriber.setCallback(onPublish);
|
subscriber.setCallback(onPublish);
|
||||||
@@ -215,7 +215,7 @@ test(nowifi_unsubscribe)
|
|||||||
test(nowifi_nocallback_when_destroyed)
|
test(nowifi_nocallback_when_destroyed)
|
||||||
{
|
{
|
||||||
published.clear();
|
published.clear();
|
||||||
assertEqual(broker.clientsCount(), (size_t)0);
|
assertEqual(broker.localClientsCount(), (size_t)0);
|
||||||
|
|
||||||
MqttClient publisher(&broker);
|
MqttClient publisher(&broker);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user