x-ryl669 / emqtt5 Goto Github PK
View Code? Open in Web Editor NEWAn embedded MQTTv5 client in C++ with minimal footprint, maximal performance
License: MIT License
An embedded MQTTv5 client in C++ with minimal footprint, maximal performance
License: MIT License
Hi,
I tried to port it to RA6M5 Renesas MCU. In Types.hpp
, there is several pre-processors macro such as _WIN32
, _POSIX
, and ESP_PLATFORM
. As RA6M5 is not fall under one of them, I'm not defining anything. When I tried to compile it, there is requirement to include pthreadRTOS.h
. Even after I make empty header file just to pass compilation, at the end of the day it still requires me to define pthread_t
.
On README.md, it said that This code is specialized for embedded system with or **without** an operating system
. AFAIK, to add thread into embedded system, we need to put Real Time OS (FreeRTOS, Azure RTOS, etc). So, my question is, how can I compile it without RTOS dependencies? Is there any pre-processor that I need to define? Or did I misinterpret something? Thank you for your assistance.
It needs a clientID to initialize the Network::Client::MQTTv5, but if we don't have clientID, how to connect to the server? for example, connect to a remote broker.
I am compiling on debian 9 and the linker does not find getEthernetRate() nor getWIFIRate(). I searched the includes and the libraries and the internet and found nothing.
Please where can I get those functions?
(I had to add link libraries pthread and dl to target MQTTc as well and lower the minimum cmake version to 3.8).
Hi! I tried to pass some props to "publish" method.
...
Protocol::MQTT::V5::registerAllProperties();
Network::Client::MQTTv5::Properties properties;
if (!correlation_data.empty()) {
Network::Client::MQTTv5::DynamicBinDataView c_data(correlation_data.length(), (const uint8_t*)correlation_data.c_str());
Protocol::MQTT::V5::Property<Network::Client::MQTTv5::DynamicBinDataView> prop(Protocol::MQTT::V5::CorrelationData, c_data);
if (!properties.append(&prop))
printf("PROP APPEND FAILED!\n");
else
printf("PROP APPEND SUCCESS!\n");
}
client.publish(publish_topic, (const uint8*) publish_message,
strlen(publish_message), retain_published_message, QoS, (uint16)0U, &properties))
But, i recieve
pure virtual method called
terminate called without an active exception
in
uint32 copyInto(uint8 * buffer)
{
o = 1; buffer[0] = header.typeAndFlags;
o += remLength.copyInto(buffer+o);
o += fixedVariableHeader.copyInto(buffer+o);
o += props.copyInto(buffer+o); //HERE
o += payload.copyInto(buffer+o);
return o;
}
Maybe i'm just doing something really stupid, but i can't make it work.
But if i just create empty Network::Client::MQTTv5::Properties properties;
it works (without any property ofc)
Cannot build when setting the value of MQTTOnlyBSDSocket
to 0
in lib/include/Network/Clients/MQTT.hpp
because lib/src/Network/Clients/MQTTClient.cpp
tries to include files that do not exist in the repository.
Hi ,
I am having a scenario of trying to connect the broker again if connection is not successful.
Code is like below: Simple code
Network::Client::MQTTv5 myClient("NameOftheClient" , CallbackForMessage);
std::string serverHost(192.168.3.21);
if( Network::Client::MQTTv5::ErrorType::Success != myClient.connectTo(serverHost.c_str(), 1883))
{
//retry with other ipaddress
std::string serverHost_new(192.168.3.221);
if( Network::Client::MQTTv5::ErrorType::Success != myClient.connectTo(serverHost_new.c_str(), 1883))
{
logger << "connection failed again"
}
}
For testing purpuse
192.168.3.21 is not mqtt broker and expecting connection to fail and result is same.
192.168.3.221 is a valid mqtt broker and expecting connection to success but it return already connected error.
Background analysis:
on connectTo function, there is a below check. If connection is not open, try to connect.
ScopedLock scope(impl->lock);
if (impl->isOpen()) return ErrorType::AlreadyConnected;
For the first time(With invalid mqtt broker address), above check is false and continue to create a socket in impl->connectWith and return network error / timeout error since its a valid.
For the second time (valid mqtt broker address) , above check is return true since the socket is already created first time and returning the already connected.
My observation is the socket is not closed if the connection is not success in the below line:
// Check we can contact the server and connect to it (not initial write to the server is required here)
if (int ret = impl->connectWith(serverHost, port, useTLS))
return ret == -7 ? ErrorType::TimedOut : ErrorType::NetworkError;
Can you help fix it or provide alternate solutions?
in LinuxSpecific.cpp [0] I have to change the typedef, otherwise it will not compile:
typedef uint32_t __u32; /* hack to avoid including kernel header in userspace */
typedef uint16_t __u16; /* ditto */
typedef uint8_t __u8; /* ditto */
// For camir version of #include <linux/ethtool.h>
typedef uint32_t u32; /* hack to avoid including kernel header in userspace */
typedef uint16_t u16; /* ditto */
typedef uint8_t u8; /* ditto */
typedef uint64_t u64; /* ditto */
[0]
my clang says "Undefined symbols". Does eMQTT5 support macOS?
Undefined symbols for architecture x86_64:
"Platform::free(void*, bool)", referenced from:
Network::Client::MQTTv5::connectTo(char const*, unsigned short, bool, unsigned short, bool, char const*, Protocol::MQTT::Common::DynamicBinDataView const*, Protocol::MQTT::V5::WillMessage*, Protocol::MQTT::V5::QualityOfServiceDelivery, bool, Protocol::MQTT::V5::Properties*) in libeMQTT5.a(MQTTClient.cpp.o)
Network::Client::MQTTv5::Impl::Impl(char const*, Network::Client::MessageReceived*, Protocol::MQTT::Common::DynamicBinDataView const*) in libeMQTT5.a(MQTTClient.cpp.o)
Protocol::MQTT::Common::DynamicString::readFrom(unsigned char const*, unsigned int) in libeMQTT5.a(MQTTClient.cpp.o)
Network::Client::MQTTv5::Impl::~Impl() in libeMQTT5.a(MQTTClient.cpp.o)
"Platform::malloc(unsigned long, bool)", referenced from:
Network::Client::MQTTv5::connectTo(char const*, unsigned short, bool, unsigned short, bool, char const*, Protocol::MQTT::Common::DynamicBinDataView const*, Protocol::MQTT::V5::WillMessage*, Protocol::MQTT::V5::QualityOfServiceDelivery, bool, Protocol::MQTT::V5::Properties*) in libeMQTT5.a(MQTTClient.cpp.o)
Network::Client::MQTTv5::Impl::Impl(char const*, Network::Client::MessageReceived*, Protocol::MQTT::Common::DynamicBinDataView const*) in libeMQTT5.a(MQTTClient.cpp.o)
"Platform::realloc(void*, unsigned long)", referenced from:
Protocol::MQTT::Common::DynamicString::readFrom(unsigned char const*, unsigned int) in libeMQTT5.a(MQTTClient.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
In [0] there is the check of the variable byte integer buffer length
uint32 readFrom(const uint8 * buffer, uint32 bufLength)
{
for (size = 0; size < 4;)
{
if ((uint32)(size+1) > bufLength) return NotEnoughData;
value[size] = buffer[size];
if (value[size++] < 0x80) break;
}
return size < 4 ? size : (uint32)BadData;
}
for buffer = {0x8c, 0xda, 0xc4, 0x09}
and bufLength = 4
this will result in BadData
but it should be a valid input.
Is the return condition correct?
I found some improvement for source readability during #4 .
#include <something/something.hpp>
is better than:
#include "../../something/something.hpp"
because ../../
is too strong method we can indicate any files without path setting.
Why is there no unsubscribe function?
Is there a reason for it?
If useful, how could it be implemented?
Hi, it's me again ๐,
when including eMQTT5 into some project, which wants to install eMQTT5 along with some other product, at least the shared object should be installed, possibly even the test program. Using eMQTT5 without local modifications will lead to the effect, that the installed product will not have eMQTT5 installed. CMake before version 3.13 will not allow this to be added from the outside, so could you please add something like
install(TARGETS eMQTT5 LIBRARY DESTINATION lib)
and
install(TARGETS MQTTc RUNTIME DESTINATION bin)
to the respective project files?
Hello,
I am having trouble including the library and I am not sure if I installed or used it correctly.
Sorry, I am not an experienced programmer. I tried to google how cmake should be used, but I haven't found a solution.
I use Ubuntu 20.04 and tried this:
cloned the project to ~/projects/eMQTT5
used those commands:
cmake CMakeLists.txt
make
sudo make install
sudo ldconfig
found MQTTc in /usr/local/bin and libeMQTT5.a in usr/local/lib
but there is nothing in /usr/local/include
in my project which is located in ~/projects/device/src I used
#include "../../eMQTT5/lib/include/Network/Clients/MQTT.hpp"
(#include "Network/Clients/MQTT.hpp" did not work)
but I get include errors in MQTT.hpp :
#include <Network/Clients/MQTTConfig.hpp> and
#include <Protocol/MQTT/MQTT.hpp> can't be found
Thanks for your help!
I run your esp port (esp-eMQTT5) on an ESP32. Note that I'm using MbedTLS with self signed certificates to secure the connection.
Everything works great except for running the eventLoop from another thread.
The thread creation and passing the client (Network::Client::MQTTv5 object) to run the command from works great when running other methods (disconnect, publish, etc) from the separate thread. However, when I try to run eventLoop from the separathe thread, there seems to be an error.
When there are no messages/events to be handled, it looks like it gets stuck in the mbedtls_ssl_read function. I turned on MbedTLS debugging and it printed the following:
I (200617) mbedtls: ssl_tls.c:2813 in_left: 0, nb_want: 5
I (200617) mbedtls: ssl_tls.c:8389 => read
I (200627) mbedtls: ssl_tls.c:4419 => read record
I (200627) mbedtls: ssl_tls.c:2628 => fetch input
I (200637) mbedtls: ssl_tls.c:2789 in_left: 0, nb_want: 5
It prints this once every three seconds. If I change the socket connection to non-blocking, it prints this constantly.
Calling eventLoop() doesn't return in any errors.
When I call eventLoop and there are multiple publish messages/events to be handled, it handles a single event correctly, then disconnects from the (locally hosted) broker.
Hi,
This repo is active for long time but why there is no release version?
I want to implement publisher and subscriber in the same client. Publisher will send data in every 1 second and subscriber will listen for any incoming message in another topic. Can you provide me with any example?
execinfo.h does not exist in alpine linux 3.19
Hence, in Types.hpp the #include <execinfo.h> could not be found. Is it possible to keep this optionally?
I try to parse mqtt packets which I dumped with Wireshark using the MQTTParsePacket.cpp example. Works so far.
In my CONNECT packet, there is an UserProperty key value pair included. packet->dump()
shows my value
I tried to read the Property but I was not sucesssful until now.
Using the example code for reading properties from [0], works not.
// packet is type of Protocol::MQTT::V5::ControlPacketSerializable*
Protocol::MQTT::V5::VisitorVariant visitor;
while(packet->props.getProperty(visitor)) {
switch(visitor.propertyType()) {
case Protocol::MQTT::V5::UserProperty:
{
// no code until now
break;
}
}
}
This does not compile because packet has no props
member.
Next try:
explicit cast packet
to Protocol::MQTT::V5::ConnectPacket*
, result is:
no matching function for call to 'Protocol::MQTT::V5::Properties::getProperty(Protocol::MQTT::V5::VisitorVariant&)'
Next try:
Protocol::MQTT::V5::ConnectPacket* connect_packet = dynamic_cast<Protocol::MQTT::V5::ConnectPacket*>(packet);
auto myProp = connect_packet->props.getProperty(Protocol::MQTT::V5::UserProperty);
if(myProp->type == Protocol::MQTT::V5::UserProperty) {
????
}
Can I cast myProp
to something like UserPropertyProp
or do I need a completely different solution.
[0] https://github.com/X-Ryl669/eMQTT5/blob/master/doc/ClientAPI.md#receiving-packets-from-the-broker
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.