Compare commits

...

13 Commits
pr22 ... 0.9.3

Author SHA1 Message Date
hsaturn
883f1e27e6 Release 0.9.3 2022-10-30 21:47:58 +01:00
hsaturn
e7fc147424 Changed tab to spaces 2022-10-30 21:43:45 +01:00
hsaturn
2147b147fc [Readme] Some minor changes 2022-10-30 21:42:59 +01:00
hsaturn
f5e9a43461 [StringIndexer] Fix compare bug and moved strToIndex to private
strToIndex is dangerous because it can increment the use of a string, or
create a new string. This method should only be called by IndexedString.
2022-10-30 21:41:52 +01:00
hsaturn
cabb56fc8c [tests] Added -g3 for tests for debugging purposes 2022-10-30 20:44:44 +01:00
hsaturn
58786eb6d9 Release 0.9.2 2022-10-30 19:48:04 +01:00
hsaturn
776242b259 Release 0.9.1 2022-10-30 19:45:50 +01:00
hsaturn
a9d19c3218 [lib] Remove library.json 2022-10-30 18:31:46 +01:00
hsaturn
7bd299ec07 Use slim lint 2022-10-30 15:23:50 +01:00
hsaturn
107469cd78 Lint action, upgrade to latest 2022-10-30 15:13:42 +01:00
hsaturn
709e1fd567 Tabs changed to spaces (at least) 2022-10-30 13:26:33 +01:00
hsaturn
4eb8f18ebf [MqttMessage] Rewrite of the length encoding 2022-10-30 13:24:05 +01:00
hsaturn
d5d27c8020 Merge pull request #25 from hsaturn/pr22
was pr#22 : added reply to message subscribe and unsubscribe
2022-01-10 05:28:08 +01:00
12 changed files with 1128 additions and 985 deletions

View File

@@ -1,26 +1,52 @@
name: Super-Linter
---
#################################
#################################
## Super Linter GitHub Actions ##
#################################
#################################
name: Lint Code Base
# Run this workflow every time a new commit pushed to your repository
#
# Documentation:
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
#
#############################
# Start the job on all push #
#############################
on: push
###############
# Set the Job #
###############
jobs:
# Set the job key. The key is displayed as the job name
# when a job name is not provided
super-lint:
build:
# Name the Job
name: Lint code base
# Set the type of machine to run on
name: Lint Code Base
# Set the agent to run on
runs-on: ubuntu-latest
##################
# Load all steps #
##################
steps:
# Checks out a copy of your repository on the ubuntu-latest machine
- name: Checkout code
uses: actions/checkout@v2
##########################
# Checkout the code base #
##########################
- name: Checkout Code
uses: actions/checkout@v3
with:
# Full git history is needed to get a proper
# list of changed files within `super-linter`
fetch-depth: 0
# Runs the Super-Linter action
- name: Run Super-Linter
uses: github/super-linter@v3
################################
# Run Linter against code base #
################################
- name: Lint Code Base
uses: github/super-linter/slim@v4
env:
VALIDATE_ALL_CODEBASE: false
# Change to 'master' if your main branch differs
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -22,6 +22,12 @@ TinyMqtt is a small, fast and capable Mqtt Broker and Client for Esp8266 / Esp32
proxy for clients that are connected to it.
- zeroconf, this is a strange but very powerful mode where
all brokers tries to connect together on the same local network.
- small memory footprint (very efficient topic storage)
## Limitations
- Max of 255 different topics can be stored (change index_t type to allow more)
- No Qos because messages are not queued but immediately sent to clients
## Quickstart

View File

@@ -1,18 +0,0 @@
{
"name": "TinyMqtt",
"keywords": "ethernet, mqtt, m2m, iot",
"description": "MQTT is a lightweight messaging protocol ideal for small devices. This library allows to send and receive and host a broker for MQTT. It does support MQTT 3.1.1 with QOS=0 on ESP8266 and ESP32 WROOM platfrms.",
"repository": {
"type": "git",
"url": "https://github.com/hsaturn/TinyMqtt.git"
},
"version": "0.8.0",
"exclude": "",
"examples": "examples/*/*.ino",
"frameworks": "arduino",
"platforms": [
"atmelavr",
"espressif8266",
"espressif32"
]
}

