Coap Client and Server

Dependencies:   DebugLib EthernetInterface cantcoap mbed-rtos

Dependents:   COAP coap

Fork of yeswecancoap by Sille Van Landschoot

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

Committer:
sillevl
Date:
Tue Nov 17 16:44:39 2015 +0000
Revision:
29:62113a57353b
Parent:
19:6414961fb98d
added method to get the ip address

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dwini 8:0169da22e764 1 #include "client.h"
dwini 10:77bd145ec06c 2 #include "response.h"
dwini 10:77bd145ec06c 3 #include "request.h"
dwini 8:0169da22e764 4
dwini 8:0169da22e764 5 // Identifier is some trivial string used for console output
dwini 8:0169da22e764 6 Client::Client(const char * server, const int port, std::string identifier) {
dwini 8:0169da22e764 7 udp_socket.init();
dwini 8:0169da22e764 8 udp_socket.set_blocking(false, 1000);
dwini 8:0169da22e764 9 new_token_id = 0;
dwini 8:0169da22e764 10 coap_server.set_address(server, port);
dwini 8:0169da22e764 11 this->identifier = identifier;
dwini 8:0169da22e764 12 new_message_id = 0;
dwini 8:0169da22e764 13 }
dwini 8:0169da22e764 14
dwini 8:0169da22e764 15 // Respons handler can be left null if no content respons is expected
dwini 19:6414961fb98d 16 void Client::sendRequest(char* uri, void (*response_handler)(Request*, Response*), CoapPDU::Code method) {
dwini 8:0169da22e764 17
dwini 8:0169da22e764 18 CoapPDU *req_pdu = new CoapPDU();
dwini 8:0169da22e764 19
dwini 8:0169da22e764 20 switch (method) {
dwini 19:6414961fb98d 21 case CoapPDU::COAP_GET:
dwini 8:0169da22e764 22 req_pdu->setType(CoapPDU::COAP_CONFIRMABLE);
dwini 19:6414961fb98d 23 break;
dwini 19:6414961fb98d 24 case CoapPDU::COAP_POST:
dwini 19:6414961fb98d 25 req_pdu->setType(CoapPDU::COAP_CONFIRMABLE);
dwini 8:0169da22e764 26 break;
dwini 8:0169da22e764 27 }
dwini 19:6414961fb98d 28 req_pdu->setCode(method);
dwini 8:0169da22e764 29 req_pdu->setMessageID(new_message_id++);
dwini 14:ce76110ecf4d 30 new_token_id++;
dwini 14:ce76110ecf4d 31 req_pdu->setToken((uint8_t *)&new_token_id, sizeof(new_token_id));
dwini 8:0169da22e764 32 req_pdu->setURI(uri, strlen(uri));
dwini 8:0169da22e764 33
dwini 8:0169da22e764 34 unsigned int retries = 5;
dwini 8:0169da22e764 35 while (retries > 0 && udp_socket.sendTo(coap_server, (char *)(req_pdu->getPDUPointer()), req_pdu->getPDULength()) < 0) {
dwini 8:0169da22e764 36 retries--;
dwini 8:0169da22e764 37 }
dwini 8:0169da22e764 38
dwini 8:0169da22e764 39 if (retries == 0) {
dwini 8:0169da22e764 40 printf("UDP socket problem - Could not send PDU\r\n");
dwini 8:0169da22e764 41 return;
dwini 8:0169da22e764 42 } else {
dwini 19:6414961fb98d 43 if (method == CoapPDU::COAP_GET) { // Or confirmable ...
dwini 8:0169da22e764 44 // We need to save request and wait for respons of server
sillevl 13:6667e331c719 45 ResourceRequest req = { new_token_id, uri, response_handler, method, req_pdu };
dwini 8:0169da22e764 46 requests.push_back(req);
dwini 8:0169da22e764 47 }
dwini 8:0169da22e764 48 }
dwini 8:0169da22e764 49 }
dwini 8:0169da22e764 50
dwini 8:0169da22e764 51 void Client::checkForResponse(void) {
dwini 8:0169da22e764 52
dwini 8:0169da22e764 53 if (requests.size() > 0) { // responses still need to be received
dwini 8:0169da22e764 54
dwini 8:0169da22e764 55 char buffer[256];
dwini 8:0169da22e764 56 // printf("\r\nChecking for response UDP packet...\r\n");
dwini 8:0169da22e764 57
dwini 8:0169da22e764 58 // Check for udp packet from endpoint
dwini 8:0169da22e764 59 int size = udp_socket.receiveFrom(coap_server, buffer, sizeof(buffer)-1);
dwini 8:0169da22e764 60 if (size > 0) {
dwini 8:0169da22e764 61 buffer[size] = '\0';
dwini 8:0169da22e764 62
dwini 8:0169da22e764 63 char uriBuffer[32];
dwini 8:0169da22e764 64 int recvURILen;
dwini 8:0169da22e764 65 int msgId;
dwini 8:0169da22e764 66 uint32_t token;
dwini 8:0169da22e764 67
dwini 8:0169da22e764 68 // Lets coap
dwini 8:0169da22e764 69 CoapPDU *recvPDU = new CoapPDU((uint8_t*)buffer, 256, size);
dwini 8:0169da22e764 70 if(recvPDU->validate()) {
dwini 8:0169da22e764 71 recvPDU->getURI(uriBuffer, 32, &recvURILen);
dwini 8:0169da22e764 72 msgId = recvPDU->getMessageID();
dwini 8:0169da22e764 73
dwini 8:0169da22e764 74 // Parse token
dwini 8:0169da22e764 75 if (recvPDU->getTokenLength() == sizeof(new_token_id)) {
dwini 8:0169da22e764 76 token = *((uint32_t*)recvPDU->getTokenPointer());
dwini 8:0169da22e764 77 } else if (recvPDU->getTokenLength() == 0) { // Server does not care about tokens ?
dwini 8:0169da22e764 78 // Then we force to match with first request
dwini 8:0169da22e764 79 token = requests[0].token_id;
dwini 8:0169da22e764 80 } else {
dwini 8:0169da22e764 81 printf("Invalid token length\r\n");
dwini 8:0169da22e764 82 delete recvPDU;
dwini 8:0169da22e764 83 return;
dwini 8:0169da22e764 84 }
dwini 8:0169da22e764 85 } else {
dwini 8:0169da22e764 86 printf("Invalid Coap PDU received\r\n");
dwini 8:0169da22e764 87 recvPDU->printHuman();
dwini 8:0169da22e764 88 delete recvPDU;
dwini 8:0169da22e764 89 return;
dwini 8:0169da22e764 90 }
dwini 8:0169da22e764 91
dwini 8:0169da22e764 92 // Check for which request the response is meant
dwini 8:0169da22e764 93 int i = 0;
dwini 8:0169da22e764 94 while (i < requests.size() && requests[i].token_id != token) {
dwini 8:0169da22e764 95 i++;
dwini 8:0169da22e764 96 }
dwini 8:0169da22e764 97
dwini 8:0169da22e764 98 if (i < requests.size()) { // Found
dwini 8:0169da22e764 99 // [TODO] Here we should check if it's not a premature ACK !!!!!!
dwini 8:0169da22e764 100
dwini 8:0169da22e764 101 // Call handler if one exists
dwini 8:0169da22e764 102 if (requests[i].response_handler) {
dwini 10:77bd145ec06c 103 requests[i].response_handler((Request*)(requests[i].req_pdu), (Response*)recvPDU);
dwini 8:0169da22e764 104 }
dwini 8:0169da22e764 105
dwini 8:0169da22e764 106 delete requests[i].req_pdu;
dwini 8:0169da22e764 107 requests.erase(requests.begin() + i);
dwini 8:0169da22e764 108 } else {
dwini 8:0169da22e764 109 printf("Respons for unknown request\r\n");
dwini 8:0169da22e764 110 recvPDU->printHuman();
dwini 8:0169da22e764 111 }
dwini 8:0169da22e764 112
dwini 8:0169da22e764 113 delete recvPDU;
dwini 8:0169da22e764 114 }
dwini 8:0169da22e764 115 }
dwini 8:0169da22e764 116 }