Merge PR #533: Add support for CoIoT

This commit is contained in:
jenkins 2022-06-30 15:04:37 +02:00
commit a0186a0fb6
8 changed files with 124 additions and 168 deletions

View File

@ -93,7 +93,7 @@ Coap::Coap(QObject *parent, const quint16 &port) :
{ {
m_socket = new QUdpSocket(this); m_socket = new QUdpSocket(this);
if (!m_socket->bind(QHostAddress::Any, port, QAbstractSocket::ShareAddress)) if (!m_socket->bind(QHostAddress::AnyIPv4, port, QAbstractSocket::ShareAddress))
qCWarning(dcCoap) << "Could not bind to port" << port << m_socket->errorString(); qCWarning(dcCoap) << "Could not bind to port" << port << m_socket->errorString();
connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead())); connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
@ -103,117 +103,44 @@ Coap::Coap(QObject *parent, const quint16 &port) :
* Returns a \l{CoapReply} to match the response with the request. */ * Returns a \l{CoapReply} to match the response with the request. */
CoapReply *Coap::ping(const CoapRequest &request) CoapReply *Coap::ping(const CoapRequest &request)
{ {
CoapReply *reply = new CoapReply(request, this); return customRequest(CoapPdu::Empty, request);
reply->setRequestMethod(CoapPdu::Empty);
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;
} }
/*! Performs a GET request to the CoAP server specified in the given \a request. /*! 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. */ * Returns a \l{CoapReply} to match the response with the request. */
CoapReply *Coap::get(const CoapRequest &request) CoapReply *Coap::get(const CoapRequest &request)
{ {
CoapReply *reply = new CoapReply(request, this); return customRequest(CoapPdu::Get, request);
reply->setRequestMethod(CoapPdu::Get);
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;
} }
/*! Performs a PUT request to the CoAP server specified in the given \a request and \a data. /*! 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. */ * Returns a \l{CoapReply} to match the response with the request. */
CoapReply *Coap::put(const CoapRequest &request, const QByteArray &data) CoapReply *Coap::put(const CoapRequest &request, const QByteArray &data)
{ {
CoapReply *reply = new CoapReply(request, this); return customRequest(CoapPdu::Put, request, data);
reply->setRequestMethod(CoapPdu::Put);
reply->setRequestPayload(data);
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;
} }
/*! Performs a POST request to the CoAP server specified in the given \a request and \a data. /*! 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. */ * Returns a \l{CoapReply} to match the response with the request. */
CoapReply *Coap::post(const CoapRequest &request, const QByteArray &data) CoapReply *Coap::post(const CoapRequest &request, const QByteArray &data)
{ {
CoapReply *reply = new CoapReply(request, this); return customRequest(CoapPdu::Post, request, data);
reply->setRequestMethod(CoapPdu::Post);
reply->setRequestPayload(data);
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;
} }
/*! Performs a DELETE request to the CoAP server specified in the given \a request. /*! 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. */ * Returns a \l{CoapReply} to match the response with the request. */
CoapReply *Coap::deleteResource(const CoapRequest &request) CoapReply *Coap::deleteResource(const CoapRequest &request)
{
return customRequest(CoapPdu::Delete, request);
}
CoapReply *Coap::customRequest(CoapPdu::ReqRspCode requestCode, const CoapRequest &request, const QByteArray &data)
{ {
CoapReply *reply = new CoapReply(request, this); CoapReply *reply = new CoapReply(request, this);
reply->setRequestMethod(CoapPdu::Delete); reply->setRequestMethod(requestCode);
if (!data.isEmpty()) {
reply->setRequestPayload(data);
}
connect(reply, &CoapReply::timeout, this, &Coap::onReplyTimeout); connect(reply, &CoapReply::timeout, this, &Coap::onReplyTimeout);
connect(reply, &CoapReply::finished, this, &Coap::onReplyFinished); connect(reply, &CoapReply::finished, this, &Coap::onReplyFinished);
@ -296,6 +223,23 @@ CoapReply *Coap::disableNotifications(const CoapRequest &request)
return reply; return reply;
} }
bool Coap::joinMulticastGroup(const QHostAddress &address)
{
bool ok = m_socket->joinMulticastGroup(address);
if (ok) {
qCDebug(dcCoap()) << "Joined CoAP multucast group on:" << address;
} else {
qCWarning(dcCoap()) << "Error joining CoAP multicast group on:" << address;
}
return ok;
}
bool Coap::leaveMulticastGroup(const QHostAddress &address)
{
return m_socket->leaveMulticastGroup(address);
}
void Coap::lookupHost() void Coap::lookupHost()
{ {
int lookupId = QHostInfo::lookupHost(m_reply->request().url().host(), this, SLOT(hostLookupFinished(QHostInfo))); int lookupId = QHostInfo::lookupHost(m_reply->request().url().host(), this, SLOT(hostLookupFinished(QHostInfo)));
@ -306,7 +250,7 @@ void Coap::sendRequest(CoapReply *reply, const bool &lookedUp)
{ {
CoapPdu pdu; CoapPdu pdu;
pdu.setMessageType(reply->request().messageType()); pdu.setMessageType(reply->request().messageType());
pdu.setStatusCode(reply->requestMethod()); pdu.setReqRspCode(reply->requestMethod());
pdu.createMessageId(); pdu.createMessageId();
pdu.createToken(); pdu.createToken();
@ -431,18 +375,15 @@ void Coap::processResponse(const CoapPdu &pdu, const QHostAddress &address, cons
return; return;
} }
qCDebug(dcCoap) << "Got message without request or registered observe resource." << endl << "<---" << pdu; // If this is neither a response to a request of a notification from an observed resource, it's a multicast message
CoapPdu responsePdu; qCDebug(dcCoap) << "<---" << QString("%1:%2").arg(address.toString()).arg(QString::number(port)) << pdu;
responsePdu.setMessageType(CoapPdu::Reset); emit multicastMessageReceived(address, pdu);
responsePdu.setMessageId(pdu.messageId());
responsePdu.setToken(pdu.token());
sendCoapPdu(address, port, responsePdu);
} }
void Coap::processIdBasedResponse(CoapReply *reply, const CoapPdu &pdu) void Coap::processIdBasedResponse(CoapReply *reply, const CoapPdu &pdu)
{ {
// check if this is an empty ACK response (which indicates a separated response) // check if this is an empty ACK response (which indicates a separated response)
if (pdu.statusCode() == CoapPdu::Empty && pdu.messageType() == CoapPdu::Acknowledgement) { if (pdu.reqRspCode() == CoapPdu::Empty && pdu.messageType() == CoapPdu::Acknowledgement) {
reply->m_timer->stop(); reply->m_timer->stop();
qCDebug(dcCoap) << "Got empty ACK. Data will be sent separated."; qCDebug(dcCoap) << "Got empty ACK. Data will be sent separated.";
return; return;
@ -461,7 +402,7 @@ void Coap::processIdBasedResponse(CoapReply *reply, const CoapPdu &pdu)
} }
// Piggybacked response // Piggybacked response
reply->setStatusCode(pdu.statusCode()); reply->setReqRspCode(pdu.reqRspCode());
reply->setContentType(pdu.contentType()); reply->setContentType(pdu.contentType());
reply->appendPayloadData(pdu.payload()); reply->appendPayloadData(pdu.payload());
reply->setFinished(); reply->setFinished();
@ -472,11 +413,11 @@ void Coap::processTokenBasedResponse(CoapReply *reply, const CoapPdu &pdu)
// Separate Response // Separate Response
CoapPdu responsePdu; CoapPdu responsePdu;
responsePdu.setMessageType(CoapPdu::Acknowledgement); responsePdu.setMessageType(CoapPdu::Acknowledgement);
responsePdu.setStatusCode(CoapPdu::Empty); responsePdu.setReqRspCode(CoapPdu::Empty);
responsePdu.setMessageId(pdu.messageId()); responsePdu.setMessageId(pdu.messageId());
sendCoapPdu(reply->hostAddress(), reply->port(), responsePdu); sendCoapPdu(reply->hostAddress(), reply->port(), responsePdu);
reply->setStatusCode(pdu.statusCode()); reply->setReqRspCode(pdu.reqRspCode());
reply->setContentType(pdu.contentType()); reply->setContentType(pdu.contentType());
reply->appendPayloadData(pdu.payload()); reply->appendPayloadData(pdu.payload());
reply->setFinished(); reply->setFinished();
@ -497,7 +438,7 @@ void Coap::processNotification(const CoapPdu &pdu, const QHostAddress &address,
// respond with ACK // respond with ACK
CoapPdu responsePdu; CoapPdu responsePdu;
responsePdu.setMessageType(CoapPdu::Acknowledgement); responsePdu.setMessageType(CoapPdu::Acknowledgement);
responsePdu.setStatusCode(CoapPdu::Empty); responsePdu.setReqRspCode(CoapPdu::Empty);
responsePdu.setMessageId(pdu.messageId()); responsePdu.setMessageId(pdu.messageId());
responsePdu.setToken(pdu.token()); responsePdu.setToken(pdu.token());
@ -530,7 +471,7 @@ void Coap::processNotification(const CoapPdu &pdu, const QHostAddress &address,
CoapPdu pdu; CoapPdu pdu;
pdu.setMessageType(m_observerReply->request().messageType()); pdu.setMessageType(m_observerReply->request().messageType());
pdu.setStatusCode(m_observerReply->requestMethod()); pdu.setReqRspCode(m_observerReply->requestMethod());
pdu.createMessageId(); pdu.createMessageId();
pdu.createToken(); pdu.createToken();
@ -568,7 +509,7 @@ void Coap::processNotification(const CoapPdu &pdu, const QHostAddress &address,
// respond with ACK // respond with ACK
CoapPdu responsePdu; CoapPdu responsePdu;
responsePdu.setMessageType(CoapPdu::Acknowledgement); responsePdu.setMessageType(CoapPdu::Acknowledgement);
responsePdu.setStatusCode(CoapPdu::Empty); responsePdu.setReqRspCode(CoapPdu::Empty);
responsePdu.setMessageId(pdu.messageId()); responsePdu.setMessageId(pdu.messageId());
responsePdu.setToken(pdu.token()); responsePdu.setToken(pdu.token());
@ -596,7 +537,7 @@ void Coap::processBlock1Response(CoapReply *reply, const CoapPdu &pdu)
// check if this was the last block // check if this was the last block
if (newBlockData.isEmpty()) { if (newBlockData.isEmpty()) {
reply->setStatusCode(pdu.statusCode()); reply->setReqRspCode(pdu.reqRspCode());
reply->setContentType(pdu.contentType()); reply->setContentType(pdu.contentType());
reply->setFinished(); reply->setFinished();
return; return;
@ -609,7 +550,7 @@ void Coap::processBlock1Response(CoapReply *reply, const CoapPdu &pdu)
CoapPdu nextBlockRequest; CoapPdu nextBlockRequest;
nextBlockRequest.setContentType(reply->request().contentType()); nextBlockRequest.setContentType(reply->request().contentType());
nextBlockRequest.setMessageType(reply->request().messageType()); nextBlockRequest.setMessageType(reply->request().messageType());
nextBlockRequest.setStatusCode(reply->requestMethod()); nextBlockRequest.setReqRspCode(reply->requestMethod());
nextBlockRequest.setMessageId(pdu.messageId() + 1); nextBlockRequest.setMessageId(pdu.messageId() + 1);
nextBlockRequest.setToken(pdu.token()); nextBlockRequest.setToken(pdu.token());
@ -655,7 +596,7 @@ void Coap::processBlock2Response(CoapReply *reply, const CoapPdu &pdu)
// check if this was the last block // check if this was the last block
if (!pdu.block().moreFlag()) { if (!pdu.block().moreFlag()) {
reply->setStatusCode(pdu.statusCode()); reply->setReqRspCode(pdu.reqRspCode());
reply->setContentType(pdu.contentType()); reply->setContentType(pdu.contentType());
reply->setFinished(); reply->setFinished();
return; return;
@ -664,7 +605,7 @@ void Coap::processBlock2Response(CoapReply *reply, const CoapPdu &pdu)
CoapPdu nextBlockRequest; CoapPdu nextBlockRequest;
nextBlockRequest.setContentType(reply->request().contentType()); nextBlockRequest.setContentType(reply->request().contentType());
nextBlockRequest.setMessageType(reply->request().messageType()); nextBlockRequest.setMessageType(reply->request().messageType());
nextBlockRequest.setStatusCode(reply->requestMethod()); nextBlockRequest.setReqRspCode(reply->requestMethod());
nextBlockRequest.setMessageId(pdu.messageId() + 1); nextBlockRequest.setMessageId(pdu.messageId() + 1);
nextBlockRequest.setToken(pdu.token()); nextBlockRequest.setToken(pdu.token());
@ -716,7 +657,7 @@ void Coap::processBlock2Notification(CoapReply *reply, const CoapPdu &pdu)
// respond with ACK // respond with ACK
CoapPdu responsePdu; CoapPdu responsePdu;
responsePdu.setMessageType(CoapPdu::Acknowledgement); responsePdu.setMessageType(CoapPdu::Acknowledgement);
responsePdu.setStatusCode(CoapPdu::Empty); responsePdu.setReqRspCode(CoapPdu::Empty);
responsePdu.setMessageId(pdu.messageId()); responsePdu.setMessageId(pdu.messageId());
responsePdu.setToken(pdu.token()); responsePdu.setToken(pdu.token());
@ -737,7 +678,7 @@ void Coap::processBlock2Notification(CoapReply *reply, const CoapPdu &pdu)
CoapPdu nextBlockRequest; CoapPdu nextBlockRequest;
nextBlockRequest.setContentType(reply->request().contentType()); nextBlockRequest.setContentType(reply->request().contentType());
nextBlockRequest.setMessageType(reply->request().messageType()); nextBlockRequest.setMessageType(reply->request().messageType());
nextBlockRequest.setStatusCode(reply->requestMethod()); nextBlockRequest.setReqRspCode(reply->requestMethod());
nextBlockRequest.setMessageId(pdu.messageId() + 1); nextBlockRequest.setMessageId(pdu.messageId() + 1);
nextBlockRequest.setToken(pdu.token()); nextBlockRequest.setToken(pdu.token());
@ -806,7 +747,7 @@ void Coap::onReadyRead()
while (m_socket->hasPendingDatagrams()) { while (m_socket->hasPendingDatagrams()) {
QByteArray datagram(m_socket->pendingDatagramSize(), 0); QByteArray datagram(m_socket->pendingDatagramSize(), 0);
m_socket->readDatagram(datagram.data(), datagram.size(), &hostAddress, &port); m_socket->readDatagram(datagram.data(), datagram.size(), &hostAddress, &port);
qCDebug(dcCoap()) << "Datagram received from:" << hostAddress << ":" << datagram; qCDebug(dcCoap()) << "Datagram received from:" << hostAddress << ":" << datagram.toHex();
CoapPdu pdu(datagram); CoapPdu pdu(datagram);
processResponse(pdu, hostAddress, port); processResponse(pdu, hostAddress, port);
} }

View File

@ -65,11 +65,14 @@ public:
CoapReply *put(const CoapRequest &request, const QByteArray &data = QByteArray()); CoapReply *put(const CoapRequest &request, const QByteArray &data = QByteArray());
CoapReply *post(const CoapRequest &request, const QByteArray &data = QByteArray()); CoapReply *post(const CoapRequest &request, const QByteArray &data = QByteArray());
CoapReply *deleteResource(const CoapRequest &request); CoapReply *deleteResource(const CoapRequest &request);
CoapReply *customRequest(CoapPdu::ReqRspCode requestCode, const CoapRequest &request, const QByteArray &data = QByteArray());
// Notifications for observable resources // Notifications for observable resources
CoapReply *enableResourceNotifications(const CoapRequest &request); CoapReply *enableResourceNotifications(const CoapRequest &request);
CoapReply *disableNotifications(const CoapRequest &request); CoapReply *disableNotifications(const CoapRequest &request);
bool joinMulticastGroup(const QHostAddress &address = QHostAddress("224.0.1.187"));
bool leaveMulticastGroup(const QHostAddress &address = QHostAddress("224.0.1.187"));
private: private:
QUdpSocket *m_socket; QUdpSocket *m_socket;
@ -105,6 +108,7 @@ private:
signals: signals:
void replyFinished(CoapReply *reply); void replyFinished(CoapReply *reply);
void notificationReceived(const CoapObserveResource &resource, const int &notificationNumber, const QByteArray &payload); void notificationReceived(const CoapObserveResource &resource, const int &notificationNumber, const QByteArray &payload);
void multicastMessageReceived(const QHostAddress &source, const CoapPdu &pdu);
private slots: private slots:
void hostLookupFinished(const QHostInfo &hostInfo); void hostLookupFinished(const QHostInfo &hostInfo);

View File

@ -173,7 +173,7 @@ CoapPdu::CoapPdu(QObject *parent) :
QObject(parent), QObject(parent),
m_version(1), m_version(1),
m_messageType(Confirmable), m_messageType(Confirmable),
m_statusCode(Empty), m_reqRspCode(Empty),
m_messageId(0), m_messageId(0),
m_contentType(TextPlain), m_contentType(TextPlain),
m_payload(QByteArray()), m_payload(QByteArray()),
@ -187,7 +187,7 @@ CoapPdu::CoapPdu(const QByteArray &data, QObject *parent) :
QObject(parent), QObject(parent),
m_version(1), m_version(1),
m_messageType(Confirmable), m_messageType(Confirmable),
m_statusCode(Empty), m_reqRspCode(Empty),
m_messageId(0), m_messageId(0),
m_contentType(TextPlain), m_contentType(TextPlain),
m_payload(QByteArray()), m_payload(QByteArray()),
@ -197,20 +197,20 @@ CoapPdu::CoapPdu(const QByteArray &data, QObject *parent) :
unpack(data); unpack(data);
} }
/*! Returns the human readable status code for the given \a statusCode. */ /*! Returns the human readable string for the given \a reqRspCode. */
QString CoapPdu::getStatusCodeString(const CoapPdu::StatusCode &statusCode) QString CoapPdu::getReqRspCodeString(CoapPdu::ReqRspCode reqRspCode)
{ {
QString statusCodeString; QString statusCodeString;
const QMetaObject &metaObject = CoapPdu::staticMetaObject; const QMetaObject &metaObject = CoapPdu::staticMetaObject;
QMetaEnum statusCodeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("StatusCode")); QMetaEnum statusCodeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("ReqRspCode"));
int classNumber = (statusCode & 0xE0) >> 5; int classNumber = (reqRspCode & 0xE0) >> 5;
int detailNumber = statusCode & 0x1F; int detailNumber = reqRspCode & 0x1F;
statusCodeString.append(QString::number(classNumber) + "."); statusCodeString.append(QString::number(classNumber) + ".");
if (detailNumber < 10) if (detailNumber < 10)
statusCodeString.append("0"); statusCodeString.append("0");
statusCodeString.append(QString::number(detailNumber) + " "); statusCodeString.append(QString::number(detailNumber) + " ");
statusCodeString.append(statusCodeEnum.valueToKey(statusCode)); statusCodeString.append(statusCodeEnum.valueToKey(reqRspCode));
return statusCodeString; return statusCodeString;
} }
@ -221,7 +221,7 @@ quint8 CoapPdu::version() const
} }
/*! Sets the version of this \l{CoapPdu} to the given \a version. */ /*! Sets the version of this \l{CoapPdu} to the given \a version. */
void CoapPdu::setVersion(const quint8 &version) void CoapPdu::setVersion(quint8 version)
{ {
m_version = version; m_version = version;
} }
@ -233,21 +233,21 @@ CoapPdu::MessageType CoapPdu::messageType() const
} }
/*! Sets the \l{CoapPdu::MessageType} of this \l{CoapPdu} to the given \a messageType. */ /*! Sets the \l{CoapPdu::MessageType} of this \l{CoapPdu} to the given \a messageType. */
void CoapPdu::setMessageType(const CoapPdu::MessageType &messageType) void CoapPdu::setMessageType(CoapPdu::MessageType messageType)
{ {
m_messageType = messageType; m_messageType = messageType;
} }
/*! Returns the \l{CoapPdu::StatusCode} of this \l{CoapPdu}. */ /*! Returns the \l{CoapPdu::ReqRspCode} of this \l{CoapPdu}. */
CoapPdu::StatusCode CoapPdu::statusCode() const CoapPdu::ReqRspCode CoapPdu::reqRspCode() const
{ {
return m_statusCode; return m_reqRspCode;
} }
/*! Sets the \l{CoapPdu::StatusCode} of this \l{CoapPdu} to the given \a statusCode. */ /*! Sets the \l{CoapPdu::ReqRspCode} of this \l{CoapPdu} to the given \a reqRspCode. */
void CoapPdu::setStatusCode(const CoapPdu::StatusCode &statusCode) void CoapPdu::setReqRspCode(CoapPdu::ReqRspCode reqRspCode)
{ {
m_statusCode = statusCode; m_reqRspCode = reqRspCode;
} }
/*! Returns the messageId of this \l{CoapPdu}. */ /*! Returns the messageId of this \l{CoapPdu}. */
@ -267,7 +267,7 @@ void CoapPdu::createMessageId()
} }
/*! Sets the messageId of this \l{CoapPdu} to the given \a messageId. */ /*! Sets the messageId of this \l{CoapPdu} to the given \a messageId. */
void CoapPdu::setMessageId(const quint16 &messageId) void CoapPdu::setMessageId(quint16 messageId)
{ {
m_messageId = messageId; m_messageId = messageId;
} }
@ -282,7 +282,7 @@ CoapPdu::ContentType CoapPdu::contentType() const
\sa CoapPdu::ContentType \sa CoapPdu::ContentType
*/ */
void CoapPdu::setContentType(const CoapPdu::ContentType &contentType) void CoapPdu::setContentType(ContentType contentType)
{ {
m_contentType = contentType; m_contentType = contentType;
} }
@ -336,7 +336,7 @@ QList<CoapOption> CoapPdu::options() const
\sa CoapOption \sa CoapOption
*/ */
void CoapPdu::addOption(const CoapOption::Option &option, const QByteArray &data) void CoapPdu::addOption(CoapOption::Option option, const QByteArray &data)
{ {
// set pdu data from the option // set pdu data from the option
switch (option) { switch (option) {
@ -384,7 +384,7 @@ CoapPduBlock CoapPdu::block() const
} }
/*! Returns true if this \l{CoapPdu} has the given \a option. */ /*! Returns true if this \l{CoapPdu} has the given \a option. */
bool CoapPdu::hasOption(const CoapOption::Option &option) const bool CoapPdu::hasOption(CoapOption::Option option) const
{ {
foreach (const CoapOption &o, m_options) { foreach (const CoapOption &o, m_options) {
if (o.option() == option) if (o.option() == option)
@ -393,12 +393,22 @@ bool CoapPdu::hasOption(const CoapOption::Option &option) const
return false; return false;
} }
CoapOption CoapPdu::option(CoapOption::Option option) const
{
foreach (const CoapOption &o, m_options) {
if (o.option() == option) {
return o;
}
}
return CoapOption();
}
/*! Resets this \l{CoapPdu} to the default values. */ /*! Resets this \l{CoapPdu} to the default values. */
void CoapPdu::clear() void CoapPdu::clear()
{ {
m_version = 1; m_version = 1;
m_messageType = Confirmable; m_messageType = Confirmable;
m_statusCode = Empty; m_reqRspCode = Empty;
m_messageId = 0; m_messageId = 0;
m_contentType = TextPlain; m_contentType = TextPlain;
m_token.clear(); m_token.clear();
@ -426,7 +436,7 @@ QByteArray CoapPdu::pack() const
rawHeader[0] = m_version << 6; rawHeader[0] = m_version << 6;
rawHeader[0] |= (quint8)m_messageType << 4; rawHeader[0] |= (quint8)m_messageType << 4;
rawHeader[0] |= (quint8)m_token.size(); rawHeader[0] |= (quint8)m_token.size();
rawHeader[1] = (quint8)m_statusCode; rawHeader[1] = (quint8)m_reqRspCode;
rawHeader[2] = (quint8)(m_messageId >> 8); rawHeader[2] = (quint8)(m_messageId >> 8);
rawHeader[3] = (quint8)(m_messageId & 0xff); rawHeader[3] = (quint8)(m_messageId & 0xff);
pduData = QByteArray::fromRawData((char *)rawHeader, 4); pduData = QByteArray::fromRawData((char *)rawHeader, 4);
@ -532,8 +542,8 @@ void CoapPdu::unpack(const QByteArray &data)
quint8 reqRspCode; quint8 reqRspCode;
stream >> reqRspCode; stream >> reqRspCode;
setStatusCode(static_cast<StatusCode>(reqRspCode)); setReqRspCode(static_cast<ReqRspCode>(reqRspCode));
// qCDebug(dcCoap()) << "Req/Rsp code:" << statusCode(); // qCDebug(dcCoap()) << "Req/Rsp code:" << reqRspCode();
quint16 messageId; quint16 messageId;
stream >> messageId; stream >> messageId;
@ -611,7 +621,7 @@ QDebug operator<<(QDebug debug, const CoapPdu &coapPdu)
const QMetaObject &metaObject = CoapPdu::staticMetaObject; const QMetaObject &metaObject = CoapPdu::staticMetaObject;
QMetaEnum messageTypeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("MessageType")); QMetaEnum messageTypeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("MessageType"));
debug.nospace() << "CoapPdu(" << messageTypeEnum.valueToKey(coapPdu.messageType()) << ")" << endl; debug.nospace() << "CoapPdu(" << messageTypeEnum.valueToKey(coapPdu.messageType()) << ")" << endl;
debug.nospace() << " Code: " << CoapPdu::getStatusCodeString(coapPdu.statusCode()) << endl; debug.nospace() << " Code: " << CoapPdu::getReqRspCodeString(coapPdu.reqRspCode()) << endl;
debug.nospace() << " Ver: " << coapPdu.version() << endl; debug.nospace() << " Ver: " << coapPdu.version() << endl;
debug.nospace() << " Token: " << coapPdu.token().length() << " " << "0x"+ coapPdu.token().toHex() << endl; debug.nospace() << " Token: " << coapPdu.token().length() << " " << "0x"+ coapPdu.token().toHex() << endl;
debug.nospace() << " Message ID: " << coapPdu.messageId() << endl; debug.nospace() << " Message ID: " << coapPdu.messageId() << endl;

View File

@ -72,7 +72,7 @@ public:
// Methods: https://tools.ietf.org/html/rfc7252#section-5.8 // Methods: https://tools.ietf.org/html/rfc7252#section-5.8
// Respond codes: https://tools.ietf.org/html/rfc7252#section-12.1.2 // Respond codes: https://tools.ietf.org/html/rfc7252#section-12.1.2
enum StatusCode { enum ReqRspCode {
Empty = 0x00, // Empty message (ping) Empty = 0x00, // Empty message (ping)
Get = 0x01, // Method GET Get = 0x01, // Method GET
Post = 0x02, // Method POST Post = 0x02, // Method POST
@ -102,7 +102,7 @@ public:
GatewayTimeout = 0xa4, // 5.04 GatewayTimeout = 0xa4, // 5.04
ProxyingNotSupported = 0xa5 // 5.05 ProxyingNotSupported = 0xa5 // 5.05
}; };
Q_ENUM(StatusCode) Q_ENUM(ReqRspCode)
// https://tools.ietf.org/html/rfc7252#section-12.3 // https://tools.ietf.org/html/rfc7252#section-12.3
enum ContentType { enum ContentType {
@ -128,24 +128,24 @@ public:
CoapPdu(QObject *parent = 0); CoapPdu(QObject *parent = 0);
CoapPdu(const QByteArray &data, QObject *parent = 0); CoapPdu(const QByteArray &data, QObject *parent = 0);
static QString getStatusCodeString(const StatusCode &statusCode); static QString getReqRspCodeString(CoapPdu::ReqRspCode reqRspCode);
// header fields // header fields
quint8 version() const; quint8 version() const;
void setVersion(const quint8 &version); void setVersion(quint8 version);
MessageType messageType() const; MessageType messageType() const;
void setMessageType(const MessageType &messageType); void setMessageType(MessageType messageType);
StatusCode statusCode() const; ReqRspCode reqRspCode() const;
void setStatusCode(const StatusCode &statusCode); void setReqRspCode(ReqRspCode reqRspCode);
quint16 messageId() const; quint16 messageId() const;
void createMessageId(); void createMessageId();
void setMessageId(const quint16 &messageId); void setMessageId(quint16 messageId);
ContentType contentType() const; ContentType contentType() const;
void setContentType(const ContentType &contentType); void setContentType(ContentType contentType);
QByteArray token() const; QByteArray token() const;
void createToken(); void createToken();
@ -156,11 +156,12 @@ public:
void setPayload(const QByteArray &payload); void setPayload(const QByteArray &payload);
QList<CoapOption> options() const; QList<CoapOption> options() const;
void addOption(const CoapOption::Option &option, const QByteArray &data); void addOption(CoapOption::Option option, const QByteArray &data);
CoapPduBlock block() const; CoapPduBlock block() const;
bool hasOption(const CoapOption::Option &option) const; bool hasOption(CoapOption::Option option) const;
CoapOption option(CoapOption::Option option) const;
void clear(); void clear();
bool isValid() const; bool isValid() const;
@ -170,7 +171,7 @@ public:
private: private:
quint8 m_version; quint8 m_version;
MessageType m_messageType; MessageType m_messageType;
StatusCode m_statusCode; ReqRspCode m_reqRspCode;
quint16 m_messageId; quint16 m_messageId;
ContentType m_contentType; ContentType m_contentType;
QByteArray m_token; QByteArray m_token;

View File

@ -184,10 +184,10 @@ CoapPdu::MessageType CoapReply::messageType() const
return m_messageType; return m_messageType;
} }
/*! Returns the \l{CoapPdu::StatusCode} of this \l{CoapReply}. */ /*! Returns the \l{CoapPdu::ReqRspCode} of this \l{CoapReply}. */
CoapPdu::StatusCode CoapReply::statusCode() const CoapPdu::ReqRspCode CoapReply::reqRspCode() const
{ {
return m_statusCode; return m_reqRspCode;
} }
CoapReply::CoapReply(const CoapRequest &request, QObject *parent) : CoapReply::CoapReply(const CoapRequest &request, QObject *parent) :
@ -198,7 +198,7 @@ CoapReply::CoapReply(const CoapRequest &request, QObject *parent) :
m_retransmissions(1), m_retransmissions(1),
m_contentType(CoapPdu::TextPlain), m_contentType(CoapPdu::TextPlain),
m_messageType(CoapPdu::Acknowledgement), m_messageType(CoapPdu::Acknowledgement),
m_statusCode(CoapPdu::Empty), m_reqRspCode(CoapPdu::Empty),
m_lockedUp(false) m_lockedUp(false)
{ {
m_timer = new QTimer(this); m_timer = new QTimer(this);
@ -275,19 +275,19 @@ void CoapReply::resend()
} }
} }
void CoapReply::setContentType(const CoapPdu::ContentType contentType) void CoapReply::setContentType(CoapPdu::ContentType contentType)
{ {
m_contentType = contentType; m_contentType = contentType;
} }
void CoapReply::setMessageType(const CoapPdu::MessageType &messageType) void CoapReply::setMessageType(CoapPdu::MessageType messageType)
{ {
m_messageType = messageType; m_messageType = messageType;
} }
void CoapReply::setStatusCode(const CoapPdu::StatusCode &statusCode) void CoapReply::setReqRspCode(CoapPdu::ReqRspCode reqRspCode)
{ {
m_statusCode = statusCode; m_reqRspCode = reqRspCode;
} }
void CoapReply::setHostAddress(const QHostAddress &address) void CoapReply::setHostAddress(const QHostAddress &address)
@ -300,7 +300,7 @@ QHostAddress CoapReply::hostAddress() const
return m_hostAddress; return m_hostAddress;
} }
void CoapReply::setPort(const int &port) void CoapReply::setPort(int port)
{ {
m_port = port; m_port = port;
} }
@ -320,12 +320,12 @@ QByteArray CoapReply::requestPayload() const
return m_requestPayload; return m_requestPayload;
} }
void CoapReply::setRequestMethod(const CoapPdu::StatusCode &method) void CoapReply::setRequestMethod(CoapPdu::ReqRspCode method)
{ {
m_requestMethod = method; m_requestMethod = method;
} }
CoapPdu::StatusCode CoapReply::requestMethod() const CoapPdu::ReqRspCode CoapReply::requestMethod() const
{ {
return m_requestMethod; return m_requestMethod;
} }
@ -352,7 +352,7 @@ QDebug operator<<(QDebug debug, CoapReply *reply)
QMetaEnum messageTypeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("MessageType")); QMetaEnum messageTypeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("MessageType"));
QMetaEnum contentTypeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("ContentType")); QMetaEnum contentTypeEnum = metaObject.enumerator(metaObject.indexOfEnumerator("ContentType"));
debug.nospace() << "CoapReply(" << messageTypeEnum.valueToKey(reply->messageType()) << ")" << endl; debug.nospace() << "CoapReply(" << messageTypeEnum.valueToKey(reply->messageType()) << ")" << endl;
debug.nospace() << " Status code: " << CoapPdu::getStatusCodeString(reply->statusCode()) << endl; debug.nospace() << " Status code: " << CoapPdu::getReqRspCodeString(reply->reqRspCode()) << endl;
debug.nospace() << " Content type: " << contentTypeEnum.valueToKey(reply->contentType()) << endl; debug.nospace() << " Content type: " << contentTypeEnum.valueToKey(reply->contentType()) << endl;
debug.nospace() << " Payload size: " << reply->payload().size() << endl; debug.nospace() << " Payload size: " << reply->payload().size() << endl;