View File

@@ -1,5 +1,5 @@
name=TinyMqtt
version=0.8.0
version=0.9.3
author=Francois BIOT, HSaturn, <hsaturn@gmail.com>
maintainer=Francois BIOT, HSaturn, <hsaturn@gmail.com>
sentence=A tiny broker and client library for MQTT messaging.
@@ -8,4 +8,3 @@ category=Communication
url=https://github.com/hsaturn/TinyMqtt
architectures=*
includes=TinyMqtt.h
depends=AsyncTCP

View File

@@ -26,30 +26,7 @@ class StringIndexer
#endif
};
public:
using index_t=uint8_t;
static index_t strToIndex(const char* str, uint8_t len)
{
for(auto it=strings.begin(); it!=strings.end(); it++)
{
if (strncmp(it->second.str.c_str(), str, len)==0)
{
it->second.used++;
return it->first;
}
}
for(index_t index=1; index; index++)
{
if (strings.find(index)==strings.end())
{
strings[index].str = std::string(str, len);
strings[index].used++;
// Serial << "Creating index " << index << " for (" << strings[index].str.c_str() << ") len=" << len << endl;
return index;
}
}
return 0; // TODO out of indexes
}
using index_t = uint8_t;
static const std::string& str(const index_t& index)
{
@@ -82,6 +59,32 @@ class StringIndexer
static uint16_t count() { return strings.size(); }
private:
friend class IndexedString;
// increment use of str or create a new index
static index_t strToIndex(const char* str, uint8_t len)
{
for(auto it=strings.begin(); it!=strings.end(); it++)
{
if (it->second.str.length() == len && strcmp(it->second.str.c_str(), str)==0)
{
it->second.used++;
return it->first;
}
}
for(index_t index=1; index; index++)
{
if (strings.find(index)==strings.end())
{
strings[index].str = std::string(str, len);
strings[index].used++;
// Serial << "Creating index " << index << " for (" << strings[index].str.c_str() << ") len=" << len << endl;
return index;
}
}
return 0; // TODO out of indexes
}
static std::map<index_t, StringCounter> strings;
};

View File

