diff --git a/doc/coap.qdoc b/doc/coap.qdoc new file mode 100644 index 00000000..a3922af1 --- /dev/null +++ b/doc/coap.qdoc @@ -0,0 +1,10 @@ +/*! + \page coap-overview.html + \title CoAP + + In order to interact with a CoAP (Constrained Application Protocol) server guh provides following classes: + + \annotatedlist coap + +*/ + diff --git a/doc/guh.qdoc b/doc/guh.qdoc index 72319b9d..79331d6b 100644 --- a/doc/guh.qdoc +++ b/doc/guh.qdoc @@ -17,8 +17,9 @@ \li \l{Types of libguh} \li \l{Device Plugins}{The Device Plugin API} \li \l{Hardware Resources}{Hardware resources available for plugins} - \li \l{GuhSettings}{Settings of guh} + \li \l{GuhSettings}{Settings API of guh} \li \l{Type Utils}{Global types of guh (Type Utils)} + \li \l{CoAP}{The CoAP API} \endlist \li \l{Plugins}{The guh plugins} \list diff --git a/libguh/coap/coap.cpp b/libguh/coap/coap.cpp index 9d4cef4b..eb95c0ea 100644 --- a/libguh/coap/coap.cpp +++ b/libguh/coap/coap.cpp @@ -18,10 +18,55 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class Coap + \brief The client connection class to a CoAP server. + + \ingroup coap + \inmodule libguh + + The Coap class provides a signal solt based communication with a \l{https://tools.ietf.org/html/rfc7252}{CoAP (Constrained Application Protocol)} + server. The API of this class was inspired by the \l{http://doc.qt.io/qt-5/qnetworkaccessmanager.html}{QNetworkAccessManager} and was + written according to the \l{https://tools.ietf.org/html/rfc7252}{RFC7252}. + This class supports also blockwise transfere according to the \l{https://tools.ietf.org/html/draft-ietf-core-block-18}{IETF V18} specifications. + + \sa CoapReply, CoapRequest + + \section2 Example + \code + MyClass::MyClass(QObject *parent) : + QObject(parent) + { + Coap *coap = new Coap(this); + connect(coap, SIGNAL(replyFinished(CoapReply*)), this, SLOT(onReplyFinished(CoapReply*))); + + CoapRequest request(QUrl("coap://coap.me/hello")); + coap->get(request); + } + \endcode + + \code + void MyClass::onReplyFinished(CoapReply *reply) + { + if (reply->error() != CoapReply::NoError) { + qWarning() << "Reply finished with error" << reply->errorString(); + } + + qDebug() << "Reply finished" << reply; + reply->deleteLater(); + } + \endcode +*/ + +/*! \fn void Coap::replyFinished(CoapReply *reply); + This signal is emitted when a \a reply is finished. +*/ + #include "coap.h" #include "coappdu.h" #include "coapoption.h" +/*! Constructs a coap access manager with the given \a parent and \a port. */ Coap::Coap(QObject *parent, const quint16 &port) : QObject(parent), m_reply(0) @@ -34,6 +79,8 @@ Coap::Coap(QObject *parent, const quint16 &port) : connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead())); } +/*! Performs a ping request to the CoAP server specified in the given \a request. + * Returns a \l{CoapReply} to match the response with the request. */ CoapReply *Coap::ping(const CoapRequest &request) { CoapReply *reply = new CoapReply(request, this); @@ -59,6 +106,8 @@ CoapReply *Coap::ping(const CoapRequest &request) return reply; } +/*! Performs a GET request to the CoAP server specified in the given \a request. + * Returns a \l{CoapReply} to match the response with the request. */ CoapReply *Coap::get(const CoapRequest &request) { CoapReply *reply = new CoapReply(request, this); @@ -84,6 +133,8 @@ CoapReply *Coap::get(const CoapRequest &request) return reply; } +/*! Performs a PUT request to the CoAP server specified in the given \a request and \a data. + * Returns a \l{CoapReply} to match the response with the request. */ CoapReply *Coap::put(const CoapRequest &request, const QByteArray &data) { CoapReply *reply = new CoapReply(request, this); @@ -110,6 +161,8 @@ CoapReply *Coap::put(const CoapRequest &request, const QByteArray &data) return reply; } +/*! Performs a POST request to the CoAP server specified in the given \a request and \a data. + * Returns a \l{CoapReply} to match the response with the request. */ CoapReply *Coap::post(const CoapRequest &request, const QByteArray &data) { CoapReply *reply = new CoapReply(request, this); @@ -136,6 +189,8 @@ CoapReply *Coap::post(const CoapRequest &request, const QByteArray &data) return reply; } +/*! Performs a DELETE request to the CoAP server specified in the given \a request. + * Returns a \l{CoapReply} to match the response with the request. */ CoapReply *Coap::deleteResource(const CoapRequest &request) { CoapReply *reply = new CoapReply(request, this); diff --git a/libguh/coap/coapoption.cpp b/libguh/coap/coapoption.cpp index cca94f4f..73b0e99e 100644 --- a/libguh/coap/coapoption.cpp +++ b/libguh/coap/coapoption.cpp @@ -18,35 +18,92 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class CoapOption + \brief Represents the option of a Coap PDU. + + \ingroup coap + \inmodule libguh + + The CoapOption class provides an easy way to create / parse CoAP options of a CoAP PDU (Protocol Data Unit). An options + can be compared with a HTTP header. + +*/ + +/*! \enum CoapOption::Option + Represents the known CoAP options according to \l{https://tools.ietf.org/html/rfc7252#section-3.1}{RFC7252}. + + \value IfMatch + + \value UriHost + + \value ETag + + \value IfNoneMatch + + \value UriPort + + \value LocationPath + + \value UriPath + + \value ContentFormat + + \value MaxAge + + \value UriQuery + + \value Accept + + \value LocationQuery + + \value Block2 + + \value Block1 + + \value ProxyUri + + \value ProxyScheme + + \value Size1 + +*/ + #include "coapoption.h" #include +/*! Constructs a \l{CoapOption} . */ CoapOption::CoapOption() { } +/*! Constructs a \l{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 . */ void CoapOption::setOption(const CoapOption::Option &option) { m_option = option; } +/*! Returns the option value of this CoapOption. */ CoapOption::Option CoapOption::option() const { return m_option; } +/*! Sets the data of this CoapOption to the given \a data. */ void CoapOption::setData(const QByteArray &data) { m_data = data; } +/*! Returns the data of this CoapOption. */ QByteArray CoapOption::data() const { return m_data; diff --git a/libguh/coap/coappdu.cpp b/libguh/coap/coappdu.cpp index 86e46ef3..a7e846f2 100644 --- a/libguh/coap/coappdu.cpp +++ b/libguh/coap/coappdu.cpp @@ -18,6 +18,114 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class CoapPdu + \brief Represents a CoAP protocol data unit (PDU). + + \ingroup coap + \inmodule libguh + +*/ + +/*! \enum CoapPdu::MessageType + + \value Confirmable + \value NonConfirmable + \value Acknowledgement + \value Reset + +*/ + +/*! \enum CoapPdu::StatusCode + + The CoAP status codes. + + Methods: \l{https://tools.ietf.org/html/rfc7252#section-5.8} + + Status codes: \l{https://tools.ietf.org/html/rfc7252#section-12.1.2} + + \value Empty + 0.00 Empty (i.e. response to ping request) + \value Get + The GET method + \value Post + The POST method + \value Put + The PUT method + \value Delete + The DELETE method + \value Created + 2.01 Created + \value Deleted + 2.02 Deleted + \value Valid + 2.03 Valid + \value Changed + 2.04 Changed + \value Content + 2.05 Content + \value Continue + 2.31 Continue (from \l{https://tools.ietf.org/html/draft-ietf-core-block-18}{Blockwise V18}) + \value BadRequest + 4.00 Bad Request + \value Unauthorized + 4.01 Unauthorized + \value BadOption + 4.02 Bad Option + \value Forbidden + 4.03 Forbidden + \value NotFound + 4.04 Not Found + \value MethodNotAllowed + 4.05 Method Not Allowed + \value NotAcceptable + 4.06 Not Acceptable + \value RequestEntityIncomplete + 4.08 Request Entity Incomplete (from \l{https://tools.ietf.org/html/draft-ietf-core-block-18}{Blockwise V18}) + \value PreconditionFailed + 4.12 Precondition Failed + \value RequestEntityTooLarge + 4.13 Request Entity Too Large (from \l{https://tools.ietf.org/html/draft-ietf-core-block-18}{Blockwise V18}) + \value UnsupportedContentFormat + 4.15 UnsupportedContentFormat + \value InternalServerError + 5.00 Internal Server Error + \value NotImplemented + 5.01 Not Implemented + \value BadGateway + 5.02 Bad Gateway + \value ServiceUnavailabl + 5.03 Service Unavailabl + \value GatewayTimeout + 5.04 Gateway Timeout + \value ProxyingNotSupported + 5.05 Proxying Not Supported + +*/ + +/*! \enum CoapPdu::ContentType + + The CoAP content types. + + \value TextPlain + \value ApplicationLink + \value ApplicationXml + \value ApplicationOctet + \value ApplicationExi + \value ApplicationJson +*/ + +/*! \enum CoapPdu::Error + + \value NoError + \value InvalidTokenError + \value InvalidPduSizeError + \value InvalidOptionDeltaError + \value InvalidOptionLengthError + \value UnknownOptionError +}; + +*/ #include "coappdu.h" #include "coapoption.h" diff --git a/libguh/coap/coapreply.cpp b/libguh/coap/coapreply.cpp index 97847d14..31703cbc 100644 --- a/libguh/coap/coapreply.cpp +++ b/libguh/coap/coapreply.cpp @@ -18,36 +18,125 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class CoapReply + \brief Represents a reply of a CoAP request. + + \ingroup coap + \inmodule libguh + + The CoapReply class contains the data and headers for a request sent with \l{Coap} client. + + \note Please don't forget to delete the reply once it is finished. + + \section2 Example + + \code + Coap *coap = new Coap(this); + connect(coap, SIGNAL(replyFinished(CoapReply*)), this, SLOT(onReplyFinished(CoapReply*))); + + CoapRequest request(QUrl("coap://example.com/")); + + CoapReply *reply = coap->ping(request); + \endcode + + \code + void MyClass::onReplyFinished(CoapReply *reply) + { + if (reply->error() != CoapReply::NoError) { + qWarning() << "Reply finished with error" << reply->errorString(); + } + + qDebug() << "Reply finished" << reply; + reply->deleteLater(); + } + \endcode + + + \sa Coap, CoapRequest + +*/ + +/*! \fn void CoapReply::timeout(); + This signal is emitted when the reply took to long. +*/ + +/*! \fn void CoapReply::finished(); + This signal is emitted when the reply is finished. +*/ + +/*! \fn void CoapReply::error(const Error &code); + This signal is emitted when an error occured. + + \sa error(), errorString() +*/ + +/*! \enum CoapReply::Error + + \value NoError + No error occured. Everything ok. + \value HostNotFoundError + The remote host name was not found (invalid hostname). + \value TimeoutError + The server did not respond after 4 retransmissions. + \value InvalidUrlSchemeError + The given URL does not have a valid scheme. + \value InvalidPduError + The package data unit (PDU) could not be parsed successfully. +*/ + + #include "coapreply.h" #include "coappdu.h" #include +/*! Returns the request for this CoapReply. */ CoapRequest CoapReply::request() const { return m_request; } +/*! Returns the payload of this CoapReply. The payload will be available once the CoapReply is finished. + + \sa isFinished +*/ QByteArray CoapReply::payload() const { return m_payload; } +/*! Returns true if the reply is finished. + + \sa finished() +*/ bool CoapReply::isFinished() const { return m_isFinished; } +/*! Returns true if the reply is running. + + \sa finished() +*/ bool CoapReply::isRunning() const { return m_timer->isActive(); } +/*! Returns error code of the reply. + + \sa errorString() +*/ CoapReply::Error CoapReply::error() const { return m_error; } +/*! Returns error string of the reply. + + \sa error() +*/ QString CoapReply::errorString() const { QString errorString; diff --git a/libguh/coap/coaprequest.cpp b/libguh/coap/coaprequest.cpp index e89434d7..ad05c01a 100644 --- a/libguh/coap/coaprequest.cpp +++ b/libguh/coap/coaprequest.cpp @@ -18,8 +18,18 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class CoapRequest + \brief Represents a request to a CoAP server. + + \ingroup coap + \inmodule libguh + +*/ + #include "coaprequest.h" +/*! Constructs a CoAP request for the given \a url. */ CoapRequest::CoapRequest(const QUrl &url) : m_url(url), m_contentType(CoapPdu::TextPlain), @@ -28,31 +38,39 @@ CoapRequest::CoapRequest(const QUrl &url) : { } +/*! Sets the URL of this CoAP request to the given \a url. */ void CoapRequest::setUrl(const QUrl &url) { m_url = url; } +/*! Returns the URL of this CoAP request. */ QUrl CoapRequest::url() const { return m_url; } +/*! Sets the \l{CoapPdu::ContentType}{ContentType} of this CoAP request to the given \a contentType. + * This method will only be used with the PUT and POST method and should describe the content format + * of the payload. */ void CoapRequest::setContentType(const CoapPdu::ContentType contentType) { m_contentType = contentType; } +/*! Returns the content format of the payload. */ CoapPdu::ContentType CoapRequest::contentType() const { return m_contentType; } +/*! Sets the \l{CoapPdu::MessageType}{MessageType} of this CoAP request to the given \a messageType. */ void CoapRequest::setMessageType(const CoapPdu::MessageType &messageType) { m_messageType = messageType; } +/*! Returns the message type of this CoapRequest. */ CoapPdu::MessageType CoapRequest::messageType() const { return m_messageType; diff --git a/libguh/coap/corelink.cpp b/libguh/coap/corelink.cpp index a4225963..f10e473a 100644 --- a/libguh/coap/corelink.cpp +++ b/libguh/coap/corelink.cpp @@ -18,6 +18,19 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class CoreLink + \brief Represents a link of a CoRE link format. + + \ingroup coap + \inmodule libguh + + This class represents a Constrained RESTful Environments (CoRE) Link format according to the + \l{http://tools.ietf.org/html/rfc6690}{RFC6690} specification. + +*/ + + #include "corelink.h" #include diff --git a/libguh/coap/corelinkparser.cpp b/libguh/coap/corelinkparser.cpp index d7d4d292..534bb862 100644 --- a/libguh/coap/corelinkparser.cpp +++ b/libguh/coap/corelinkparser.cpp @@ -18,10 +18,34 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class CoreLinkParser + \brief Provides an easy way to parse a CoRE link list. + + \ingroup coap + \inmodule libguh + + \section2 Example + + \code + if (reply->contentType == CoapPdu::ApplicationLink) { + CoreLinkParser parser(reply->payload()); + + foreach (const CoreLink &link, parser.links()) { + qDebug() << link; + } + } + \endcode + + \sa CoreLink + +*/ + #include "corelinkparser.h" #include +/*! Constructs a CoRE link parser. The given \a data should contain a CoRE link list. */ CoreLinkParser::CoreLinkParser(const QByteArray &data, QObject *parent) : QObject(parent), m_data(data) @@ -55,6 +79,7 @@ CoreLinkParser::CoreLinkParser(const QByteArray &data, QObject *parent) : } } +/*! Returns the parsed list of \l{CoreLink}{CoreLinks}.*/ QList CoreLinkParser::links() const { return m_links;