View File

@ -66,7 +66,7 @@ public:
CoapPdu::ContentType contentType() const; CoapPdu::ContentType contentType() const;
CoapPdu::MessageType messageType() const; CoapPdu::MessageType messageType() const;
CoapPdu::StatusCode statusCode() const; CoapPdu::ReqRspCode reqRspCode() const;
private: private:
CoapReply(const CoapRequest &request, QObject *parent = 0); CoapReply(const CoapRequest &request, QObject *parent = 0);
@ -78,9 +78,9 @@ private:
void resend(); void resend();
void setContentType(const CoapPdu::ContentType contentType = CoapPdu::TextPlain); void setContentType(CoapPdu::ContentType contentType = CoapPdu::TextPlain);
void setMessageType(const CoapPdu::MessageType &messageType); void setMessageType(CoapPdu::MessageType messageType);
void setStatusCode(const CoapPdu::StatusCode &statusCode); void setReqRspCode(CoapPdu::ReqRspCode reqRspCode);
QTimer *m_timer; QTimer *m_timer;
CoapRequest m_request; CoapRequest m_request;
@ -93,20 +93,20 @@ private:
CoapPdu::ContentType m_contentType; CoapPdu::ContentType m_contentType;
CoapPdu::MessageType m_messageType; CoapPdu::MessageType m_messageType;
CoapPdu::StatusCode m_statusCode; CoapPdu::ReqRspCode m_reqRspCode;
// data for the request // data for the request
void setHostAddress(const QHostAddress &address); void setHostAddress(const QHostAddress &address);
QHostAddress hostAddress() const; QHostAddress hostAddress() const;
void setPort(const int &port); void setPort(int port);
int port() const; int port() const;
void setRequestPayload(const QByteArray &requestPayload); void setRequestPayload(const QByteArray &requestPayload);
QByteArray requestPayload() const; QByteArray requestPayload() const;
void setRequestMethod(const CoapPdu::StatusCode &method); void setRequestMethod(CoapPdu::ReqRspCode method);
CoapPdu::StatusCode requestMethod() const; CoapPdu::ReqRspCode requestMethod() const;
void setRequestData(const QByteArray &requestData); void setRequestData(const QByteArray &requestData);
QByteArray requestData() const; QByteArray requestData() const;
@ -125,7 +125,7 @@ private:
QHostAddress m_hostAddress; QHostAddress m_hostAddress;
int m_port; int m_port;
CoapPdu::StatusCode m_requestMethod; CoapPdu::ReqRspCode m_requestMethod;
QByteArray m_requestPayload; QByteArray m_requestPayload;
QByteArray m_requestData; QByteArray m_requestData;
bool m_lockedUp; bool m_lockedUp;

View File

@ -44,7 +44,7 @@ CoapRequest::CoapRequest(const QUrl &url) :
m_url(url), m_url(url),
m_contentType(CoapPdu::TextPlain), m_contentType(CoapPdu::TextPlain),
m_messageType(CoapPdu::Confirmable), m_messageType(CoapPdu::Confirmable),
m_statusCode(CoapPdu::Empty) m_reqRspCode(CoapPdu::Empty)
{ {
} }

View File

@ -57,7 +57,7 @@ private:
QUrl m_url; QUrl m_url;
CoapPdu::ContentType m_contentType; CoapPdu::ContentType m_contentType;
CoapPdu::MessageType m_messageType; CoapPdu::MessageType m_messageType;
CoapPdu::StatusCode m_statusCode; CoapPdu::ReqRspCode m_reqRspCode;
}; };