client version of coap

Dependencies:   nRF24L01P cantcoap3

Dependents:   client3

Committer:
Ka_myk
Date:
Fri Jan 25 12:10:49 2019 +0000
Revision:
5:d633e12f113f
Parent:
4:792cf53a73c4
all mains;

Who changed what in which revision?

UserRevisionLine numberNew 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 1:1d936c763440 5 #include "coapClient.h"
Ka_myk 2:e8823d9fa162 6 #include "dbg.h"
Ka_myk 0:6a6f97ca5572 7
Ka_myk 0:6a6f97ca5572 8 bool match_uri(CoapPDU& coapPDU, char* uri) {
Ka_myk 0:6a6f97ca5572 9 char respone_uri[32];
Ka_myk 0:6a6f97ca5572 10 int len = 0;
Ka_myk 0:6a6f97ca5572 11 coapPDU.getURI(respone_uri, 32, &len);
Ka_myk 0:6a6f97ca5572 12 return strcmp(uri, respone_uri) == 0;
Ka_myk 0:6a6f97ca5572 13 }
Ka_myk 0:6a6f97ca5572 14
Ka_myk 0:6a6f97ca5572 15
Ka_myk 1:1d936c763440 16 bool isExpectedResponse(CoapPDU& response, uint16_t message_id, char* uri) {
Ka_myk 0:6a6f97ca5572 17 return match_uri(response, uri) && response.getType() == CoapPDU::COAP_ACKNOWLEDGEMENT &&
Ka_myk 0:6a6f97ca5572 18 response.getMessageID() == message_id;
Ka_myk 0:6a6f97ca5572 19 }
Ka_myk 0:6a6f97ca5572 20
Ka_myk 1:1d936c763440 21 bool CoapClient::isAck(CoapPDU& response, uint16_t message_id, char* uri) {
Ka_myk 0:6a6f97ca5572 22 if (response.validate()) {
Ka_myk 4:792cf53a73c4 23 response.printHuman();
Ka_myk 5:d633e12f113f 24 DBG("WANNA: %d %s", message_id, uri);
Ka_myk 0:6a6f97ca5572 25 if (isExpectedResponse(response, message_id, uri)) {
Ka_myk 0:6a6f97ca5572 26 return true;
Ka_myk 0:6a6f97ca5572 27 }
Ka_myk 0:6a6f97ca5572 28 }
Ka_myk 0:6a6f97ca5572 29 return false;
Ka_myk 0:6a6f97ca5572 30 }
Ka_myk 0:6a6f97ca5572 31
Ka_myk 2:e8823d9fa162 32 bool CoapClient::hasGetResponse(CoapPDU& response) {
Ka_myk 2:e8823d9fa162 33 return std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0 &&
Ka_myk 2:e8823d9fa162 34 response.getCode() == CoapPDU::COAP_CONTENT;
Ka_myk 2:e8823d9fa162 35 }
Ka_myk 0:6a6f97ca5572 36
Ka_myk 2:e8823d9fa162 37 bool CoapClient::hasPostResponse(CoapPDU& response) {
Ka_myk 2:e8823d9fa162 38 return response.getCode() == CoapPDU::COAP_CREATED &&
Ka_myk 2:e8823d9fa162 39 std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0;
Ka_myk 0:6a6f97ca5572 40 }
Ka_myk 0:6a6f97ca5572 41
Ka_myk 2:e8823d9fa162 42
Ka_myk 0:6a6f97ca5572 43 /* send get request to given uri of connected server
Ka_myk 0:6a6f97ca5572 44 *
Ka_myk 0:6a6f97ca5572 45 * @return number of saved bytes in provided buffer or
Ka_myk 0:6a6f97ca5572 46 * -1 if server responded ambiguously;
Ka_myk 0:6a6f97ca5572 47 * -2 if server timed out;
Ka_myk 0:6a6f97ca5572 48 * -3 if provided buffer is to small to save response,
Ka_myk 0:6a6f97ca5572 49 * -4 if if radio is not functioning properly
Ka_myk 0:6a6f97ca5572 50 * */
Ka_myk 0:6a6f97ca5572 51 int CoapClient::get(uint8_t* buffer, int len, char* uri) {
Ka_myk 4:792cf53a73c4 52 Timer t;
Ka_myk 0:6a6f97ca5572 53 CoapPDU coapPDU = CoapPDU();
Ka_myk 0:6a6f97ca5572 54 uint16_t messageId = preparePDU(coapPDU);
Ka_myk 5:d633e12f113f 55 this->message_counter +=4;
Ka_myk 0:6a6f97ca5572 56 coapPDU.setCode(CoapPDU::COAP_GET);
Ka_myk 0:6a6f97ca5572 57 coapPDU.setURI(uri);
Ka_myk 0:6a6f97ca5572 58
Ka_myk 0:6a6f97ca5572 59 uint8_t returnBuffer[radioWrapper.packetSize()];
Ka_myk 4:792cf53a73c4 60 int TIMEOUT = this->listeningTimeout;
Ka_myk 4:792cf53a73c4 61 int timeout = TIMEOUT;
Ka_myk 0:6a6f97ca5572 62 for (int i = 0; i < this->retransmissionLimit; i++) {
Ka_myk 4:792cf53a73c4 63 while (timeout > 0) {
Ka_myk 4:792cf53a73c4 64 int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); // send empty payload to get uri
Ka_myk 4:792cf53a73c4 65 if (ret < 0) {
Ka_myk 4:792cf53a73c4 66 return RADIO_NOT_WORKING;
Ka_myk 4:792cf53a73c4 67 }
Ka_myk 4:792cf53a73c4 68 t.start();
Ka_myk 4:792cf53a73c4 69 int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param
Ka_myk 4:792cf53a73c4 70 t.stop();
Ka_myk 4:792cf53a73c4 71 timeout -= t.read_ms();
Ka_myk 4:792cf53a73c4 72 t.reset();
Ka_myk 4:792cf53a73c4 73 if (readLen > 0) { // if something is recieved process it
Ka_myk 4:792cf53a73c4 74 CoapPDU response(returnBuffer, len, readLen);
Ka_myk 4:792cf53a73c4 75 if (isAck(response, messageId, uri) && hasGetResponse(response)) {
Ka_myk 4:792cf53a73c4 76 DBG("RESPONSE: %d", readLen);
Ka_myk 4:792cf53a73c4 77 response.printHuman();
Ka_myk 4:792cf53a73c4 78 if (response.getPayloadLength() <= len) {
Ka_myk 4:792cf53a73c4 79 std::memcpy(buffer, response.getPayloadPointer(),
Ka_myk 4:792cf53a73c4 80 static_cast<size_t>(response.getPayloadLength()));
Ka_myk 4:792cf53a73c4 81 return response.getPayloadLength();
Ka_myk 4:792cf53a73c4 82 } else {
Ka_myk 4:792cf53a73c4 83 return SMALL_BUFFER;
Ka_myk 4:792cf53a73c4 84 }
Ka_myk 4:792cf53a73c4 85 } else {
Ka_myk 4:792cf53a73c4 86 DBG("NIEMOJE");
Ka_myk 4:792cf53a73c4 87 DBG("PAYLOAD: %s", response.getPayloadPointer());
Ka_myk 4:792cf53a73c4 88 continue;
Ka_myk 4:792cf53a73c4 89 }
Ka_myk 4:792cf53a73c4 90 } else if (readLen < 0) {
Ka_myk 4:792cf53a73c4 91 return RADIO_NOT_WORKING;
Ka_myk 4:792cf53a73c4 92 }
Ka_myk 0:6a6f97ca5572 93 }
Ka_myk 4:792cf53a73c4 94 TIMEOUT *= 2;
Ka_myk 4:792cf53a73c4 95 timeout = TIMEOUT;
Ka_myk 0:6a6f97ca5572 96 }
Ka_myk 2:e8823d9fa162 97
Ka_myk 2:e8823d9fa162 98 return
Ka_myk 2:e8823d9fa162 99 SERVER_TIMED_OUT;
Ka_myk 0:6a6f97ca5572 100 }
Ka_myk 0:6a6f97ca5572 101
Ka_myk 0:6a6f97ca5572 102 /* send post request to given uri of connected server
Ka_myk 0:6a6f97ca5572 103 *
Ka_myk 0:6a6f97ca5572 104 * @return 0 if operation has been completed successfully
Ka_myk 0:6a6f97ca5572 105 * -1 if server responded ambiguously;
Ka_myk 0:6a6f97ca5572 106 * -2 if server timed out;
Ka_myk 0:6a6f97ca5572 107 * -4 if radio is not working properly
Ka_myk 0:6a6f97ca5572 108 * */
Ka_myk 0:6a6f97ca5572 109 int CoapClient::post(uint8_t* buffer, int len, char* uri) {
Ka_myk 4:792cf53a73c4 110 Timer t;
Ka_myk 0:6a6f97ca5572 111 CoapPDU coapPDU = CoapPDU();
Ka_myk 0:6a6f97ca5572 112 uint16_t messageId = preparePDU(coapPDU);
Ka_myk 5:d633e12f113f 113 this->message_counter +=4;
Ka_myk 0:6a6f97ca5572 114 coapPDU.setCode(CoapPDU::COAP_POST);
Ka_myk 0:6a6f97ca5572 115
Ka_myk 0:6a6f97ca5572 116 coapPDU.setURI(uri);
Ka_myk 0:6a6f97ca5572 117 coapPDU.setPayload(buffer, len);
Ka_myk 0:6a6f97ca5572 118 uint8_t returnBuffer[radioWrapper.packetSize()];
Ka_myk 4:792cf53a73c4 119 int TIMEOUT = this->listeningTimeout;
Ka_myk 4:792cf53a73c4 120 int timeout = TIMEOUT;
Ka_myk 0:6a6f97ca5572 121 for (int i = 0; i < this->retransmissionLimit; i++) {
Ka_myk 4:792cf53a73c4 122 while(timeout > 0) {
Ka_myk 4:792cf53a73c4 123 int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength());
Ka_myk 4:792cf53a73c4 124 if (ret < 0) {
Ka_myk 4:792cf53a73c4 125 return RADIO_NOT_WORKING;
Ka_myk 4:792cf53a73c4 126 }
Ka_myk 4:792cf53a73c4 127 t.start();
Ka_myk 4:792cf53a73c4 128 int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param
Ka_myk 4:792cf53a73c4 129 t.stop();
Ka_myk 4:792cf53a73c4 130 timeout -= t.read_ms();
Ka_myk 4:792cf53a73c4 131 t.reset();
Ka_myk 4:792cf53a73c4 132 if (readLen > 0) { // if something is recieved process it
Ka_myk 4:792cf53a73c4 133 CoapPDU response(returnBuffer, len, readLen);
Ka_myk 4:792cf53a73c4 134 if (isAck(response, messageId, uri) && hasPostResponse(response)) {
Ka_myk 4:792cf53a73c4 135 return 0;
Ka_myk 4:792cf53a73c4 136 } else { // if server hasn't responded properly
Ka_myk 4:792cf53a73c4 137 DBG("NIEMOJE");
Ka_myk 4:792cf53a73c4 138 DBG("PAYLOAD: %s", response.getPayloadPointer());
Ka_myk 4:792cf53a73c4 139 continue;
Ka_myk 4:792cf53a73c4 140 }
Ka_myk 4:792cf53a73c4 141 } else if (readLen < 0) {
Ka_myk 4:792cf53a73c4 142 return RADIO_NOT_WORKING;
Ka_myk 4:792cf53a73c4 143 }
Ka_myk 0:6a6f97ca5572 144 }
Ka_myk 4:792cf53a73c4 145 TIMEOUT *= 2;
Ka_myk 4:792cf53a73c4 146 timeout = TIMEOUT;
Ka_myk 0:6a6f97ca5572 147 }
Ka_myk 0:6a6f97ca5572 148 return SERVER_TIMED_OUT;
Ka_myk 0:6a6f97ca5572 149 }
Ka_myk 0:6a6f97ca5572 150
Ka_myk 0:6a6f97ca5572 151 uint16_t CoapClient::preparePDU(CoapPDU& coapPDU) {
Ka_myk 0:6a6f97ca5572 152 coapPDU.setVersion(1);
Ka_myk 0:6a6f97ca5572 153 coapPDU.setType(CoapPDU::COAP_CONFIRMABLE);
Ka_myk 0:6a6f97ca5572 154 coapPDU.setMessageID(this->message_counter);
Ka_myk 2:e8823d9fa162 155 coapPDU.setToken(this->token, 1);
Ka_myk 5:d633e12f113f 156 return this->message_counter;
Ka_myk 0:6a6f97ca5572 157 }
Ka_myk 0:6a6f97ca5572 158
Ka_myk 5:d633e12f113f 159 CoapClient::CoapClient(uint16_t counter, uint8_t* token, int retransmissionLimit, int timeout, int channel, unsigned long long rx_address,
Ka_myk 5:d633e12f113f 160 unsigned long long tx_address):
Ka_myk 2:e8823d9fa162 161 listeningTimeout(timeout), retransmissionLimit(retransmissionLimit),
Ka_myk 5:d633e12f113f 162 radioWrapper(channel, rx_address, tx_address), message_counter(counter) {
Ka_myk 2:e8823d9fa162 163 std::memcpy(this->token, token, 1);
Ka_myk 4:792cf53a73c4 164 }