client version of coap
Dependencies: nRF24L01P cantcoap3
coapClient.cpp
00001 // 00002 // Created by Kamil Mykitiuk on 2019-01-17. 00003 // 00004 00005 #include "coapClient.h" 00006 #include "dbg.h" 00007 00008 bool match_uri(CoapPDU& coapPDU, char* uri) { 00009 char respone_uri[32]; 00010 int len = 0; 00011 coapPDU.getURI(respone_uri, 32, &len); 00012 return strcmp(uri, respone_uri) == 0; 00013 } 00014 00015 00016 bool isExpectedResponse(CoapPDU& response, uint16_t message_id, char* uri) { 00017 return match_uri(response, uri) && response.getType() == CoapPDU::COAP_ACKNOWLEDGEMENT && 00018 response.getMessageID() == message_id; 00019 } 00020 00021 bool CoapClient::isAck(CoapPDU& response, uint16_t message_id, char* uri) { 00022 if (response.validate()) { 00023 response.printHuman(); 00024 DBG("WANNA: %d %s", message_id, uri); 00025 if (isExpectedResponse(response, message_id, uri)) { 00026 return true; 00027 } 00028 } 00029 return false; 00030 } 00031 00032 bool CoapClient::hasGetResponse(CoapPDU& response) { 00033 return std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0 && 00034 response.getCode() == CoapPDU::COAP_CONTENT; 00035 } 00036 00037 bool CoapClient::hasPostResponse(CoapPDU& response) { 00038 return response.getCode() == CoapPDU::COAP_CREATED && 00039 std::memcmp(response.getTokenPointer(), this->token, static_cast<size_t>(response.getTokenLength())) == 0; 00040 } 00041 00042 00043 /* send get request to given uri of connected server 00044 * 00045 * @return number of saved bytes in provided buffer or 00046 * -1 if server responded ambiguously; 00047 * -2 if server timed out; 00048 * -3 if provided buffer is to small to save response, 00049 * -4 if if radio is not functioning properly 00050 * */ 00051 int CoapClient::get(uint8_t* buffer, int len, char* uri) { 00052 Timer t; 00053 CoapPDU coapPDU = CoapPDU(); 00054 uint16_t messageId = preparePDU(coapPDU); 00055 this->message_counter +=4; 00056 coapPDU.setCode(CoapPDU::COAP_GET); 00057 coapPDU.setURI(uri); 00058 00059 uint8_t returnBuffer[radioWrapper.packetSize()]; 00060 int TIMEOUT = this->listeningTimeout; 00061 int timeout = TIMEOUT; 00062 for (int i = 0; i < this->retransmissionLimit; i++) { 00063 while (timeout > 0) { 00064 int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); // send empty payload to get uri 00065 if (ret < 0) { 00066 return RADIO_NOT_WORKING; 00067 } 00068 t.start(); 00069 int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param 00070 t.stop(); 00071 timeout -= t.read_ms(); 00072 t.reset(); 00073 if (readLen > 0) { // if something is recieved process it 00074 CoapPDU response(returnBuffer, len, readLen); 00075 if (isAck(response, messageId, uri) && hasGetResponse(response)) { 00076 DBG("RESPONSE: %d", readLen); 00077 response.printHuman(); 00078 if (response.getPayloadLength() <= len) { 00079 std::memcpy(buffer, response.getPayloadPointer(), 00080 static_cast<size_t>(response.getPayloadLength())); 00081 return response.getPayloadLength(); 00082 } else { 00083 return SMALL_BUFFER; 00084 } 00085 } else { 00086 DBG("NIEMOJE"); 00087 DBG("PAYLOAD: %s", response.getPayloadPointer()); 00088 continue; 00089 } 00090 } else if (readLen < 0) { 00091 return RADIO_NOT_WORKING; 00092 } 00093 } 00094 TIMEOUT *= 2; 00095 timeout = TIMEOUT; 00096 } 00097 00098 return 00099 SERVER_TIMED_OUT; 00100 } 00101 00102 /* send post request to given uri of connected server 00103 * 00104 * @return 0 if operation has been completed successfully 00105 * -1 if server responded ambiguously; 00106 * -2 if server timed out; 00107 * -4 if radio is not working properly 00108 * */ 00109 int CoapClient::post(uint8_t* buffer, int len, char* uri) { 00110 Timer t; 00111 CoapPDU coapPDU = CoapPDU(); 00112 uint16_t messageId = preparePDU(coapPDU); 00113 this->message_counter +=4; 00114 coapPDU.setCode(CoapPDU::COAP_POST); 00115 00116 coapPDU.setURI(uri); 00117 coapPDU.setPayload(buffer, len); 00118 uint8_t returnBuffer[radioWrapper.packetSize()]; 00119 int TIMEOUT = this->listeningTimeout; 00120 int timeout = TIMEOUT; 00121 for (int i = 0; i < this->retransmissionLimit; i++) { 00122 while(timeout > 0) { 00123 int ret = radioWrapper.write(coapPDU.getPDUPointer(), coapPDU.getPDULength()); 00124 if (ret < 0) { 00125 return RADIO_NOT_WORKING; 00126 } 00127 t.start(); 00128 int readLen = radioWrapper.read(returnBuffer, radioWrapper.packetSize(), timeout); // add timeout param 00129 t.stop(); 00130 timeout -= t.read_ms(); 00131 t.reset(); 00132 if (readLen > 0) { // if something is recieved process it 00133 CoapPDU response(returnBuffer, len, readLen); 00134 if (isAck(response, messageId, uri) && hasPostResponse(response)) { 00135 return 0; 00136 } else { // if server hasn't responded properly 00137 DBG("NIEMOJE"); 00138 DBG("PAYLOAD: %s", response.getPayloadPointer()); 00139 continue; 00140 } 00141 } else if (readLen < 0) { 00142 return RADIO_NOT_WORKING; 00143 } 00144 } 00145 TIMEOUT *= 2; 00146 timeout = TIMEOUT; 00147 } 00148 return SERVER_TIMED_OUT; 00149 } 00150 00151 uint16_t CoapClient::preparePDU(CoapPDU& coapPDU) { 00152 coapPDU.setVersion(1); 00153 coapPDU.setType(CoapPDU::COAP_CONFIRMABLE); 00154 coapPDU.setMessageID(this->message_counter); 00155 coapPDU.setToken(this->token, 1); 00156 return this->message_counter; 00157 } 00158 00159 CoapClient::CoapClient(uint16_t counter, uint8_t* token, int retransmissionLimit, int timeout, int channel, unsigned long long rx_address, 00160 unsigned long long tx_address): 00161 listeningTimeout(timeout), retransmissionLimit(retransmissionLimit), 00162 radioWrapper(channel, rx_address, tx_address), message_counter(counter) { 00163 std::memcpy(this->token, token, 1); 00164 }
Generated on Wed Jul 13 2022 02:51:40 by 1.7.2