client version of coap
Dependencies: nRF24L01P cantcoap3
coapClient.cpp@1:1d936c763440, 2019-01-20 (annotated)
- Committer:
- Ka_myk
- Date:
- Sun Jan 20 13:48:02 2019 +0000
- Revision:
- 1:1d936c763440
- Parent:
- 0:6a6f97ca5572
- Child:
- 2:e8823d9fa162
try to make it work;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ka_myk | 0:6a6f97ca5572 | 1 | // |
Ka_myk | 0:6a6f97ca5572 | 2 | // Created by Kamil Mykitiuk on 2019-01-17. |
Ka_myk | 0:6a6f97ca5572 | 3 | // |
Ka_myk | 0:6a6f97ca5572 | 4 | |
Ka_myk | 0:6a6f97ca5572 | 5 | #include <cstring> |
Ka_myk | 1:1d936c763440 | 6 | #include "coapClient.h" |
Ka_myk | 0:6a6f97ca5572 | 7 | |
Ka_myk | 0:6a6f97ca5572 | 8 | |
Ka_myk | 0:6a6f97ca5572 | 9 | bool match_uri(CoapPDU& coapPDU, char* uri) { |
Ka_myk | 0:6a6f97ca5572 | 10 | char respone_uri[32]; |
Ka_myk | 0:6a6f97ca5572 | 11 | int len = 0; |
Ka_myk | 0:6a6f97ca5572 | 12 | coapPDU.getURI(respone_uri, 32, &len); |
Ka_myk | 0:6a6f97ca5572 | 13 | return strcmp(uri, respone_uri) == 0; |
Ka_myk | 0:6a6f97ca5572 | 14 | } |
Ka_myk | 0:6a6f97ca5572 | 15 | |
Ka_myk | 0:6a6f97ca5572 | 16 | |
Ka_myk | 1:1d936c763440 | 17 | bool isExpectedResponse(CoapPDU& response, uint16_t message_id, char* uri) { |
Ka_myk | 0:6a6f97ca5572 | 18 | return match_uri(response, uri) && response.getType() == CoapPDU::COAP_ACKNOWLEDGEMENT && |
Ka_myk | 0:6a6f97ca5572 | 19 | response.getMessageID() == message_id; |
Ka_myk | 0:6a6f97ca5572 | 20 | } |
Ka_myk | 0:6a6f97ca5572 | 21 | |
Ka_myk | 1:1d936c763440 | 22 | bool CoapClient::isAck(CoapPDU& response, uint16_t message_id, char* uri) { |
Ka_myk | 0:6a6f97ca5572 | 23 | if (response.validate()) { |
Ka_myk | 0:6a6f97ca5572 | 24 | if (isExpectedResponse(response, message_id, uri)) { |
Ka_myk | 0:6a6f97ca5572 | 25 | return true; |
Ka_myk | 0:6a6f97ca5572 | 26 | } else { |
Ka_myk | 0:6a6f97ca5572 | 27 | sendReset(response.getMessageID()); // if this is not what we wanted, inform server about error |
Ka_myk | 0:6a6f97ca5572 | 28 | } |
Ka_myk | 0:6a6f97ca5572 | 29 | } |
Ka_myk | 0:6a6f97ca5572 | 30 | return false; |
Ka_myk | 0:6a6f97ca5572 | 31 | } |
Ka_myk | 0:6a6f97ca5572 | 32 | |
Ka_myk | 0:6a6f97ca5572 | 33 | |
Ka_myk | 0:6a6f97ca5572 | 34 | /* send reset to server |
Ka_myk | 0:6a6f97ca5572 | 35 | * |
Ka_myk | 0:6a6f97ca5572 | 36 | * @return 0 if successful |
Ka_myk | 0:6a6f97ca5572 | 37 | * -4 if radio is not working properly |
Ka_myk | 0:6a6f97ca5572 | 38 | * */ |
Ka_myk | 0:6a6f97ca5572 | 39 | int CoapClient::sendReset(uint16_t message_id) { |
Ka_myk | 0:6a6f97ca5572 | 40 | CoapPDU reset = CoapPDU(); |
Ka_myk | 0:6a6f97ca5572 | 41 | reset.setMessageID(message_id); |
Ka_myk | 0:6a6f97ca5572 | 42 | reset.setType(CoapPDU::COAP_RESET); |
Ka_myk | 0:6a6f97ca5572 | 43 | int ret = this->radioWrapper.write(reset.getPDUPointer(), reset.getPDULength()); |
Ka_myk | 0:6a6f97ca5572 | 44 | if (ret < 0) { |
Ka_myk | 0:6a6f97ca5572 | 45 | return RADIO_NOT_WORKING; |
Ka_myk | 0:6a6f97ca5572 | 46 | } else { |
Ka_myk | 0:6a6f97ca5572 | 47 | return 0; |
Ka_myk | 0:6a6f97ca5572 | 48 | } |
Ka_myk | 0:6a6f97ca5572 | 49 | } |
Ka_myk | 0:6a6f97ca5572 | 50 | |
Ka_myk | 0:6a6f97ca5572 | 51 | /* send get request to given uri of connected server |
Ka_myk | 0:6a6f97ca5572 | 52 | * |
Ka_myk | 0:6a6f97ca5572 | 53 | * @return number of saved bytes in provided buffer or |
Ka_myk | 0:6a6f97ca5572 | 54 | * -1 if server responded ambiguously; |
Ka_myk | 0:6a6f97ca5572 | 55 | * -2 if server timed out; |
Ka_myk | 0:6a6f97ca5572 | 56 | * -3 if provided buffer is to small to save response, |
Ka_myk | 0:6a6f97ca5572 | 57 | * -4 if if radio is not functioning properly |
Ka_myk | 0:6a6f97ca5572 | 58 | * */ |
Ka_myk | 0:6a6f97ca5572 | 59 | int CoapClient::get(uint8_t* buffer, int len, char* uri) { |
Ka_myk | 0:6a6f97ca5572 | 60 | CoapPDU coapPDU = CoapPDU(); |
Ka_myk | 0:6a6f97ca5572 | 61 | uint16_t messageId = preparePDU(coapPDU); |
Ka_myk | 0:6a6f97ca5572 | 62 | coapPDU.setCode(CoapPDU::COAP_GET); |
Ka_myk | 0:6a6f97ca5572 | 63 | coapPDU.setURI(uri); |
Ka_myk | 0:6a6f97ca5572 | 64 | |
Ka_myk | 0:6a6f97ca5572 | 65 | uint8_t returnBuffer[radioWrapper.packetSize()]; |
Ka_myk | 0:6a6f97ca5572 | 66 | int timeout = this->listeningTimeout; |
Ka_myk | 0:6a6f97ca5572 | 67 | for (int i = 0; i < this->retransmissionLimit; i++) { |
Ka_myk | 0:6a6f97ca5572 | 68 | int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); // send empty payload to get uri |
Ka_myk | 0:6a6f97ca5572 | 69 | |
Ka_myk | 0:6a6f97ca5572 | 70 | if (ret < 0) { |
Ka_myk | 0:6a6f97ca5572 | 71 | return RADIO_NOT_WORKING; |
Ka_myk | 0:6a6f97ca5572 | 72 | } |
Ka_myk | 0:6a6f97ca5572 | 73 | |
Ka_myk | 0:6a6f97ca5572 | 74 | int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param |
Ka_myk | 0:6a6f97ca5572 | 75 | if (readLen > 0) { // if something is recieved process it |
Ka_myk | 0:6a6f97ca5572 | 76 | CoapPDU response(returnBuffer, len, readLen); |
Ka_myk | 0:6a6f97ca5572 | 77 | if (isAck(response, messageId, uri)) { |
Ka_myk | 0:6a6f97ca5572 | 78 | if (std::memcmp(response.getTokenPointer(), this->token, |
Ka_myk | 0:6a6f97ca5572 | 79 | static_cast<size_t>(response.getTokenLength())) == 0) { |
Ka_myk | 0:6a6f97ca5572 | 80 | if (response.getPayloadLength() >= len) { |
Ka_myk | 0:6a6f97ca5572 | 81 | std::memcpy(buffer, response.getPayloadPointer(), |
Ka_myk | 0:6a6f97ca5572 | 82 | static_cast<size_t>(response.getPayloadLength())); |
Ka_myk | 0:6a6f97ca5572 | 83 | return response.getPayloadLength(); |
Ka_myk | 0:6a6f97ca5572 | 84 | } else { |
Ka_myk | 0:6a6f97ca5572 | 85 | return SMALL_BUFFER; |
Ka_myk | 0:6a6f97ca5572 | 86 | } |
Ka_myk | 0:6a6f97ca5572 | 87 | } else { |
Ka_myk | 0:6a6f97ca5572 | 88 | return SERVER_RESPONSE_AMBIGOUS; |
Ka_myk | 0:6a6f97ca5572 | 89 | } |
Ka_myk | 0:6a6f97ca5572 | 90 | } |
Ka_myk | 0:6a6f97ca5572 | 91 | } else if (readLen < 0) { |
Ka_myk | 0:6a6f97ca5572 | 92 | return RADIO_NOT_WORKING; |
Ka_myk | 0:6a6f97ca5572 | 93 | } |
Ka_myk | 0:6a6f97ca5572 | 94 | timeout *= 2; |
Ka_myk | 0:6a6f97ca5572 | 95 | } |
Ka_myk | 0:6a6f97ca5572 | 96 | return SERVER_TIMED_OUT; |
Ka_myk | 0:6a6f97ca5572 | 97 | } |
Ka_myk | 0:6a6f97ca5572 | 98 | |
Ka_myk | 0:6a6f97ca5572 | 99 | /* send post request to given uri of connected server |
Ka_myk | 0:6a6f97ca5572 | 100 | * |
Ka_myk | 0:6a6f97ca5572 | 101 | * @return 0 if operation has been completed successfully |
Ka_myk | 0:6a6f97ca5572 | 102 | * -1 if server responded ambiguously; |
Ka_myk | 0:6a6f97ca5572 | 103 | * -2 if server timed out; |
Ka_myk | 0:6a6f97ca5572 | 104 | * -4 if radio is not working properly |
Ka_myk | 0:6a6f97ca5572 | 105 | * */ |
Ka_myk | 0:6a6f97ca5572 | 106 | int CoapClient::post(uint8_t* buffer, int len, char* uri) { |
Ka_myk | 0:6a6f97ca5572 | 107 | CoapPDU coapPDU = CoapPDU(); |
Ka_myk | 0:6a6f97ca5572 | 108 | uint16_t messageId = preparePDU(coapPDU); |
Ka_myk | 0:6a6f97ca5572 | 109 | coapPDU.setCode(CoapPDU::COAP_POST); |
Ka_myk | 0:6a6f97ca5572 | 110 | |
Ka_myk | 0:6a6f97ca5572 | 111 | coapPDU.setURI(uri); |
Ka_myk | 0:6a6f97ca5572 | 112 | coapPDU.setPayload(buffer, len); |
Ka_myk | 0:6a6f97ca5572 | 113 | uint8_t returnBuffer[radioWrapper.packetSize()]; |
Ka_myk | 0:6a6f97ca5572 | 114 | int timeout = this->listeningTimeout; |
Ka_myk | 0:6a6f97ca5572 | 115 | for (int i = 0; i < this->retransmissionLimit; i++) { |
Ka_myk | 0:6a6f97ca5572 | 116 | |
Ka_myk | 0:6a6f97ca5572 | 117 | int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); |
Ka_myk | 0:6a6f97ca5572 | 118 | if (ret < 0) { |
Ka_myk | 0:6a6f97ca5572 | 119 | return RADIO_NOT_WORKING; |
Ka_myk | 0:6a6f97ca5572 | 120 | } |
Ka_myk | 0:6a6f97ca5572 | 121 | int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param |
Ka_myk | 0:6a6f97ca5572 | 122 | if (readLen > 0) { // if something is recieved process it |
Ka_myk | 0:6a6f97ca5572 | 123 | CoapPDU response(returnBuffer, len, readLen); |
Ka_myk | 0:6a6f97ca5572 | 124 | if (isAck(response, messageId, uri)) { |
Ka_myk | 0:6a6f97ca5572 | 125 | if (response.getCode() == CoapPDU::COAP_CREATED && |
Ka_myk | 0:6a6f97ca5572 | 126 | std::memcmp(response.getTokenPointer(), this->token, |
Ka_myk | 0:6a6f97ca5572 | 127 | static_cast<size_t>(response.getTokenLength())) == 0) { |
Ka_myk | 0:6a6f97ca5572 | 128 | return 0; |
Ka_myk | 0:6a6f97ca5572 | 129 | } else // if server hasn't responded properly |
Ka_myk | 0:6a6f97ca5572 | 130 | return SERVER_RESPONSE_AMBIGOUS; |
Ka_myk | 0:6a6f97ca5572 | 131 | } |
Ka_myk | 0:6a6f97ca5572 | 132 | } else if (readLen < 0) { |
Ka_myk | 0:6a6f97ca5572 | 133 | return RADIO_NOT_WORKING; |
Ka_myk | 0:6a6f97ca5572 | 134 | } |
Ka_myk | 0:6a6f97ca5572 | 135 | timeout *= 2; |
Ka_myk | 0:6a6f97ca5572 | 136 | } |
Ka_myk | 0:6a6f97ca5572 | 137 | return SERVER_TIMED_OUT; |
Ka_myk | 0:6a6f97ca5572 | 138 | } |
Ka_myk | 0:6a6f97ca5572 | 139 | |
Ka_myk | 0:6a6f97ca5572 | 140 | uint16_t CoapClient::preparePDU(CoapPDU& coapPDU) { |
Ka_myk | 0:6a6f97ca5572 | 141 | coapPDU.setVersion(1); |
Ka_myk | 0:6a6f97ca5572 | 142 | coapPDU.setType(CoapPDU::COAP_CONFIRMABLE); |
Ka_myk | 0:6a6f97ca5572 | 143 | coapPDU.setMessageID(this->message_counter); |
Ka_myk | 0:6a6f97ca5572 | 144 | coapPDU.setToken(this->token, 4); |
Ka_myk | 0:6a6f97ca5572 | 145 | return this->message_counter++; |
Ka_myk | 0:6a6f97ca5572 | 146 | } |
Ka_myk | 0:6a6f97ca5572 | 147 | |
Ka_myk | 1:1d936c763440 | 148 | CoapClient::CoapClient(uint8_t* token, int retransmissionLimit, int timeout, int channel, unsigned long long rx_address, unsigned long long tx_address) : |
Ka_myk | 1:1d936c763440 | 149 | listeningTimeout(timeout), retransmissionLimit(retransmissionLimit), radioWrapper(channel, rx_address, tx_address) { |
Ka_myk | 0:6a6f97ca5572 | 150 | std::memcpy(this->token, token, 4); |
Ka_myk | 0:6a6f97ca5572 | 151 | this->message_counter = 16; |
Ka_myk | 0:6a6f97ca5572 | 152 | } |