client version of coap
Dependencies: nRF24L01P cantcoap3
coapClient.cpp
- Committer:
- Ka_myk
- Date:
- 2019-01-18
- Revision:
- 0:6a6f97ca5572
- Child:
- 1:1d936c763440
File content as of revision 0:6a6f97ca5572:
// // Created by Kamil Mykitiuk on 2019-01-17. // #include <cstring> #include "CoapClient.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, u_int16_t message_id, char* uri) { return match_uri(response, uri) && response.getType() == CoapPDU::COAP_ACKNOWLEDGEMENT && response.getMessageID() == message_id; } bool CoapClient::isAck(CoapPDU& response, u_int16_t message_id, char* uri) { if (response.validate()) { if (isExpectedResponse(response, message_id, uri)) { return true; } else { sendReset(response.getMessageID()); // if this is not what we wanted, inform server about error } } return false; } /* send reset to server * * @return 0 if successful * -4 if radio is not working properly * */ int CoapClient::sendReset(uint16_t message_id) { CoapPDU reset = CoapPDU(); reset.setMessageID(message_id); reset.setType(CoapPDU::COAP_RESET); int ret = this->radioWrapper.write(reset.getPDUPointer(), reset.getPDULength()); if (ret < 0) { return RADIO_NOT_WORKING; } else { return 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) { 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; for (int i = 0; i < this->retransmissionLimit; i++) { int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); // send empty payload to get uri if (ret < 0) { return RADIO_NOT_WORKING; } int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param if (readLen > 0) { // if something is recieved process it CoapPDU response(returnBuffer, len, readLen); if (isAck(response, messageId, uri)) { if (std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0) { if (response.getPayloadLength() >= len) { std::memcpy(buffer, response.getPayloadPointer(), static_cast<size_t>(response.getPayloadLength())); return response.getPayloadLength(); } else { return SMALL_BUFFER; } } else { return SERVER_RESPONSE_AMBIGOUS; } } } else if (readLen < 0) { return RADIO_NOT_WORKING; } timeout *= 2; } 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) { 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; for (int i = 0; i < this->retransmissionLimit; i++) { int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); if (ret < 0) { return RADIO_NOT_WORKING; } int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param if (readLen > 0) { // if something is recieved process it CoapPDU response(returnBuffer, len, readLen); if (isAck(response, messageId, uri)) { if (response.getCode() == CoapPDU::COAP_CREATED && std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0) { return 0; } else // if server hasn't responded properly return SERVER_RESPONSE_AMBIGOUS; } } else if (readLen < 0) { return RADIO_NOT_WORKING; } timeout *= 2; } 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, 4); return this->message_counter++; } CoapClient::CoapClient(uint8_t* token, int retransmissionLimit, int timeout, RadioWrapper& radio) : radioWrapper(radio), listeningTimeout( timeout), retransmissionLimit( retransmissionLimit) { std::memcpy(this->token, token, 4); this->message_counter = 16; }