add observing resources
add documentation
This commit is contained in:
parent
d5af628a52
commit
9195f06462
@ -62,6 +62,11 @@
|
||||
This signal is emitted when a \a reply is finished.
|
||||
*/
|
||||
|
||||
/*! \fn void Coap::notificationReceived(const CoapObserveResource &resource, const int ¬ificationNumber, const QByteArray &payload);
|
||||
This signal is emitted when a value of an observed \a resource changed. The \a notificationNumber specifies the the count of the notification
|
||||
to keep the correct order. The value can be parsed from the \a payload.
|
||||
*/
|
||||
|
||||
#include "coap.h"
|
||||
#include "coappdu.h"
|
||||
#include "coapoption.h"
|
||||
@ -216,6 +221,67 @@ CoapReply *Coap::deleteResource(const CoapRequest &request)
|
||||
return reply;
|
||||
}
|
||||
|
||||
/*! Enables notifications (observing) on the CoAP server for the resource specified in the
|
||||
* given \a request.
|
||||
* Returns a \l{CoapReply} to match the response with the request. */
|
||||
CoapReply *Coap::enableResourceNotifications(const CoapRequest &request)
|
||||
{
|
||||
CoapReply *reply = new CoapReply(request, this);
|
||||
reply->setRequestMethod(CoapPdu::Get);
|
||||
reply->setObservation(true);
|
||||
reply->setObservationEnable(true);
|
||||
|
||||
connect(reply, &CoapReply::timeout, this, &Coap::onReplyTimeout);
|
||||
connect(reply, &CoapReply::finished, this, &Coap::onReplyFinished);
|
||||
|
||||
if (request.url().scheme() != "coap") {
|
||||
reply->setError(CoapReply::InvalidUrlSchemeError);
|
||||
reply->m_isFinished = true;
|
||||
return reply;
|
||||
}
|
||||
|
||||
// check if there is a request running
|
||||
if (m_reply == 0) {
|
||||
m_reply = reply;
|
||||
lookupHost();
|
||||
} else {
|
||||
m_replyQueue.enqueue(reply);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
/*! Disables notifications (observing) on the CoAP server for the resource specified in the
|
||||
* given \a request.
|
||||
* Returns a \l{CoapReply} to match the response with the request. */
|
||||
CoapReply *Coap::disableNotifications(const CoapRequest &request)
|
||||
{
|
||||
CoapReply *reply = new CoapReply(request, this);
|
||||
reply->setRequestMethod(CoapPdu::Get);
|
||||
reply->setMessageType(CoapPdu::Reset);
|
||||
reply->setObservation(true);
|
||||
reply->setObservationEnable(false);
|
||||
|
||||
connect(reply, &CoapReply::timeout, this, &Coap::onReplyTimeout);
|
||||
connect(reply, &CoapReply::finished, this, &Coap::onReplyFinished);
|
||||
|
||||
if (request.url().scheme() != "coap") {
|
||||
reply->setError(CoapReply::InvalidUrlSchemeError);
|
||||
reply->m_isFinished = true;
|
||||
return reply;
|
||||
}
|
||||
|
||||
// check if there is a request running
|
||||
if (m_reply == 0) {
|
||||
m_reply = reply;
|
||||
lookupHost();
|
||||
} else {
|
||||
m_replyQueue.enqueue(reply);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
void Coap::lookupHost()
|
||||
{
|
||||
int lookupId = QHostInfo::lookupHost(m_reply->request().url().host(), this, SLOT(hostLookupFinished(QHostInfo)));
|
||||
@ -230,21 +296,42 @@ void Coap::sendRequest(CoapReply *reply, const bool &lookedUp)
|
||||
pdu.createMessageId();
|
||||
pdu.createToken();
|
||||
|
||||
// Add the options in correct order
|
||||
// Option number 3
|
||||
if (lookedUp)
|
||||
pdu.addOption(CoapOption::UriHost, reply->request().url().host().toUtf8());
|
||||
|
||||
if (reply->observation() && reply->requestMethod() == CoapPdu::Get) {
|
||||
if (reply->observationEnable()) {
|
||||
// Option number 6
|
||||
pdu.addOption(CoapOption::Observe, QByteArray::number(0));
|
||||
m_observeResources.insert(pdu.token(), CoapObserveResource(reply->request().url(), pdu.token()));
|
||||
} else {
|
||||
// if disable, we should use the sam token as the notifications
|
||||
foreach (const CoapObserveResource &resource, m_observeResources.values()) {
|
||||
if (resource.url() == reply->request().url()) {
|
||||
pdu.setToken(resource.token());
|
||||
}
|
||||
}
|
||||
// Option number 6
|
||||
pdu.addOption(CoapOption::Observe, QByteArray::number(1));
|
||||
if (m_observeResources.contains(pdu.token()))
|
||||
m_observeResources.remove(pdu.token());
|
||||
}
|
||||
}
|
||||
|
||||
// Option number 7
|
||||
if (reply->port() != 5683)
|
||||
pdu.addOption(CoapOption::UriPort, QByteArray::number(reply->request().url().port()));
|
||||
|
||||
QStringList urlTokens = reply->request().url().path().split("/");
|
||||
urlTokens.removeAll(QString());
|
||||
|
||||
// Option number 11
|
||||
foreach (const QString &token, urlTokens)
|
||||
pdu.addOption(CoapOption::UriPath, token.toUtf8());
|
||||
|
||||
if (reply->request().url().hasQuery())
|
||||
pdu.addOption(CoapOption::UriQuery, reply->request().url().query().toUtf8());
|
||||
|
||||
if (reply->requestMethod() == CoapPdu::Get)
|
||||
pdu.addOption(CoapOption::Block2, CoapPduBlock::createBlock(0));
|
||||
|
||||
// Option number 12
|
||||
if (reply->requestMethod() == CoapPdu::Post || reply->requestMethod() == CoapPdu::Put) {
|
||||
pdu.addOption(CoapOption::ContentFormat, QByteArray(1, ((quint8)reply->request().contentType())));
|
||||
|
||||
@ -257,6 +344,14 @@ void Coap::sendRequest(CoapReply *reply, const bool &lookedUp)
|
||||
}
|
||||
}
|
||||
|
||||
// Option number 15
|
||||
if (reply->request().url().hasQuery())
|
||||
pdu.addOption(CoapOption::UriQuery, reply->request().url().query().toUtf8());
|
||||
|
||||
// Option number 23
|
||||
if (reply->requestMethod() == CoapPdu::Get)
|
||||
pdu.addOption(CoapOption::Block2, CoapPduBlock::createBlock(0));
|
||||
|
||||
QByteArray pduData = pdu.pack();
|
||||
reply->setRequestData(pduData);
|
||||
reply->setMessageId(pdu.messageId());
|
||||
@ -264,8 +359,6 @@ void Coap::sendRequest(CoapReply *reply, const bool &lookedUp)
|
||||
reply->m_lockedUp = lookedUp;
|
||||
reply->m_timer->start();
|
||||
|
||||
qDebug() << "--->" << pdu;
|
||||
|
||||
// send the data
|
||||
if (reply->request().messageType() == CoapPdu::NonConfirmable) {
|
||||
sendData(reply->hostAddress(), reply->port(), pduData);
|
||||
@ -286,30 +379,43 @@ void Coap::sendCoapPdu(const QHostAddress &hostAddress, const quint16 &port, con
|
||||
m_socket->writeDatagram(pdu.pack(), hostAddress, port);
|
||||
}
|
||||
|
||||
void Coap::processResponse(const CoapPdu &pdu)
|
||||
void Coap::processResponse(const CoapPdu &pdu, const QHostAddress &address, const quint16 &port)
|
||||
{
|
||||
qDebug() << "<---" << pdu;
|
||||
// if we are waiting for a response
|
||||
if (m_reply) {
|
||||
qDebug() << "<---" << QString("%1:%2").arg(address.toString()).arg(QString::number(port)) << pdu;
|
||||
if (!pdu.isValid()) {
|
||||
qWarning() << "Got invalid PDU";
|
||||
m_reply->setError(CoapReply::InvalidPduError);
|
||||
m_reply->setFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pdu.isValid()) {
|
||||
qWarning() << "Got invalid PDU";
|
||||
m_reply->setError(CoapReply::InvalidPduError);
|
||||
m_reply->setFinished();
|
||||
// check if the message is a response to a reply (message id based check)
|
||||
if (m_reply->messageId() == pdu.messageId()) {
|
||||
processIdBasedResponse(m_reply, pdu);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if we know the message by token (message token based check)
|
||||
if (m_reply->messageToken() == pdu.token()) {
|
||||
processTokenBasedResponse(m_reply, pdu);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// check if this is a notification from a known observed resource
|
||||
if (m_observeResources.keys().contains(pdu.token())) {
|
||||
processNotification(pdu, address, port);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the message is a response to a reply (message id based check)
|
||||
if (m_reply->messageId() == pdu.messageId()) {
|
||||
processIdBasedResponse(m_reply, pdu);
|
||||
return;
|
||||
}
|
||||
qWarning() << "Got message without request or registered observe resource.";
|
||||
CoapPdu responsePdu;
|
||||
responsePdu.setMessageType(CoapPdu::Reset);
|
||||
responsePdu.setMessageId(pdu.messageId());
|
||||
responsePdu.setToken(pdu.token());
|
||||
sendCoapPdu(address, port, responsePdu);
|
||||
|
||||
// check if we know the message by token (message token based check)
|
||||
if (m_reply->messageToken() == pdu.token()) {
|
||||
processTokenBasedResponse(m_reply, pdu);
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Got message without request";
|
||||
}
|
||||
|
||||
void Coap::processIdBasedResponse(CoapReply *reply, const CoapPdu &pdu)
|
||||
@ -355,6 +461,27 @@ void Coap::processTokenBasedResponse(CoapReply *reply, const CoapPdu &pdu)
|
||||
reply->setFinished();
|
||||
}
|
||||
|
||||
void Coap::processNotification(const CoapPdu &pdu, const QHostAddress &address, const quint16 &port)
|
||||
{
|
||||
// respond with ACK
|
||||
CoapPdu responsePdu;
|
||||
responsePdu.setMessageType(CoapPdu::Acknowledgement);
|
||||
responsePdu.setStatusCode(CoapPdu::Empty);
|
||||
responsePdu.setMessageId(pdu.messageId());
|
||||
responsePdu.setToken(pdu.token());
|
||||
sendCoapPdu(address, port, responsePdu);
|
||||
|
||||
int notificationNumber = 0;
|
||||
foreach (const CoapOption &option, pdu.options()) {
|
||||
if (option.option() == CoapOption::Observe) {
|
||||
notificationNumber = option.data().toHex().toInt(0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
CoapObserveResource resource = m_observeResources.value(pdu.token());
|
||||
emit notificationReceived(resource, notificationNumber, pdu.payload());
|
||||
}
|
||||
|
||||
void Coap::processBlock1Response(CoapReply *reply, const CoapPdu &pdu)
|
||||
{
|
||||
qDebug() << "sent successfully block #" << pdu.block().blockNumber();
|
||||
@ -383,21 +510,27 @@ void Coap::processBlock1Response(CoapReply *reply, const CoapPdu &pdu)
|
||||
nextBlockRequest.setMessageId(pdu.messageId() + 1);
|
||||
nextBlockRequest.setToken(pdu.token());
|
||||
|
||||
// Add the options in correct order
|
||||
// Option number 3
|
||||
if (reply->m_lockedUp)
|
||||
nextBlockRequest.addOption(CoapOption::UriHost, reply->request().url().host().toUtf8());
|
||||
|
||||
// Option number 7
|
||||
if (reply->port() != 5683)
|
||||
nextBlockRequest.addOption(CoapOption::UriPort, QByteArray::number(reply->request().url().port()));
|
||||
|
||||
QStringList urlTokens = reply->request().url().path().split("/");
|
||||
urlTokens.removeAll(QString());
|
||||
|
||||
// Option number 11
|
||||
foreach (const QString &token, urlTokens)
|
||||
nextBlockRequest.addOption(CoapOption::UriPath, token.toUtf8());
|
||||
|
||||
// Option number 15
|
||||
if (reply->request().url().hasQuery())
|
||||
nextBlockRequest.addOption(CoapOption::UriQuery, reply->request().url().query().toUtf8());
|
||||
|
||||
// Option number 27
|
||||
nextBlockRequest.addOption(CoapOption::Block1, CoapPduBlock::createBlock(pdu.block().blockNumber() + 1, 2, moreFlag));
|
||||
|
||||
nextBlockRequest.setPayload(newBlockData);
|
||||
@ -432,22 +565,27 @@ void Coap::processBlock2Response(CoapReply *reply, const CoapPdu &pdu)
|
||||
nextBlockRequest.setMessageId(pdu.messageId() + 1);
|
||||
nextBlockRequest.setToken(pdu.token());
|
||||
|
||||
// Add the options in correct order
|
||||
// Option number 3
|
||||
if (reply->m_lockedUp)
|
||||
nextBlockRequest.addOption(CoapOption::UriHost, reply->request().url().host().toUtf8());
|
||||
|
||||
// Option number 7
|
||||
if (reply->port() != 5683)
|
||||
nextBlockRequest.addOption(CoapOption::UriPort, QByteArray::number(reply->request().url().port()));
|
||||
|
||||
|
||||
QStringList urlTokens = reply->request().url().path().split("/");
|
||||
urlTokens.removeAll(QString());
|
||||
|
||||
// Option number 11
|
||||
foreach (const QString &token, urlTokens)
|
||||
nextBlockRequest.addOption(CoapOption::UriPath, token.toUtf8());
|
||||
|
||||
// Option number 15
|
||||
if (reply->request().url().hasQuery())
|
||||
nextBlockRequest.addOption(CoapOption::UriQuery, reply->request().url().query().toUtf8());
|
||||
|
||||
// Option number 23
|
||||
nextBlockRequest.addOption(CoapOption::Block2, CoapPduBlock::createBlock(pdu.block().blockNumber() + 1, 2, false));
|
||||
|
||||
QByteArray pduData = nextBlockRequest.pack();
|
||||
@ -496,7 +634,7 @@ void Coap::onReadyRead()
|
||||
}
|
||||
|
||||
CoapPdu pdu(data);
|
||||
processResponse(pdu);
|
||||
processResponse(pdu, hostAddress, port);
|
||||
}
|
||||
|
||||
void Coap::onReplyTimeout()
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "libguh.h"
|
||||
#include "coaprequest.h"
|
||||
#include "coapreply.h"
|
||||
#include "coapobserveresource.h"
|
||||
|
||||
/* Information about CoAP
|
||||
*
|
||||
@ -37,6 +38,7 @@
|
||||
* Blockwise transfers in CoAP : https://tools.ietf.org/html/draft-ietf-core-block-18
|
||||
* Constrained RESTful Environments (CoRE) Link Format : http://tools.ietf.org/html/rfc6690
|
||||
* Observing Resources in CoAP : https://tools.ietf.org/html/rfc7641
|
||||
*
|
||||
*/
|
||||
|
||||
class LIBGUH_EXPORT Coap : public QObject
|
||||
@ -52,28 +54,36 @@ public:
|
||||
CoapReply *post(const CoapRequest &request, const QByteArray &data = QByteArray());
|
||||
CoapReply *deleteResource(const CoapRequest &request);
|
||||
|
||||
// Notifications for observable resources
|
||||
CoapReply *enableResourceNotifications(const CoapRequest &request);
|
||||
CoapReply *disableNotifications(const CoapRequest &request);
|
||||
|
||||
private:
|
||||
QUdpSocket *m_socket;
|
||||
|
||||
CoapReply *m_reply;
|
||||
QHash<int, CoapReply *> m_runningHostLookups;
|
||||
QHash<QByteArray, CoapObserveResource> m_observeResources;
|
||||
|
||||
QQueue<CoapReply *> m_replyQueue;
|
||||
|
||||
void lookupHost();
|
||||
void sendRequest(CoapReply *reply, const bool &lookedUp = false);
|
||||
void sendData(const QHostAddress &hostAddress, const quint16 &port, const QByteArray &data);
|
||||
void sendCoapPdu(const QHostAddress &hostAddress, const quint16 &port, const CoapPdu &pdu);
|
||||
void sendCoapPdu(const QHostAddress &address, const quint16 &port, const CoapPdu &pdu);
|
||||
|
||||
void processResponse(const CoapPdu &pdu);
|
||||
void processResponse(const CoapPdu &pdu, const QHostAddress &address, const quint16 &port);
|
||||
void processIdBasedResponse(CoapReply *reply, const CoapPdu &pdu);
|
||||
void processTokenBasedResponse(CoapReply *reply, const CoapPdu &pdu);
|
||||
|
||||
void processNotification(const CoapPdu &pdu, const QHostAddress &address, const quint16 &port);
|
||||
|
||||
void processBlock1Response(CoapReply *reply, const CoapPdu &pdu);
|
||||
void processBlock2Response(CoapReply *reply, const CoapPdu &pdu);
|
||||
|
||||
signals:
|
||||
void replyFinished(CoapReply *reply);
|
||||
void notificationReceived(const CoapObserveResource &resource, const int ¬ificationNumber, const QByteArray &payload);
|
||||
|
||||
private slots:
|
||||
void hostLookupFinished(const QHostInfo &hostInfo);
|
||||
@ -82,4 +92,5 @@ private slots:
|
||||
void onReplyFinished();
|
||||
};
|
||||
|
||||
|
||||
#endif // COAP_H
|
||||
|
||||
65
libguh/coap/coapobserveresource.cpp
Normal file
65
libguh/coap/coapobserveresource.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of QtCoap. *
|
||||
* *
|
||||
* QtCoap is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 3 of the License. *
|
||||
* *
|
||||
* QtCoap 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with QtCoap. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*!
|
||||
\class CoapObserveResource
|
||||
\brief Holds information about an observed resource.
|
||||
|
||||
\ingroup coap
|
||||
\inmodule libguh
|
||||
|
||||
The CoapObserveResource class holds information about an observed resource.
|
||||
|
||||
\sa Coap::notificationReceived()
|
||||
|
||||
*/
|
||||
|
||||
#include "coapobserveresource.h"
|
||||
|
||||
/*! Constructs a CoapObserveResource. */
|
||||
CoapObserveResource::CoapObserveResource()
|
||||
{
|
||||
}
|
||||
|
||||
/*! Constructs a CoapObserveResource with the given \a url and \a token. */
|
||||
CoapObserveResource::CoapObserveResource(const QUrl &url, const QByteArray &token):
|
||||
m_url(url),
|
||||
m_token(token)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Constructs a copy of the given \a other \l{CoapObserveResource}. */
|
||||
CoapObserveResource::CoapObserveResource(const CoapObserveResource &other)
|
||||
{
|
||||
m_url = other.url();
|
||||
m_token = other.token();
|
||||
}
|
||||
|
||||
/*! Returns the url of this \l{CoapObserveResource}. */
|
||||
QUrl CoapObserveResource::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
/*! Returns the token of this \l{CoapObserveResource}. */
|
||||
QByteArray CoapObserveResource::token() const
|
||||
{
|
||||
return m_token;
|
||||
}
|
||||
46
libguh/coap/coapobserveresource.h
Normal file
46
libguh/coap/coapobserveresource.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
|
||||
* *
|
||||
* This file is part of QtCoap. *
|
||||
* *
|
||||
* QtCoap is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, version 3 of the License. *
|
||||
* *
|
||||
* QtCoap 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with QtCoap. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef COAPOBSERVERESOURCE_H
|
||||
#define COAPOBSERVERESOURCE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
#include "libguh.h"
|
||||
|
||||
class LIBGUH_EXPORT CoapObserveResource
|
||||
{
|
||||
|
||||
public:
|
||||
CoapObserveResource();
|
||||
CoapObserveResource(const QUrl &url, const QByteArray &token);
|
||||
CoapObserveResource(const CoapObserveResource &other);
|
||||
|
||||
QUrl url() const;
|
||||
QByteArray token() const;
|
||||
|
||||
private:
|
||||
QUrl m_url;
|
||||
QByteArray m_token;
|
||||
|
||||
};
|
||||
|
||||
#endif // COAPOBSERVERESOURCE_H
|
||||
@ -41,6 +41,8 @@
|
||||
|
||||
\value IfNoneMatch
|
||||
|
||||
\value Observe
|
||||
\l{https://tools.ietf.org/html/rfc7641}
|
||||
\value UriPort
|
||||
|
||||
\value LocationPath
|
||||
@ -58,8 +60,10 @@
|
||||
\value LocationQuery
|
||||
|
||||
\value Block2
|
||||
\l{https://tools.ietf.org/html/draft-ietf-core-block-18}
|
||||
|
||||
\value Block1
|
||||
\l{https://tools.ietf.org/html/draft-ietf-core-block-18}
|
||||
|
||||
\value ProxyUri
|
||||
|
||||
@ -73,19 +77,21 @@
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
/*! Constructs a \l{CoapOption} . */
|
||||
/*! Constructs a CoapOption. */
|
||||
CoapOption::CoapOption()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Constructs a \l{CoapOption} with the given \a option and option \a data. */
|
||||
/*! Constructs a CoapOption with the given \a option and option \a data. */
|
||||
CoapOption::CoapOption(const CoapOption::Option &option, const QByteArray &data) :
|
||||
m_option(option),
|
||||
m_data(data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Sets the option value of this CoapOption to the given \a option . */
|
||||
/*! Sets the \l{CoapOption::Option} of this CoapOption to the given \a option. */
|
||||
void CoapOption::setOption(const CoapOption::Option &option)
|
||||
{
|
||||
m_option = option;
|
||||
@ -111,6 +117,10 @@ QByteArray CoapOption::data() const
|
||||
|
||||
#include "coappdu.h"
|
||||
|
||||
/*! Writes the data of the given \a coapOption to \a dbg.
|
||||
|
||||
\sa CoapOption
|
||||
*/
|
||||
QDebug operator<<(QDebug debug, const CoapOption &coapOption)
|
||||
{
|
||||
const QMetaObject &metaObject = CoapOption::staticMetaObject;
|
||||
@ -147,7 +157,10 @@ QDebug operator<<(QDebug debug, const CoapOption &coapOption)
|
||||
debug.nospace() << "CoapOption(" << optionEnum.valueToKey(coapOption.option()) << "): " << coapOption.data().toHex() << " Block #" << block.blockNumber() << ", More flag = " << block.moreFlag() << ", SZX:" << block.blockSize() << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case CoapOption::Observe: {
|
||||
debug.nospace() << "CoapOption(" << optionEnum.valueToKey(coapOption.option()) << "): " << coapOption.data().toHex().toInt(0, 16) << endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
QString optionName = optionEnum.valueToKey(coapOption.option());
|
||||
if (optionName.isNull()) {
|
||||
|
||||
@ -39,6 +39,7 @@ public:
|
||||
UriHost = 3,
|
||||
ETag = 4,
|
||||
IfNoneMatch = 5,
|
||||
Observe = 6, // (Observe) https://tools.ietf.org/html/rfc7641
|
||||
UriPort = 7,
|
||||
LocationPath = 8,
|
||||
UriPath = 11,
|
||||
@ -47,7 +48,7 @@ public:
|
||||
UriQuery = 15,
|
||||
Accept = 17,
|
||||
LocationQuery = 20,
|
||||
Block2 = 23, // (Block)
|
||||
Block2 = 23, // (Block) https://tools.ietf.org/html/draft-ietf-core-block-18
|
||||
Block1 = 27, // (Block)
|
||||
ProxyUri = 35,
|
||||
ProxyScheme = 39,
|
||||
|
||||
@ -132,6 +132,7 @@
|
||||
#include <QMetaEnum>
|
||||
#include <QTime>
|
||||
|
||||
/*! Constructs a CoapPdu with the given \a parent. */
|
||||
CoapPdu::CoapPdu(QObject *parent) :
|
||||
QObject(parent),
|
||||
m_version(1),
|
||||
@ -145,6 +146,7 @@ CoapPdu::CoapPdu(QObject *parent) :
|
||||
qsrand(QDateTime::currentMSecsSinceEpoch());
|
||||
}
|
||||
|
||||
/*! Constructs a CoapPdu from the given \a data with the given \a parent. */
|
||||
CoapPdu::CoapPdu(const QByteArray &data, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_version(1),
|
||||
@ -159,6 +161,7 @@ CoapPdu::CoapPdu(const QByteArray &data, QObject *parent) :
|
||||
unpack(data);
|
||||
}
|
||||
|
||||
/*! Returns the human readable status code for the given \a statusCode. */
|
||||
QString CoapPdu::getStatusCodeString(const CoapPdu::StatusCode &statusCode)
|
||||
{
|
||||
QString statusCodeString;
|
||||
@ -175,68 +178,89 @@ QString CoapPdu::getStatusCodeString(const CoapPdu::StatusCode &statusCode)
|
||||
return statusCodeString;
|
||||
}
|
||||
|
||||
/*! Returns the version of this \l{CoapPdu}. */
|
||||
quint8 CoapPdu::version() const
|
||||
{
|
||||
return m_version;
|
||||
}
|
||||
|
||||
/*! Sets the version of this \l{CoapPdu} to the given \a version. */
|
||||
void CoapPdu::setVersion(const quint8 &version)
|
||||
{
|
||||
m_version = version;
|
||||
}
|
||||
|
||||
/*! Returns the \l{CoapPdu::MessageType} of this \l{CoapPdu}. */
|
||||
CoapPdu::MessageType CoapPdu::messageType() const
|
||||
{
|
||||
return m_messageType;
|
||||
}
|
||||
|
||||
/*! Sets the \l{CoapPdu::MessageType} of this \l{CoapPdu} to the given \a messageType. */
|
||||
void CoapPdu::setMessageType(const CoapPdu::MessageType &messageType)
|
||||
{
|
||||
m_messageType = messageType;
|
||||
}
|
||||
|
||||
/*! Returns the \l{CoapPdu::StatusCode} of this \l{CoapPdu}. */
|
||||
CoapPdu::StatusCode CoapPdu::statusCode() const
|
||||
{
|
||||
return m_statusCode;
|
||||
}
|
||||
|
||||
/*! Sets the \l{CoapPdu::StatusCode} of this \l{CoapPdu} to the given \a statusCode. */
|
||||
void CoapPdu::setStatusCode(const CoapPdu::StatusCode &statusCode)
|
||||
{
|
||||
m_statusCode = statusCode;
|
||||
}
|
||||
|
||||
/*! Returns the messageId of this \l{CoapPdu}. */
|
||||
quint16 CoapPdu::messageId() const
|
||||
{
|
||||
return m_messageId;
|
||||
}
|
||||
|
||||
/*! Creates a random message id for this \l{CoapPdu} and sets the
|
||||
message id to the created value.
|
||||
|
||||
\sa setMessageId()
|
||||
*/
|
||||
void CoapPdu::createMessageId()
|
||||
{
|
||||
setMessageId((quint16)qrand() % 65536);
|
||||
}
|
||||
|
||||
/*! Sets the messageId of this \l{CoapPdu} to the given \a messageId. */
|
||||
void CoapPdu::setMessageId(const quint16 &messageId)
|
||||
{
|
||||
m_messageId = messageId;
|
||||
}
|
||||
|
||||
/*! Returns the \l{CoapPdu::ContentType} of this \l{CoapPdu}. */
|
||||
CoapPdu::ContentType CoapPdu::contentType() const
|
||||
{
|
||||
return m_contentType;
|
||||
}
|
||||
|
||||
/*! Sets the content type of this \l{CoapPdu} to the given \a contentType.
|
||||
|
||||
\sa CoapPdu::ContentType
|
||||
*/
|
||||
void CoapPdu::setContentType(const CoapPdu::ContentType &contentType)
|
||||
{
|
||||
// TODO: add the contentFormat option
|
||||
|
||||
m_contentType = contentType;
|
||||
}
|
||||
|
||||
/*! Returns the token of this \l{CoapPdu}. */
|
||||
QByteArray CoapPdu::token() const
|
||||
{
|
||||
return m_token;
|
||||
}
|
||||
/*! Creates a random token for this \l{CoapPdu} and sets the
|
||||
token to the created value.
|
||||
|
||||
\sa setToken()
|
||||
*/
|
||||
void CoapPdu::createToken()
|
||||
{
|
||||
m_token.clear();
|
||||
@ -247,26 +271,34 @@ void CoapPdu::createToken()
|
||||
}
|
||||
}
|
||||
|
||||
/*! Sets the token of this \l{CoapPdu} to the given \a token. */
|
||||
void CoapPdu::setToken(const QByteArray &token)
|
||||
{
|
||||
m_token = token;
|
||||
}
|
||||
|
||||
/*! Returns the payload of this \l{CoapPdu}. */
|
||||
QByteArray CoapPdu::payload() const
|
||||
{
|
||||
return m_payload;
|
||||
}
|
||||
|
||||
/*! Sets the payload of this \l{CoapPdu} to the given \a payload. */
|
||||
void CoapPdu::setPayload(const QByteArray &payload)
|
||||
{
|
||||
m_payload = payload;
|
||||
}
|
||||
|
||||
/*! Returns the list of \l{CoapOption}{CoapOptions} of this \l{CoapPdu}. */
|
||||
QList<CoapOption> CoapPdu::options() const
|
||||
{
|
||||
return m_options;
|
||||
}
|
||||
|
||||
/*! Adds the given \a option with the given \a data to this \l{CoapPdu}.
|
||||
|
||||
\sa CoapOption
|
||||
*/
|
||||
void CoapPdu::addOption(const CoapOption::Option &option, const QByteArray &data)
|
||||
{
|
||||
// set pdu data from the option
|
||||
@ -304,11 +336,13 @@ void CoapPdu::addOption(const CoapOption::Option &option, const QByteArray &data
|
||||
m_options.insert(index + 1, CoapOption(option, data));
|
||||
}
|
||||
|
||||
/*! Returns the block of this \l{CoapPdu}. */
|
||||
CoapPduBlock CoapPdu::block() const
|
||||
{
|
||||
return m_block;
|
||||
}
|
||||
|
||||
/*! Returns true if this \l{CoapPdu} has the given \a option. */
|
||||
bool CoapPdu::hasOption(const CoapOption::Option &option) const
|
||||
{
|
||||
foreach (const CoapOption &o, m_options) {
|
||||
@ -318,6 +352,7 @@ bool CoapPdu::hasOption(const CoapOption::Option &option) const
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Resets this \l{CoapPdu} to the default values. */
|
||||
void CoapPdu::clear()
|
||||
{
|
||||
m_version = 1;
|
||||
@ -331,11 +366,13 @@ void CoapPdu::clear()
|
||||
m_error = NoError;
|
||||
}
|
||||
|
||||
/*! Returns true if this \l{CoapPdu} has no errors. */
|
||||
bool CoapPdu::isValid() const
|
||||
{
|
||||
return (m_error == NoError);
|
||||
}
|
||||
|
||||
/*! Returns the packed \l{CoapPdu} as byte array which are ready to send to the server.*/
|
||||
QByteArray CoapPdu::pack() const
|
||||
{
|
||||
QByteArray pduData;
|
||||
@ -499,6 +536,10 @@ void CoapPdu::unpack(const QByteArray &data)
|
||||
}
|
||||
}
|
||||
|
||||
/*! Writes the data of the given \a coapPdu to \a dbg.
|
||||
|
||||
\sa CoapPdu
|
||||
*/
|
||||
QDebug operator<<(QDebug debug, const CoapPdu &coapPdu)
|
||||
{
|
||||
const QMetaObject &metaObject = CoapPdu::staticMetaObject;
|
||||
|
||||
@ -151,7 +151,6 @@ public:
|
||||
|
||||
void clear();
|
||||
bool isValid() const;
|
||||
bool isNull() const;
|
||||
|
||||
QByteArray pack() const;
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
*/
|
||||
|
||||
/*! \fn void CoapReply::error(const Error &code);
|
||||
This signal is emitted when an error occured.
|
||||
This signal is emitted when an error occured. The given \a code represents the \l{CoapReply::Error}.
|
||||
|
||||
\sa error(), errorString()
|
||||
*/
|
||||
@ -91,13 +91,13 @@
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
/*! Returns the request for this CoapReply. */
|
||||
/*! Returns the request for this \l{CoapReply}. */
|
||||
CoapRequest CoapReply::request() const
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
|
||||
/*! Returns the payload of this CoapReply. The payload will be available once the CoapReply is finished.
|
||||
/*! Returns the payload of this \l{CoapReply}. The payload will be available once the \l{CoapReply} is finished.
|
||||
|
||||
\sa isFinished
|
||||
*/
|
||||
@ -106,7 +106,7 @@ QByteArray CoapReply::payload() const
|
||||
return m_payload;
|
||||
}
|
||||
|
||||
/*! Returns true if the reply is finished.
|
||||
/*! Returns true if the \l{CoapReply} is finished.
|
||||
|
||||
\sa finished()
|
||||
*/
|
||||
@ -115,7 +115,7 @@ bool CoapReply::isFinished() const
|
||||
return m_isFinished;
|
||||
}
|
||||
|
||||
/*! Returns true if the reply is running.
|
||||
/*! Returns true if the \l{CoapReply} is running.
|
||||
|
||||
\sa finished()
|
||||
*/
|
||||
@ -124,7 +124,7 @@ bool CoapReply::isRunning() const
|
||||
return m_timer->isActive();
|
||||
}
|
||||
|
||||
/*! Returns error code of the reply.
|
||||
/*! Returns error \l{CoapReply::Error} of the \l{CoapReply}.
|
||||
|
||||
\sa errorString()
|
||||
*/
|
||||
@ -133,7 +133,7 @@ CoapReply::Error CoapReply::error() const
|
||||
return m_error;
|
||||
}
|
||||
|
||||
/*! Returns error string of the reply.
|
||||
/*! Returns error string of the \l{CoapReply}.
|
||||
|
||||
\sa error()
|
||||
*/
|
||||
@ -161,16 +161,19 @@ QString CoapReply::errorString() const
|
||||
return errorString;
|
||||
}
|
||||
|
||||
/*! Returns the \l{CoapPdu::ContentType} of this \l{CoapReply}. */
|
||||
CoapPdu::ContentType CoapReply::contentType() const
|
||||
{
|
||||
return m_contentType;
|
||||
}
|
||||
|
||||
/*! Returns the \l{CoapPdu::MessageType} of this \l{CoapReply}. */
|
||||
CoapPdu::MessageType CoapReply::messageType() const
|
||||
{
|
||||
return m_messageType;
|
||||
}
|
||||
|
||||
/*! Returns the \l{CoapPdu::StatusCode} of this \l{CoapReply}. */
|
||||
CoapPdu::StatusCode CoapReply::statusCode() const
|
||||
{
|
||||
return m_statusCode;
|
||||
@ -219,6 +222,26 @@ void CoapReply::setMessageToken(const QByteArray &messageToken)
|
||||
m_messageToken = messageToken;
|
||||
}
|
||||
|
||||
bool CoapReply::observation() const
|
||||
{
|
||||
return m_observation;
|
||||
}
|
||||
|
||||
void CoapReply::setObservation(const bool &observation)
|
||||
{
|
||||
m_observation = observation;
|
||||
}
|
||||
|
||||
bool CoapReply::observationEnable() const
|
||||
{
|
||||
return m_observationEnable;
|
||||
}
|
||||
|
||||
void CoapReply::setObservationEnable(const bool &observationEnable)
|
||||
{
|
||||
m_observationEnable = observationEnable;
|
||||
}
|
||||
|
||||
void CoapReply::setFinished()
|
||||
{
|
||||
m_isFinished = true;
|
||||
@ -308,6 +331,10 @@ void CoapReply::setRequestData(const QByteArray &requestData)
|
||||
m_requestData = requestData;
|
||||
}
|
||||
|
||||
/*! Writes the data of the given \a reply to \a dbg.
|
||||
|
||||
\sa CoapReply
|
||||
*/
|
||||
QDebug operator<<(QDebug debug, CoapReply *reply)
|
||||
{
|
||||
const QMetaObject &metaObject = CoapPdu::staticMetaObject;
|
||||
|
||||
@ -108,6 +108,12 @@ private:
|
||||
QByteArray messageToken() const;
|
||||
void setMessageToken(const QByteArray &messageToken);
|
||||
|
||||
bool observation() const;
|
||||
void setObservation(const bool &observation);
|
||||
|
||||
bool observationEnable() const;
|
||||
void setObservationEnable(const bool &observationEnable);
|
||||
|
||||
QHostAddress m_hostAddress;
|
||||
int m_port;
|
||||
CoapPdu::StatusCode m_requestMethod;
|
||||
@ -117,6 +123,9 @@ private:
|
||||
int m_messageId;
|
||||
QByteArray m_messageToken;
|
||||
|
||||
bool m_observation;
|
||||
bool m_observationEnable;
|
||||
|
||||
signals:
|
||||
void timeout();
|
||||
void finished();
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
/*! Constructs a \l{CoreLink}. */
|
||||
CoreLink::CoreLink() :
|
||||
m_contentType(CoapPdu::TextPlain),
|
||||
m_maximumSize(-1),
|
||||
@ -42,76 +43,94 @@ CoreLink::CoreLink() :
|
||||
{
|
||||
}
|
||||
|
||||
/*! Returns the path of this \l{CoreLink}. */
|
||||
QString CoreLink::path() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
/*! Sets the \a path of this \l{CoreLink}. */
|
||||
void CoreLink::setPath(const QString &path)
|
||||
{
|
||||
m_path = path;
|
||||
}
|
||||
|
||||
/*! Returns the title of this \l{CoreLink}. */
|
||||
QString CoreLink::title() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
/*! Sets the \a title of this \l{CoreLink}. */
|
||||
void CoreLink::setTitle(const QString &title)
|
||||
{
|
||||
m_title = title;
|
||||
}
|
||||
|
||||
/*! Returns the resource type of this \l{CoreLink}. */
|
||||
QString CoreLink::resourceType() const
|
||||
{
|
||||
return m_resourceType;
|
||||
}
|
||||
|
||||
/*! Sets the resource type of this \l{CoreLink} to the given \a resourceType. */
|
||||
void CoreLink::setResourceType(const QString &resourceType)
|
||||
{
|
||||
m_resourceType = resourceType;
|
||||
}
|
||||
|
||||
/*! Returns the interface description of this \l{CoreLink}. */
|
||||
QString CoreLink::interfaceDescription() const
|
||||
{
|
||||
return m_interfaceDescription;
|
||||
}
|
||||
|
||||
/*! Sets the interface description of this \l{CoreLink} to the given \a interfaceDescription. */
|
||||
void CoreLink::setInterfaceDescription(const QString &interfaceDescription)
|
||||
{
|
||||
m_interfaceDescription = interfaceDescription;
|
||||
}
|
||||
|
||||
/*! Returns the l{CoapPdu::ContentType} of this \l{CoreLink}. */
|
||||
CoapPdu::ContentType CoreLink::contentType() const
|
||||
{
|
||||
return m_contentType;
|
||||
}
|
||||
|
||||
/*! Sets the l{CoapPdu::ContentType} of this \l{CoreLink} to the given \a contentType. */
|
||||
void CoreLink::setContentType(const CoapPdu::ContentType &contentType)
|
||||
{
|
||||
m_contentType = contentType;
|
||||
}
|
||||
|
||||
/*! Returns the maximum payload size of this \l{CoreLink}. */
|
||||
int CoreLink::maximumSize() const
|
||||
{
|
||||
return m_maximumSize;
|
||||
}
|
||||
|
||||
/*! Sets the maximum payload size of this \l{CoreLink} to the given \a maximumSize. */
|
||||
void CoreLink::setMaximumSize(const int &maximumSize)
|
||||
{
|
||||
m_maximumSize = maximumSize;
|
||||
}
|
||||
|
||||
/*! Returns true if this \l{CoreLink} is observable. */
|
||||
bool CoreLink::observable() const
|
||||
{
|
||||
return m_observable;
|
||||
}
|
||||
|
||||
/*! Sets this \l{CoreLink} \a observable. */
|
||||
void CoreLink::setObservable(const bool &observable)
|
||||
{
|
||||
m_observable = observable;
|
||||
}
|
||||
|
||||
/*! Writes the data of the given \a link to \a dbg.
|
||||
|
||||
\sa CoreLink
|
||||
*/
|
||||
QDebug operator<<(QDebug debug, const CoreLink &link)
|
||||
{
|
||||
const QMetaObject &metaObject = CoapPdu::staticMetaObject;
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
/*! Constructs a CoRE link parser. The given \a data should contain a CoRE link list. */
|
||||
/*! Constructs a CoRE link parser with the given \a parent. The given \a data should contain a CoRE link list from the discovery. */
|
||||
CoreLinkParser::CoreLinkParser(const QByteArray &data, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_data(data)
|
||||
|
||||
@ -46,6 +46,7 @@ SOURCES += devicemanager.cpp \
|
||||
coap/coappdublock.cpp \
|
||||
coap/corelinkparser.cpp \
|
||||
coap/corelink.cpp \
|
||||
coap/coapobserveresource.cpp \
|
||||
types/action.cpp \
|
||||
types/actiontype.cpp \
|
||||
types/state.cpp \
|
||||
@ -90,6 +91,7 @@ HEADERS += devicemanager.h \
|
||||
coap/coappdublock.h \
|
||||
coap/corelinkparser.h \
|
||||
coap/corelink.h \
|
||||
coap/coapobserveresource.h \
|
||||
types/action.h \
|
||||
types/actiontype.h \
|
||||
types/state.h \
|
||||
|
||||
Reference in New Issue
Block a user