client version of coap
Dependencies: nRF24L01P cantcoap3
coapClient.cpp
- Committer:
- Ka_myk
- Date:
- 2019-01-25
- Revision:
- 4:792cf53a73c4
- Parent:
- 2:e8823d9fa162
- Child:
- 5:d633e12f113f
File content as of revision 4:792cf53a73c4:
// // Created by Kamil Mykitiuk on 2019-01-17. // #include "coapClient.h" #include "dbg.h" bool match_uri(CoapPDU& coapPDU, char* uri) { char respone_uri[32]; int len = 0; coapPDU.getURI(respone_uri, 32, &len); return strcmp(uri, respone_uri) == 0; } bool isExpectedResponse(CoapPDU& response, uint16_t message_id, char* uri) { return match_uri(response, uri) && response.getType() == CoapPDU::COAP_ACKNOWLEDGEMENT && response.getMessageID() == message_id; } bool CoapClient::isAck(CoapPDU& response, uint16_t message_id, char* uri) { if (response.validate()) { response.printHuman(); if (isExpectedResponse(response, message_id, uri)) { return true; } } return false; } bool CoapClient::hasGetResponse(CoapPDU& response) { return std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0 && response.getCode() == CoapPDU::COAP_CONTENT; } bool CoapClient::hasPostResponse(CoapPDU& response) { return response.getCode() == CoapPDU::COAP_CREATED && std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0; } /* send get request to given uri of connected server * * @return number of saved bytes in provided buffer or * -1 if server responded ambiguously; * -2 if server timed out; * -3 if provided buffer is to small to save response, * -4 if if radio is not functioning properly * */ int CoapClient::get(uint8_t* buffer, int len, char* uri) { Timer t; CoapPDU coapPDU = CoapPDU(); uint16_t messageId = preparePDU(coapPDU); coapPDU.setCode(CoapPDU::COAP_GET); coapPDU.setURI(uri); uint8_t returnBuffer[radioWrapper.packetSize()]; int TIMEOUT = this->listeningTimeout; int timeout = TIMEOUT; for (int i = 0; i < this->retransmissionLimit; i++) { while (timeout > 0) { int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); // send empty payload to get uri if (ret < 0) { return RADIO_NOT_WORKING; } t.start(); int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param t.stop(); timeout -= t.read_ms(); t.reset(); if (readLen > 0) { // if something is recieved process it CoapPDU response(returnBuffer, len, readLen); if (isAck(response, messageId, uri) && hasGetResponse(response)) { DBG("RESPONSE: %d", readLen); response.printHuman(); if (response.getPayloadLength() <= len) { std::memcpy(buffer, response.getPayloadPointer(), static_cast<size_t>(response.getPayloadLength())); return response.getPayloadLength(); } else { return SMALL_BUFFER; } } else { DBG("NIEMOJE"); DBG("PAYLOAD: %s", response.getPayloadPointer()); continue; } } else if (readLen < 0) { return RADIO_NOT_WORKING; } } TIMEOUT *= 2; timeout = TIMEOUT; } return SERVER_TIMED_OUT; } /* send post request to given uri of connected server * * @return 0 if operation has been completed successfully * -1 if server responded ambiguously; * -2 if server timed out; * -4 if radio is not working properly * */ int CoapClient::post(uint8_t* buffer, int len, char* uri) { Timer t; CoapPDU coapPDU = CoapPDU(); uint16_t messageId = preparePDU(coapPDU); coapPDU.setCode(CoapPDU::COAP_POST); coapPDU.setURI(uri); coapPDU.setPayload(buffer, len); uint8_t returnBuffer[radioWrapper.packetSize()]; int TIMEOUT = this->listeningTimeout; int timeout = TIMEOUT; for (int i = 0; i < this->retransmissionLimit; i++) { while(timeout > 0) { int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); if (ret < 0) { return RADIO_NOT_WORKING; } t.start(); int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param t.stop(); timeout -= t.read_ms(); t.reset(); if (readLen > 0) { // if something is recieved process it CoapPDU response(returnBuffer, len, readLen); if (isAck(response, messageId, uri) && hasPostResponse(response)) { return 0; } else { // if server hasn't responded properly DBG("NIEMOJE"); DBG("PAYLOAD: %s", response.getPayloadPointer()); continue; } } else if (readLen < 0) { return RADIO_NOT_WORKING; } } TIMEOUT *= 2; timeout = TIMEOUT; } return SERVER_TIMED_OUT; } uint16_t CoapClient::preparePDU(CoapPDU& coapPDU) { coapPDU.setVersion(1); coapPDU.setType(CoapPDU::COAP_CONFIRMABLE); coapPDU.setMessageID(this->message_counter); coapPDU.setToken(this->token, 1); return this->message_counter++; } CoapClient::CoapClient(uint8_t* token, int retransmissionLimit, int timeout, int channel, unsigned long long rx_address, unsigned long long tx_address) : listeningTimeout(timeout), retransmissionLimit(retransmissionLimit), radioWrapper(channel, rx_address, tx_address) { std::memcpy(this->token, token, 1); this->message_counter = 666; // set to random }