Library for handling subset of coap functionality by radio transmitter.

Dependencies:   nRF24L01P cantcoap

Dependents:   server2

coapServer.cpp

Committer:
Ka_myk
Date:
2019-01-20
Revision:
2:c3ca8b8526e0
Parent:
1:1d936c763440
Child:
4:9f635ab44d8e

File content as of revision 2:c3ca8b8526e0:

//
// Created by Kamil Mykitiuk on 2019-01-18.
//

#include "coapServer.h"
#include "dbg.h"

int CoapServer::listen(uint8_t* buffer, int len, METHOD* requestMethod, int* uriNumber) {
    uint8_t requestBuffer[radioWrapper.packetSize()];
    int ret = radioWrapper.read(requestBuffer, radioWrapper.packetSize(), this->listeningTimeout);
    DBG("REC: %d \r\n", ret);
    if (ret < 0) {
        return RADIO_NOT_WORKING;
    } else if (ret > 0) {
        CoapPDU request(requestBuffer, ret, radioWrapper.packetSize());
        if (request.validate()) {
            request.printHuman();
            this->lastMessageId = request.getMessageID();
            std::memcpy(this->lastMessageToken, request.getTokenPointer(), 1);
            if (request.getPayloadLength() <= len) {
                std::memcpy(buffer, request.getPayloadPointer(), static_cast<size_t>(request.getPayloadLength()));
                if (request.getCode() == CoapPDU::COAP_GET) {
                    *requestMethod = GET;
                } else if (request.getCode() == CoapPDU::COAP_POST) {
                    *requestMethod = POST;
                }
                char requestUri[32];
                int requestUriLen = 0;
                request.getURI(requestUri, 32, &requestUriLen);
                bool foundMatchingUri = false;
                DBG("URI: %s", requestUri);
                for (int i = 0; i < urisNumber; ++i) {
                    if (std::strcmp(requestUri, this->uris[i].data()) == 0) {
                        *uriNumber = i;
                        foundMatchingUri = true;
                    }
                }
                if (!foundMatchingUri) {
                    return UNKNOWN_URI;
                }
                return request.getPayloadLength();
            } else {
                return SMALL_BUFFER;
            }
        }
    }
    return 0;
}

int CoapServer::respond(int uri, uint8_t* buffer, int len, CoapPDU::Code responseCode) {
    CoapPDU response = CoapPDU();
    prepareAckPDU(response);
    response.setCode(responseCode);

    DBG("uri: %d, %s", (int) uris[uri].size(), uris[uri].data());
    if (response.addOption(CoapPDU::COAP_OPTION_URI_PATH, (int) uris[uri].size(), (uint8_t*) uris[uri].data()) != 0) {
        return COAP_ERROR;
    }
    DBG("SEND RESPONSE");
    response.setPayload(buffer, len);
    response.printHuman();
    int ret = radioWrapper.write(response.getPDUPointer(), response.getPDULength());
    if (ret < 0) {
        return RADIO_NOT_WORKING;
    }
    return ret;
}

void CoapServer::prepareAckPDU(CoapPDU& coapPDU) {
    coapPDU.setVersion(1);
    coapPDU.setType(CoapPDU::COAP_ACKNOWLEDGEMENT);
    coapPDU.setMessageID(this->lastMessageId);
    coapPDU.setToken(this->lastMessageToken, 1);
}

CoapServer::CoapServer(int timeout, std::string* uris, int urisNumber, int channel, unsigned long long rx_address,
                       unsigned long long tx_address) :
        listeningTimeout(timeout), radioWrapper(channel, rx_address, tx_address), urisNumber(urisNumber), uris(uris) {}