@@ -771,9 +771,18 @@ void MqttMessage::encodeLength()
if (state != Complete)
{
int length = buffer.size()-3; // 3 = 1 byte for header + 2 bytes for pre-reserved length field.
if (length <= 0x7F)
{
buffer.erase(1,1);
buffer[1] = length;
vheader = 2;
}
else
{
buffer[1] = 0x80 | (length & 0x7F);
buffer[2] = (length >> 7);
vheader = 3;
}
// We could check that buffer[2] < 128 (end of length encoding)
state = Complete;

View File

@@ -20,6 +20,14 @@
#else
#define dbg_ptr uint32_t
#endif
#ifdef WIO_TERMINAL
// Uncommon board handling
// If you have a problem with this line, just remove it.
// Note: https://github.com/hsaturn/TinyMqtt/issues/41
#include <rpcWiFi.h>
#endif
#include <vector>
#include <set>
#include <string>

View File

@@ -1,6 +1,8 @@
# See https://github.com/bxparks/EpoxyDuino for documentation about this
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
EXTRA_CXXFLAGS=-g3 -O0
APP_NAME := length-tests
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsyncTCP
ARDUINO_LIB_DIRS := ../../../EspMock/libraries

View File

@@ -2,6 +2,10 @@
#include <AUnit.h>
#include <TinyMqtt.h>
#include <map>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
/**
* TinyMqtt network unit tests.
@@ -10,7 +14,60 @@
* Checks with a local broker. Clients must connect to the local broker
**/
using namespace std;
// if ascii_pos = 0, no ascii dump, else ascii dump starts after column ascii_pos
std::string bufferToHexa(const uint8_t* buffer, size_t length, char sep = 0, size_t ascii_pos = 0)
{
std::stringstream out;
std::string ascii;
std::string h("0123456789ABCDEF");
for(size_t i=0; i<length; i++)
{
uint8_t c = buffer[i];
out << h[ c >> 4] << h[ c & 0x0F ];
if (sep) out << sep;
if (ascii_pos)
{
if (c>=32)
ascii += c;
else
ascii +='.';
}
}
std::string ret(out.str());
if (ascii_pos)
{
while(ret.length() < ascii_pos)
ret += ' ';
ret +='[' + ascii + ']';
}
return ret;
}
void dumpMqttMessage(const uint8_t* buffer, size_t length)
{
std::map<int, std::string> pkt =
{ { MqttMessage::Unknown , "Unknown " },
{ MqttMessage::Connect , "Connect " },
{ MqttMessage::ConnAck , "ConnAck " },
{ MqttMessage::Publish , "Publish " },
{ MqttMessage::PubAck , "PubAck " },
{ MqttMessage::Subscribe , "Subscribe " },
{ MqttMessage::SubAck , "SubAck " },
{ MqttMessage::UnSubscribe , "Unsubscribe " },
{ MqttMessage::UnSuback , "UnSubAck " },
{ MqttMessage::PingReq , "PingReq " },
{ MqttMessage::PingResp , "PingResp " },
{ MqttMessage::Disconnect , "Disconnect " } };
std::cout << " | data sent " << std::setw(3) << length << " : ";
auto it = pkt.find(buffer[0] & 0xF0);
if (it == pkt.end())
std::cout << pkt[MqttMessage::Unknown];
else
std::cout << it->second;
std::cout << bufferToHexa(buffer, length, ' ', 60) << std::endl;
}
String toString(const IPAddress& ip)
{
@@ -299,7 +356,7 @@ test(network_hudge_payload)
MqttClient subscriber(&broker);
subscriber.setCallback(onPublish);
subscriber.subscribe("a/b");
subscriber.subscribe("a/b"); // Note -> this does not send any byte .... (nowhere to send)
MqttClient publisher(&broker);
publisher.publish("a/b", payload); // This publish is received
@@ -310,6 +367,47 @@ test(network_hudge_payload)
assertEqual(strcmp(payload, lastPayload), 0);
}
test(connack)
{
const bool view = false;
NetworkObserver check(
[this](const WiFiClient*, const uint8_t* buffer, size_t length)
{
if (view) dumpMqttMessage(buffer, length);
if (buffer[0] == MqttMessage::ConnAck)
{
std::string hex = bufferToHexa(buffer, length);
assertStringCaseEqual(hex.c_str(), "20020000");
}
}
);
start_servers(2, true);
assertEqual(WiFi.status(), WL_CONNECTED);
MqttBroker broker(1883);
broker.begin();
IPAddress broker_ip = WiFi.localIP();
ESP8266WiFiClass::selectInstance(2);
MqttClient client;
client.connect(broker_ip.toString().c_str(), 1883);
broker.loop();
assertTrue(broker.clientsCount() == 1);
assertTrue(client.connected());
MqttClient::counters[MqttMessage::Type::SubAck] = 0;
client.subscribe("a/b");
// TODO how to avoid these loops ???
broker.loop();
client.loop();
assertEqual(MqttClient::counters[MqttMessage::Type::SubAck], 1);
}
//----------------------------------------------------------------------------
// setup() and loop()
void setup() {

View File

@@ -1,6 +1,8 @@
# See https://github.com/bxparks/EpoxyDuino for documentation about this
# Makefile to compile and run Arduino programs natively on Linux or MacOS.
EXTRA_CXXFLAGS=-g3 -O0
APP_NAME := string-indexer-tests
ARDUINO_LIBS := AUnit AceCommon AceTime TinyMqtt EspMock ESP8266WiFi ESPAsync
ARDUINO_LIB_DIRS := ../../../EspMock/libraries

View File

@@ -62,6 +62,14 @@ test(indexer_same_strings_should_equal)
assertTrue(one == two);
}
test(indexer_compare_strings_with_same_beginning)
{
IndexedString two("one_two");
IndexedString one("one");
assertNotEqual(one.getIndex(), two.getIndex());
}
test(indexer_indexed_operator_eq)
{
IndexedString one("one");