From d606e250128c1dd4d54b081b09dbd935fc186f6f Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 1 Feb 2019 10:29:52 +0100 Subject: Add API for canceling observe for the given URL Change-Id: Idb84601dd8f1d8c011ecccd95c0e65e77920bd11 Reviewed-by: Karsten Heimrich --- src/coap/qcoapclient.cpp | 15 ++++++++++++++- src/coap/qcoapclient.h | 1 + src/coap/qcoapprotocol.cpp | 23 +++++++++++++++++++++-- src/coap/qcoapprotocol.h | 3 ++- src/coap/qcoaprequest.cpp | 47 +++++++++++++++++++++++++++++----------------- src/coap/qcoaprequest.h | 1 + 6 files changed, 69 insertions(+), 21 deletions(-) diff --git a/src/coap/qcoapclient.cpp b/src/coap/qcoapclient.cpp index 7df1295..816e88c 100644 --- a/src/coap/qcoapclient.cpp +++ b/src/coap/qcoapclient.cpp @@ -599,12 +599,25 @@ QCoapReply *QCoapClient::observe(const QUrl &url) */ void QCoapClient::cancelObserve(QCoapReply *notifiedReply) { - // TODO: Plan to add an override to cancel observe with an URL Q_D(QCoapClient); QMetaObject::invokeMethod(d->protocol, "cancelObserve", Q_ARG(QPointer, QPointer(notifiedReply))); } +/*! + \overload + + Cancels the observation of a resource identified by the \a url. + + \sa observe() +*/ +void QCoapClient::cancelObserve(const QUrl &url) +{ + Q_D(QCoapClient); + const auto adjustedUrl = QCoapRequest::adjustedUrl(url, d->connection->isSecure()); + QMetaObject::invokeMethod(d->protocol, "cancelObserve", Q_ARG(QUrl, adjustedUrl)); +} + /*! \internal diff --git a/src/coap/qcoapclient.h b/src/coap/qcoapclient.h index 5b95e55..bce7446 100644 --- a/src/coap/qcoapclient.h +++ b/src/coap/qcoapclient.h @@ -70,6 +70,7 @@ public: QCoapReply *observe(const QCoapRequest &request); QCoapReply *observe(const QUrl &request); void cancelObserve(QCoapReply *notifiedReply); + void cancelObserve(const QUrl &url); #if 0 //! TODO Add Multicast discovery in a later submission. diff --git a/src/coap/qcoapprotocol.cpp b/src/coap/qcoapprotocol.cpp index 638ca8a..00075f0 100644 --- a/src/coap/qcoapprotocol.cpp +++ b/src/coap/qcoapprotocol.cpp @@ -508,9 +508,9 @@ void QCoapProtocolPrivate::sendReset(QCoapInternalRequest *request) const A Reset (RST) message will be sent at the reception of the next message. */ -void QCoapProtocol::cancelObserve(QPointer reply) +void QCoapProtocol::cancelObserve(QPointer reply) const { - Q_D(QCoapProtocol); + Q_D(const QCoapProtocol); if (reply.isNull()) return; @@ -528,6 +528,25 @@ void QCoapProtocol::cancelObserve(QPointer reply) QMetaObject::invokeMethod(reply, "_q_setObserveCancelled", Qt::QueuedConnection); } +/*! + \internal + + Cancels resource observation for the given \a url. The QCoapReply::notified() + signal will not be emitted after cancellation. + + A Reset (RST) message will be sent at the reception of the next message. +*/ +void QCoapProtocol::cancelObserve(const QUrl &url) const +{ + Q_D(const QCoapProtocol); + + for (const auto &exchange : d->exchangeMap) { + Q_ASSERT(exchange.userReply); + if (exchange.userReply->url() == url) + cancelObserve(exchange.userReply); + } +} + /*! \internal diff --git a/src/coap/qcoapprotocol.h b/src/coap/qcoapprotocol.h index cddedb0..b357db7 100644 --- a/src/coap/qcoapprotocol.h +++ b/src/coap/qcoapprotocol.h @@ -77,7 +77,8 @@ public Q_SLOTS: private Q_SLOTS: void sendRequest(QPointer reply, QCoapConnection *connection); - void cancelObserve(QPointer reply); + void cancelObserve(QPointer reply) const; + void cancelObserve(const QUrl &url) const; private: Q_DECLARE_PRIVATE(QCoapProtocol) diff --git a/src/coap/qcoaprequest.cpp b/src/coap/qcoaprequest.cpp index f5631f6..b75be82 100644 --- a/src/coap/qcoaprequest.cpp +++ b/src/coap/qcoaprequest.cpp @@ -247,23 +247,7 @@ void QCoapRequest::enableObserve() void QCoapRequest::adjustUrl(bool secure) { Q_D(QCoapRequest); - - if (d->uri.isEmpty() || !d->uri.isValid()) - return; - - QUrl finalizedUrl = d->uri; - const auto scheme = secure ? CoapSecureScheme : CoapScheme; - if (d->uri.isRelative()) - finalizedUrl = d->uri.toString().prepend(scheme + QLatin1String("://")); - else if (d->uri.scheme().isEmpty()) - finalizedUrl.setScheme(scheme); - - if (d->uri.port() == -1) { - const auto port = secure ? QtCoap::DefaultSecurePort : QtCoap::DefaultPort; - finalizedUrl.setPort(port); - } - - d->uri = finalizedUrl; + d->uri = adjustedUrl(d->uri, secure); } /*! @@ -293,6 +277,35 @@ bool QCoapRequest::isUrlValid(const QUrl &url) && !url.hasFragment()); } +/*! + Adjusts the \a url by setting the correct default scheme and port + (if not indicated) based on the \a secure parameter. Returns the + adjusted URL. + + In non-secure mode the scheme of request URL will default to \c coap, and + its port will default to \e 5683. In secure mode the scheme will default to + \c coaps, and the port will default to \e 5684. +*/ +QUrl QCoapRequest::adjustedUrl(const QUrl &url, bool secure) +{ + if (url.isEmpty() || !url.isValid()) + return QUrl(); + + QUrl finalizedUrl = url; + const auto scheme = secure ? CoapSecureScheme : CoapScheme; + if (url.isRelative()) + finalizedUrl = url.toString().prepend(scheme + QLatin1String("://")); + else if (url.scheme().isEmpty()) + finalizedUrl.setScheme(scheme); + + if (url.port() == -1) { + const auto port = secure ? QtCoap::DefaultSecurePort : QtCoap::DefaultPort; + finalizedUrl.setPort(port); + } + + return finalizedUrl; +} + /*! \internal diff --git a/src/coap/qcoaprequest.h b/src/coap/qcoaprequest.h index 8c2ce97..7d6c7a5 100644 --- a/src/coap/qcoaprequest.h +++ b/src/coap/qcoaprequest.h @@ -68,6 +68,7 @@ public: bool isValid() const; static bool isUrlValid(const QUrl &url); + static QUrl adjustedUrl(const QUrl &url, bool secure); private: // Q_DECLARE_PRIVATE equivalent for shared data pointers -- cgit v1.2.3