diff --git a/libnymea/hardwaremanager.cpp b/libnymea/hardwaremanager.cpp index e0498d9d..a6a635c9 100644 --- a/libnymea/hardwaremanager.cpp +++ b/libnymea/hardwaremanager.cpp @@ -57,6 +57,11 @@ Returns the BluetoothLowEnergyManager \l{HardwareResource}. */ +/*! \fn MqttProvider* HardwareManager::mqttProvider(); + Returns the MqttProvider \l{HardwareResource}. +*/ + + #include "hardwaremanager.h" #include "hardwareresource.h" diff --git a/libnymea/network/mqtt/mqttchannel.cpp b/libnymea/network/mqtt/mqttchannel.cpp index 7428bdfd..21d49424 100644 --- a/libnymea/network/mqtt/mqttchannel.cpp +++ b/libnymea/network/mqtt/mqttchannel.cpp @@ -1,3 +1,71 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! + \class MqttChannel + \brief Represents a isolated channel between a device and aplugin on the nymea internal MQTT broker + + \ingroup hardware + \inmodule libnymea + + The MQTT channel class holds the required data to connect to the nymea internal MQTT broker. +*/ + +/*! \fn QString MqttChannel::clientId(); + Returns the clientId used to connect to the broker. + + \sa username() \sa password() +*/ + +/*! \fn QString MqttChannel::username(); + Returns the username used to connect to the broker. + + \sa clientId() \sa password() +*/ + +/*! \fn QString MqttChannel::password(); + Returns the password used to connect to the broker. + + \sa username() \sa clientId() +*/ + +/*! \fn QString MqttChannel::serverAddress(); + Returns the server address for the client to connect to. + + \sa username() \sa password() +*/ + +/*! \fn QString MqttChannel::serverPort(); + Returns the server port used to connect to the broker. + + \sa username() \sa password() +*/ + +/*! \fn QString MqttChannel::topicPrefix(); + Returns the topic prefix allowed in the broker's policy for this channel. + Clients connecting to this channel are allowed to subscribe to "topicPrefix/#" as well + as publishing to "topicPrefix/..." +*/ + #include "mqttchannel.h" diff --git a/libnymea/network/mqtt/mqttprovider.cpp b/libnymea/network/mqtt/mqttprovider.cpp index a90d0252..57ac2e5e 100644 --- a/libnymea/network/mqtt/mqttprovider.cpp +++ b/libnymea/network/mqtt/mqttprovider.cpp @@ -1,3 +1,179 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! + \class MqttProvider + \brief Provides means of communicating to devices via MQTT + + \ingroup hardware + \inmodule libnymea + + The MQTT provider class offers 2 different ways to establish a MQTT connection to a MQTT enabled IoT device: + For one it supports establishing a secure channel between the device and the plugin, using nymea's internal MQTT + broker. The second approach is to provide a generic MQTT client object connected to nymea's internal MQTT broker. + + Note, if you whish to establish a MQTT connection to an external MQTT broker, you can just create your own MqttClient + and connect to wherever you need to. The MqttProvider hardware resource only manages connections to the nymea internal + MQTT broker. + + If using MqttProvider hardware resource, the MQTT broker will be automatically configured with appropriate policies. + + \chapter Example 1 + + Establishing a secure MQTT directly between plugin and the MQTT device: + + \tt devicepluginexample.h + + \code + #include "network/mqtt/mqttprovider.h" + #include "network/mqtt/mqttchannel.h" + + class DevicePluginExample : public DevicePlugin + { + ... + public: + DeviceManager::DeviceSetupStatus setupDevice(Device* device) override; + void deviceRemoved(Device* device) override; + + private slots: + void onDevicePublishReceived(MqttChannel* channel, const QString &topic, const QByteArray &payload); + + ... + + }; + + \endcode + + \tt devicepluginexample.cpp + + \code + DeviceManager::DeviceSetupStatus DevicePluginExample::setupDevice(Device *device) { + MqttChannel *channel = hardware()->mqttProvider()->createChannel(device->id(), "192.168.0.100"); + + // Provision credentials to device: + QString clientId = channel->clientId(); + QString username = channel->username(); + QString password = channel->password(); + hardwareManager()->networkManager()->post("https://192.168.0.100/setup?clientId=" + username + "&username=" + username); + + // connect to publishes in this channel + connect(channel, &MqttChannel::publishReceived, this, onDevicePublishReceived); + + // publish to the channel + channel->publish(channel->prefix() + "/my/test/topic", "Hello world"); + } + + void DevicePluginExample::deviceRemoved(Device* device) { + hardware()->mqttProvider()->releaseChannel(channel); + } + + void DevicePluginExample::onDevicePublishReceibed(MqttChannel *channel, const QString &topic, const QByteArray &payload) { + qCDebug(dcExample()) << "Publish received from:" << channel->clientId() << topic << payload; + } + \endcode + + \chapter Example 2 + + Obtaining a MQTT client connected to the nymea internal MQTT broker: + + \tt devicepluginexample.h + + \code + #include "network/mqtt/mqttprovider.h" + #include " + + class DevicePluginExample : public DevicePlugin + { + ... + public: + DeviceManager::DeviceSetupStatus setupDevice(Device* device) override; + void deviceRemoved(Device* device) override; + + private slots: + void onPublishReceived(const QString &topic, const QByteArray &payload, bool retained); + + ... + + }; + + \endcode + + \tt devicepluginexample.cpp + + \code + DeviceManager::DeviceSetupStatus DevicePluginExample::setupDevice(Device *device) { + MqttClient *client = hardware()->mqttProvider()->createInternalClient(device->id()); + + // subscribe to topics + client->subscribe("/my/test/topic", Mqtt::QuS1); + + // connect to publishes in this channel + connect(channel, &MqttClient::publishReceived, this, onPublishReceived); + + // publish to the broker + client->publish("/my/test/topic", "Hello world"); + } + + void DevicePluginExample::deviceRemoved(Device* device) { + hardware()->mqttProvider()->releaseChannel(channel); + } + + void DevicePluginExample::onPublishRecei(const QString &topic, const QByteArray &payload, bool retained) { + qCDebug(dcExample()) << "Publish received from:" << channel->clientId() << topic << payload << retained; + } + \endcode + + + \sa HardwareResource, HardwareManager::mqttProvider() +*/ + +/*! \fn MqttChannel *MqttProvider::createChannel(const DeviceId &deviceId, const QHostAddress &clientAddress); + Creates a new MQTT channel on the internal broker. The returned channel will have the required details for the + client device to connect to the broker. A temporaray clientId/user/password combination will be created and + clients connecting to the broker with those credentials will have access to subscribe and post to # within the + given topic prefix. + + \sa releaseChannel(MqttChannel *channel) +*/ + +/*! \fn void MqttProvider::releaseChannel(MqttChannel *channel) + Releases the given MQTT channel. This means the broker will disconnect any clients connected on this channel + and remove the policy from the broker. The channel object will be destroyed and must not be accessed any more + after calling this function. + + \sa createChannel(const DeviceId &deviceId, const QHostAddress &clientAddress) +*/ + +/*! \fn MqttClient *MqttProvider::createInternalClient(const DeviceId &deviceId); + Creates a temporary policy on the internal MQTT broker to allow this client connecting. If that is successful + it will create a new MqttClient object and connect it to the broker. + + The client will not be subscribed to any topics yet. See the nymea-mqtt documentation for information on the MqttClient API. + + The client will be owned by the MqttProvider and cleaned up when the system goes down, however, the user is free to + delete the client at any point. The policy attached to it will be removed from the MQTT broker. +*/ + + #include "mqttprovider.h" #include "mqttchannel.h" diff --git a/libnymea/network/mqtt/mqttprovider.h b/libnymea/network/mqtt/mqttprovider.h index 1e2d7e83..187c1d1a 100644 --- a/libnymea/network/mqtt/mqttprovider.h +++ b/libnymea/network/mqtt/mqttprovider.h @@ -1,3 +1,25 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 2018 Michael Zanetti * + * * + * This file is part of nymea. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; If not, see * + * . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef MQTTPROVIDER_H #define MQTTPROVIDER_H