Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DebugLib EthernetInterface cantcoap mbed-rtos
Fork of yeswecancoap by
Revision 9:b13b9ec63874, committed 2015-10-21
- Comitter:
- dwini
- Date:
- Wed Oct 21 11:27:22 2015 +0000
- Parent:
- 7:1bed29e1b0a4
- Parent:
- 8:0169da22e764
- Child:
- 10:77bd145ec06c
- Commit message:
- Merge with first implementation of client
Changed in this revision
--- a/EthernetInterface.lib Wed Oct 21 10:23:21 2015 +0000 +++ b/EthernetInterface.lib Wed Oct 21 11:27:22 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/EthernetInterface/#097a9996f8d5 +http://mbed.org/users/mbed_official/code/EthernetInterface/#2fc406e2553f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client.cpp Wed Oct 21 11:27:22 2015 +0000
@@ -0,0 +1,110 @@
+#include "client.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)(CoapPDU*, CoapPDU*), Method method) {
+
+ CoapPDU *req_pdu = new CoapPDU();
+
+ switch (method) {
+ case GET:
+ req_pdu->setType(CoapPDU::COAP_CONFIRMABLE);
+ req_pdu->setCode(CoapPDU::COAP_GET);
+ break;
+ }
+ req_pdu->setMessageID(new_message_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 == 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(requests[i].req_pdu, recvPDU);
+ }
+
+ delete requests[i].req_pdu;
+ requests.erase(requests.begin() + i);
+ } else {
+ printf("Respons for unknown request\r\n");
+ recvPDU->printHuman();
+ }
+
+ delete recvPDU;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client.h Wed Oct 21 11:27:22 2015 +0000
@@ -0,0 +1,48 @@
+#pragma once
+
+/*
+Waarom client per server
+Ten eerste moeten van een repons dan niet bepalen voor welke request hij juist was.
+Alles dat voor een bepaalde client / socket toekomt is voor die client.
+Dat betekent ook dat we niet eeuwig moeten wachten op een respons maar dat we async
+kunnen werken en werken met timeouts. We overlopen dan gewoon constant de clients die nog
+geen respons hebben gekregen.
+*/
+
+#include <string>
+#include <vector>
+#include "cantcoap.h"
+#include "coap.h"
+
+enum Method;
+
+class Client {
+
+ private:
+ // ResourceRequest holding info of previous request
+ struct ResourceRequest{
+ uint32_t token_id;
+ char* uri;
+ void (*response_handler)(CoapPDU*, CoapPDU*); // Not sure if we need request and respons PDU's
+ int method;
+ CoapPDU * req_pdu;
+ };
+
+ private:
+ UDPSocket udp_socket;
+ Endpoint coap_server; // One client per endpoint
+ uint32_t new_token_id; // Matches requests and responses
+ uint16_t new_message_id;
+ std::string identifier; // Identifier is some trivial string used for console output
+
+ // List of unhandled previous requests
+ std::vector<ResourceRequest> requests;
+
+ public:
+ Client(const char * server, const int port, std::string identifier="Client");
+
+ public:
+ void sendRequest(char* uri, void (*response_handler)(CoapPDU*, CoapPDU*), Method method);
+ void checkForResponse(void);
+
+};
\ No newline at end of file
--- a/coap.h Wed Oct 21 10:23:21 2015 +0000
+++ b/coap.h Wed Oct 21 11:27:22 2015 +0000
@@ -6,6 +6,7 @@
#include "dbg.h"
#include "server.h"
+#include "client.h"
enum Method {GET, POST, PUT, DELETE};
--- a/mbed-rtos.lib Wed Oct 21 10:23:21 2015 +0000 +++ b/mbed-rtos.lib Wed Oct 21 11:27:22 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed-rtos/#5dfe422a963d +http://mbed.org/users/mbed_official/code/mbed-rtos/#12552ef4e980
