40#include "ESP8266WiFi.h"
55#include <PubSubClient.h>
77 typedef std::function<void(
CBORObject &)> CBORExtender;
87 : mpCredentials(&credentials),
89 mInfoExtender(infoExtender),
90 mPubSubClient(mWiFiClient),
91 mNetworkConnected(false),
93 mPubSubClient.setCallback([
this](
char *topic, uint8_t *payload,
unsigned int length) {
102 if (_readCOSEMessage(
Bytes(payload, length), decoded)) {
103 device->
handle(topic, decoded);
133 mPubSubClient.setServer(domain, port);
144 if (mDevices.pushUnique(&device)) {
146 device.topics()->
forEach([
this](String topic) {
147 mPubSubClient.subscribe(topic.c_str());
160 if (mDevices.removeOne(&device)) {
162 device.topics()->
forEach([
this](String topic) {
163 mPubSubClient.unsubscribe(topic.c_str());
195 scheduler.
push(
"mqtt", mTaskMQTT);
218 mNetworkConnected =
true;
228 mNetworkConnected =
false;
237 if (!mTaskMQTT->isAttached()) {
238 mTaskMQTT->attach(10);
254 return &mPubSubClient;
261 inline void _initTasks() {
263 if (!mNetworkConnected) {
267 if (!mPubSubClient.connected()) {
269 Bytes packetExtention;
272 mInfoExtender(packet);
273 packetExtention = packet.build();
276 CBORObject offlineCBOR(packetExtention);
277 _prepareOfflinePacket(offlineCBOR);
278 auto offlinePacket = _buildCOSEMessage(offlineCBOR.build());
279 auto password = _getUserPassword();
280 if (mPubSubClient.connect(
281 _getClientId().c_str(),
282 _getUserLogin().c_str(),
283 (
const char *)password.raw(),
285 mPath.buildDevicePath(
"status").c_str(),
288 (
const char *)offlinePacket.raw(),
289 offlinePacket.size(),
291 CBORObject onlineCBOR(packetExtention);
292 _prepareOnlinePacket(onlineCBOR);
293 auto onlinePacket = _buildCOSEMessage(onlineCBOR.build());
294 mPubSubClient.publish(
295 mPath.buildDevicePath(
"status").c_str(),
300 device->topics()->forEach([
this](String topic) {
301 mPubSubClient.subscribe(topic.c_str());
309 mPubSubClient.loop();
319 Bytes _buildCOSEMessage(
const Bytes &payload,
bool sign =
false) {
321 obj.setPayload(payload);
322 auto kid = mpCredentials->keyId();
324 obj.sign(*mpCredentials);
325 obj.setUnprotectedKid(kid);
337 bool _readCOSEMessage(
const Bytes &message, Bytes &outPayload) {
338 COSEMessage obj(message);
339 if (obj.wasReadSuccessful()) {
340 outPayload = obj.getPayload();
353 void _prepareOnlinePacket(CBORObject &packet) {
356 .put(
"connection_id", mConnectionId++);
366 void _prepareOfflinePacket(CBORObject &packet) {
369 .put(
"connection_id", mConnectionId);
376 String _getClientId() {
377 return "device:" + mpCredentials->getDeviceId();
384 String _getUserLogin() {
385 return mpCredentials->getPublicKey();
396 Bytes _getUserPassword() {
398 auto protectedData = password.putMap(
"protected");
399 protectedData.put(
"device", mpCredentials->getDeviceId().c_str());
400 protectedData.put(
"owner", mpCredentials->getOwnerId().c_str());
401 protectedData.put(
"creator", mpCredentials->getCreatorId().c_str());
402 protectedData.put(
"timestamp",
static_cast<int64_t
>(
Date::now()));
403 auto unprotectedData = password.putMap(
"unprotected");
404 unprotectedData.put(
"alg",
"EdDSA");
406 auto signature = mpCredentials->sign(protectedData.build());
407 password.put(
"signature", signature.raw(), signature.size());
409 return password.build();
412 const Credentials *mpCredentials;
415 CBORExtender mInfoExtender;
416 PubSubClient mPubSubClient;
418 bool mNetworkConnected;
421 WiFiClient mWiFiClient;
423 ClearQueue<MQTTDevice *> mDevices;
MQTT event definitions for the Uniot event system.
Network event definitions for the Uniot event system.
Complete WiFi network management and configuration system.
void forEach(VoidCallback callback) const
Executes a callback function on each element in the queue.
Definition ClearQueue.h:325
Definition CBORObject.h:40
Manages device identity and cryptographic credentials for Uniot devices.
Definition Credentials.h:61
void forceSync()
Forces immediate NTP time synchronization.
Definition Date.h:139
static time_t now()
Returns the current Unix timestamp.
Definition Date.h:74
void emitEvent(unsigned int topic, int msg)
EventListener * stopListeningToEvent(unsigned int topic)
EventListener * listenToEvent(unsigned int topic)
Interface for connecting components to the TaskScheduler.
Definition ISchedulerConnectionKit.h:35
virtual void syncSubscriptions()=0
Reconstructs subscriptions after reconnection or credential changes.
bool isSubscribed(const String &topic)
Checks if the device is subscribed to a given topic.
Definition MQTTDevice.cpp:126
void unsubscribeFromAll()
Unsubscribes from all subscribed topics.
Definition MQTTDevice.cpp:55
virtual void handle(const String &topic, const Bytes &payload)=0
Handles incoming MQTT messages.
virtual void pushTo(TaskScheduler &scheduler) override
Registers MQTT tasks with the provided scheduler.
Definition MQTTKit.h:194
friend class MQTTDevice
Definition MQTTKit.h:78
~MQTTKit()
Destructor - cleans up event listeners.
Definition MQTTKit.h:121
void setServer(const char *domain, uint16_t port)
Sets the MQTT broker server address and port.
Definition MQTTKit.h:132
void renewSubscriptions()
Renews all device subscriptions.
Definition MQTTKit.h:182
const MQTTPath & getPath()
Gets the MQTT path helper object.
Definition MQTTKit.h:172
virtual void attach() override
Attaches this kit (empty implementation)
Definition MQTTKit.h:202
void addDevice(MQTTDevice &device)
Adds a device to be managed by this MQTT kit.
Definition MQTTKit.h:143
MQTTKit(const Credentials &credentials, CBORExtender infoExtender=nullptr)
Constructs an MQTTKit instance.
Definition MQTTKit.h:86
PubSubClient * client()
Gets access to the underlying PubSubClient.
Definition MQTTKit.h:253
virtual void onEventReceived(unsigned int topic, int msg) override
Handles network and time events.
Definition MQTTKit.h:214
void removeDevice(MQTTDevice &device)
Removes a device from this MQTT kit.
Definition MQTTKit.h:159
Definition TaskScheduler.h:67
static Date & getInstance()
Definition Singleton.h:73
Definition TaskScheduler.h:164
EventListener< unsigned int, int, Bytes > CoreEventListener
Type alias for the common EventListener configuration used in the core system.
Definition EventListener.h:100
#define UNIOT_LOG_DEBUG(...)
Log an DEBUG level message Used for general information about system operation. Only compiled if UNIO...
Definition Logger.h:293
#define UNIOT_LOG_ERROR(...)
Log an ERROR level message Used for critical errors that may prevent normal operation....
Definition Logger.h:226
SharedPointer< SchedulerTask > TaskPtr
Shared pointer type for scheduler tasks.
Definition TaskScheduler.h:171
static TaskPtr make(SchedulerTask::SchedulerTaskCallback callback)
Static factory method to create a task with a callback.
Definition TaskScheduler.h:193
TaskScheduler & push(const char *name, TaskPtr task)
Add a named task to the scheduler.
Definition TaskScheduler.h:214
@ TIME
Time synchronization and date-related operations.
Definition DateEvents.h:61
@ SYNCED
System time has been successfully synchronized with time source.
Definition DateEvents.h:72
@ CONNECTION
MQTT connection state changes and operations.
Definition MQTTEvents.h:61
@ SUCCESS
MQTT connection established successfully.
Definition MQTTEvents.h:73
@ FAILED
MQTT connection failed or was lost.
Definition MQTTEvents.h:72
@ DISCONNECTING
Currently disconnecting from network.
Definition NetworkEvents.h:88
@ SUCCESS
Network operation completed successfully.
Definition NetworkEvents.h:86
@ ACCESS_POINT
Device is operating in access point mode.
Definition NetworkEvents.h:90
@ AVAILABLE
Configured network is available for connection.
Definition NetworkEvents.h:91
@ DISCONNECTED
Network connection has been lost or terminated.
Definition NetworkEvents.h:89
@ FAILED
Network operation failed (connection, scan, etc.)
Definition NetworkEvents.h:85
@ CONNECTING
Currently attempting to connect to network.
Definition NetworkEvents.h:87
@ CONNECTION
WiFi connection state changes and operations.
Definition NetworkEvents.h:74
Contains all classes and functions related to the Uniot Core.