void CoapNetworkAccessManager::processNotification(CoapTarget *target, const CoapPdu &pdu, const QHostAddress &address, const quint16 &port)
{
    qCDebug(dcCoap) << "<--- Notification" << address << pdu;

    // Check if this target has an observation resource for this token
    if (!target->hasObservationResource(pdu.token())) {
        qCWarning(dcCoap()) << "No observe resource for this notification.";
        return;
    }

    CoapObserveResource resource = target->getObservationResource(pdu.token());

    // check if it is a blockwise notification
    if (pdu.hasOption(CoapOption::Block2)) {

        // First part of the blocked notification
        // respond with ACK
        CoapPdu responsePdu;
        responsePdu.setMessageType(CoapPdu::Acknowledgement);
        responsePdu.setStatusCode(CoapPdu::Empty);
        responsePdu.setMessageId(pdu.messageId());
        responsePdu.setToken(pdu.token());

        qCDebug(dcCoap) << "---> Notification:" << address << responsePdu;
        sendCoapPdu(address, port, responsePdu);

        // create reply for blockwise transfere
        if (target->hasRunningObservationReply()) {
            CoapReply *oldReply = target->currentObservationReply();
            oldReply->deleteLater();
            target->removeReply(oldReply);
        }

        CoapReply *reply = new CoapReply(CoapRequest(resource.url()), this);
        reply->setRequestMethod(CoapPdu::Get);
        reply->appendPayloadData(pdu.payload());

        // Lets store the observation number
        int notificationNumber = 0;
        foreach (const CoapOption &option, pdu.options()) {
            if (option.option() == CoapOption::Observe) {
                notificationNumber = option.data().toHex().toInt(0, 16);
            }
        }

        target->setCurrentObservationReply(reply);
        m_observeBlockwise.insert(reply, notificationNumber);

        connect(reply, &CoapReply::timeout, this, &CoapNetworkAccessManager::onReplyTimeout);
        connect(reply, &CoapReply::finished, this, &CoapNetworkAccessManager::onReplyFinished);

        CoapPdu pdu;
        pdu.setMessageType(reply->request().messageType());
        pdu.setStatusCode(reply->requestMethod());
        pdu.createMessageId();
        pdu.createToken();

        // Add the options in correct order
        // Option number 3
        pdu.addOption(CoapOption::UriHost, reply->request().url().host().toUtf8());

        QStringList urlTokens = reply->request().url().path().split("/");
        urlTokens.removeAll(QString());

        // Option number 11
        foreach (const QString &token, urlTokens)
            pdu.addOption(CoapOption::UriPath, token.toUtf8());

        // Option number 15
        if (reply->request().url().hasQuery())
            pdu.addOption(CoapOption::UriQuery, reply->request().url().query().toUtf8());

        // Option number 23
        pdu.addOption(CoapOption::Block2, CoapPduBlock::createBlock(1, 2, true));

        QByteArray pduData = pdu.pack();
        reply->setRequestData(pduData);
        reply->setHostAddress(address);
        reply->setPort(port);
        reply->m_timer->start();

        qCDebug(dcCoap) << "---> Notification" << address << pdu;
        sendData(address, port, pduData);

    } else {
Beispiel #2
0
/*! Constructs a copy of the given \a other \l{CoapObserveResource}. */
CoapObserveResource::CoapObserveResource(const CoapObserveResource &other)
{
    m_url = other.url();
    m_token = other.token();
}