Library for handling subset of coap functionality by radio transmitter.
Dependencies: nRF24L01P cantcoap
Diff: coapServer.cpp
- Revision:
- 4:9f635ab44d8e
- Parent:
- 2:c3ca8b8526e0
- Child:
- 5:b8d21be6b36c
--- a/coapServer.cpp Sun Jan 20 23:28:23 2019 +0000 +++ b/coapServer.cpp Mon Jan 21 18:52:22 2019 +0000 @@ -5,74 +5,108 @@ #include "coapServer.h" #include "dbg.h" -int CoapServer::listen(uint8_t* buffer, int len, METHOD* requestMethod, int* uriNumber) { +int CoapServer::nextIndex() { + this->lastMessageIndex = (this->lastMessageIndex+1) % this->queueMax; + return this->lastMessageIndex; +} + +int CoapServer::ackRepeatedPost(CoapPDU& request, int pipe) { + CoapPDU response = CoapPDU(); + response.setVersion(1); + response.setType(CoapPDU::COAP_ACKNOWLEDGEMENT); + response.setCode(CoapPDU::COAP_CREATED); + char requestUri[32]; + int requestUriLen = 0; + request.getURI(requestUri, 32, &requestUriLen); + if(response.setURI(requestUri, requestUriLen) != 0) { + return COAP_ERROR; + } + if(radioWrapper.write(response.getPDUPointer(), response.getPDULength(), pipe) < 0) { + return RADIO_NOT_WORKING; + } + return SILENT; +} + +int CoapServer::listen(uint8_t* buffer, int len, METHOD* requestMethod, int* uriNumber, int* pipe) { uint8_t requestBuffer[radioWrapper.packetSize()]; - int ret = radioWrapper.read(requestBuffer, radioWrapper.packetSize(), this->listeningTimeout); - DBG("REC: %d \r\n", ret); + int ret = radioWrapper.read(requestBuffer, radioWrapper.packetSize(), this->listeningTimeout, pipe); + DBG("READ: %d", ret); if (ret < 0) { return RADIO_NOT_WORKING; - } else if (ret > 0) { - CoapPDU request(requestBuffer, ret, radioWrapper.packetSize()); + } else if(ret > 0) { + CoapPDU request(requestBuffer, radioWrapper.packetSize(), ret); if (request.validate()) { request.printHuman(); - this->lastMessageId = request.getMessageID(); - std::memcpy(this->lastMessageToken, request.getTokenPointer(), 1); + for (int i = 0; i < idQ.size(); ++i) { // check if messageId is known + if(idQ[i] == request.getMessageID()) { + if(request.getCode() == CoapPDU::COAP_POST) { // dla posta odpowiadamy pustym + return ackRepeatedPost(request, *pipe); + } + } else { // geta obsługujemy od nowa + break; + } + } + + // zapamiętaj dane + int index = nextIndex(); + this->idQ[index] = request.getMessageID(); + this->tokenQ[index] = request.getTokenPointer()[0]; + 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); + DBG("URI: %s %d", requestUri, requestUriLen); + for (int i = 0; i < urisNumber; ++i) { - if (std::strcmp(requestUri, this->uris[i].data()) == 0) { + if(std::strcmp(requestUri, this->uris[i].data()) == 0) { *uriNumber = i; foundMatchingUri = true; } } - if (!foundMatchingUri) { + if(!foundMatchingUri) { return UNKNOWN_URI; } + return request.getPayloadLength(); } else { return SMALL_BUFFER; } } } - return 0; + return SILENT; } -int CoapServer::respond(int uri, uint8_t* buffer, int len, CoapPDU::Code responseCode) { +int CoapServer::respond(int uri, uint8_t* buffer, int len, CoapPDU::Code responseCode, int pipe) { CoapPDU response = CoapPDU(); - prepareAckPDU(response); + response.setVersion(1); + response.setType(CoapPDU::COAP_ACKNOWLEDGEMENT); + response.setMessageID(this->idQ[this->lastMessageIndex]); + uint8_t token = this->tokenQ[this->lastMessageIndex]; + response.setToken(&token, 1); 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; + response.setURI((char*) uris[uri].data(), (int)uris[uri].size()); + if(len > 0) { + response.setPayload(buffer, len); } - DBG("SEND RESPONSE"); - response.setPayload(buffer, len); - response.printHuman(); - int ret = radioWrapper.write(response.getPDUPointer(), response.getPDULength()); - if (ret < 0) { + int ret = radioWrapper.write(response.getPDUPointer(), response.getPDULength(), pipe); + 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) {} \ No newline at end of file +CoapServer::CoapServer(unsigned queueMax, int timeout, std::string* uris, int urisNumber, int channel, + unsigned long long tx_address, unsigned long long rx_addresses[]) : queueMax(queueMax), listeningTimeout(timeout),radioWrapper(channel, tx_address, rx_addresses), urisNumber(urisNumber), uris(uris){ + idQ.resize(queueMax, 0); + tokenQ.resize(queueMax, 0); +} \ No newline at end of file