Coap Client and Server
Dependencies: DebugLib EthernetInterface cantcoap mbed-rtos
Fork of yeswecancoap by
YesWeCanCoap
Is a small coap client and server library for mbed based on the cantcoap library.
Import librarycantcoap
This is CoAP library with a focus on simplicity. It offers minimal CoAP PDU construction and decoding to and from byte buffers.
yeswecancoap server enables easy implementation of coap resources, each with a dedicated function. When the function is registered by the server, it will do the rest.
Coap server example
Repository: YesWeCanCoap-example
Coap client example
under construction
client.cpp
- Committer:
- sillevl
- Date:
- 2015-11-17
- Revision:
- 29:62113a57353b
- Parent:
- 19:6414961fb98d
File content as of revision 29:62113a57353b:
#include "client.h" #include "response.h" #include "request.h" // Identifier is some trivial string used for console output Client::Client(const char * server, const int port, std::string identifier) { udp_socket.init(); udp_socket.set_blocking(false, 1000); new_token_id = 0; coap_server.set_address(server, port); this->identifier = identifier; new_message_id = 0; } // Respons handler can be left null if no content respons is expected void Client::sendRequest(char* uri, void (*response_handler)(Request*, Response*), CoapPDU::Code method) { CoapPDU *req_pdu = new CoapPDU(); switch (method) { case CoapPDU::COAP_GET: req_pdu->setType(CoapPDU::COAP_CONFIRMABLE); break; case CoapPDU::COAP_POST: req_pdu->setType(CoapPDU::COAP_CONFIRMABLE); break; } req_pdu->setCode(method); req_pdu->setMessageID(new_message_id++); new_token_id++; req_pdu->setToken((uint8_t *)&new_token_id, sizeof(new_token_id)); req_pdu->setURI(uri, strlen(uri)); unsigned int retries = 5; while (retries > 0 && udp_socket.sendTo(coap_server, (char *)(req_pdu->getPDUPointer()), req_pdu->getPDULength()) < 0) { retries--; } if (retries == 0) { printf("UDP socket problem - Could not send PDU\r\n"); return; } else { if (method == CoapPDU::COAP_GET) { // Or confirmable ... // We need to save request and wait for respons of server ResourceRequest req = { new_token_id, uri, response_handler, method, req_pdu }; requests.push_back(req); } } } void Client::checkForResponse(void) { if (requests.size() > 0) { // responses still need to be received char buffer[256]; // printf("\r\nChecking for response UDP packet...\r\n"); // Check for udp packet from endpoint int size = udp_socket.receiveFrom(coap_server, buffer, sizeof(buffer)-1); if (size > 0) { buffer[size] = '\0'; char uriBuffer[32]; int recvURILen; int msgId; uint32_t token; // Lets coap CoapPDU *recvPDU = new CoapPDU((uint8_t*)buffer, 256, size); if(recvPDU->validate()) { recvPDU->getURI(uriBuffer, 32, &recvURILen); msgId = recvPDU->getMessageID(); // Parse token if (recvPDU->getTokenLength() == sizeof(new_token_id)) { token = *((uint32_t*)recvPDU->getTokenPointer()); } else if (recvPDU->getTokenLength() == 0) { // Server does not care about tokens ? // Then we force to match with first request token = requests[0].token_id; } else { printf("Invalid token length\r\n"); delete recvPDU; return; } } else { printf("Invalid Coap PDU received\r\n"); recvPDU->printHuman(); delete recvPDU; return; } // Check for which request the response is meant int i = 0; while (i < requests.size() && requests[i].token_id != token) { i++; } if (i < requests.size()) { // Found // [TODO] Here we should check if it's not a premature ACK !!!!!! // Call handler if one exists if (requests[i].response_handler) { requests[i].response_handler((Request*)(requests[i].req_pdu), (Response*)recvPDU); } delete requests[i].req_pdu; requests.erase(requests.begin() + i); } else { printf("Respons for unknown request\r\n"); recvPDU->printHuman(); } delete recvPDU; } } }