add observing resources

add documentation
This commit is contained in:
Simon Stürz 2016-02-08 20:51:24 +01:00 committed by Michael Zanetti
parent d5af628a52
commit 9195f06462
13 changed files with 417 additions and 46 deletions

View File

@ -62,6 +62,11 @@
This signal is emitted when a \a reply is finished.
*/
/*! \fn void Coap::notificationReceived(const CoapObserveResource &resource, const int &notificationNumber, 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()

View File

@ -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 &notificationNumber, const QByteArray &payload);
private slots:
void hostLookupFinished(const QHostInfo &hostInfo);
@ -82,4 +92,5 @@ private slots:
void onReplyFinished();
};
#endif // COAP_H

View 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;
}

View 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

View File

@ -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()) {

View File

@ -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,

View File

@ -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;

View File

@ -151,7 +151,6 @@ public:
void clear();
bool isValid() const;
bool isNull() const;
QByteArray pack() const;

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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)

View File

@ -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 \