From 0fb0149d9dda2a1da519f782155176004d73c9a1 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 16:56:48 +0200 Subject: [PATCH 1/5] CoapClient - Made `address` package-accessible CoapMessagingLayer - Added `getEndpointAddress()` which returns the associated `CoapClient`'s address --- source/doap/client/client.d | 2 +- source/doap/client/messaging.d | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/doap/client/client.d b/source/doap/client/client.d index 35a7c83..6f0d78d 100644 --- a/source/doap/client/client.d +++ b/source/doap/client/client.d @@ -17,7 +17,7 @@ public class CoapClient /** * CoAP server endpoint */ - private Address address; + package Address address; /** * Running status diff --git a/source/doap/client/messaging.d b/source/doap/client/messaging.d index f27f1fa..2c13d70 100644 --- a/source/doap/client/messaging.d +++ b/source/doap/client/messaging.d @@ -11,6 +11,7 @@ import doap.client.request : CoapRequest; import std.stdio; import std.socket : Socket, SocketSet; +import std.socket : Address; // TODO: Generalize this and then make // ... a UDP version of it @@ -42,6 +43,11 @@ class CoapMessagingLayer : Thread this.client = client; } + public final Address getEndpointAddress() + { + return this.client.address; + } + /** * Reading loop which reads datagrams * from the socket From 76feaade27cb9a65eed41acfaee87af0a390dbd1 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 16:57:39 +0200 Subject: [PATCH 2/5] CoapMessagingLayer - Made `getEndpointAddress()` protected - Added documentation for `getEndpointAddress()` --- source/doap/client/messaging.d | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/doap/client/messaging.d b/source/doap/client/messaging.d index 2c13d70..cd26434 100644 --- a/source/doap/client/messaging.d +++ b/source/doap/client/messaging.d @@ -43,7 +43,13 @@ class CoapMessagingLayer : Thread this.client = client; } - public final Address getEndpointAddress() + /** + * Retrieves the CoAP endpoint the client is + * connected to + * + * Returns: the endpoint address + */ + protected final Address getEndpointAddress() { return this.client.address; } From 0c81ce635f4e8bcd5a7c414f4e099a301773b8c0 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 17:19:38 +0200 Subject: [PATCH 3/5] CoapClient - Removed the `Socket` instance - `init()` now calls `begin()` on the messaging layer and no longer creates a new `Socket` itself - `close()` now just calls `close()` on the messaging layer - `transmitRequest(CoapRequest)` now calls `send(CoapPacket)` on the messaging layer instead of via a socket's `send(ubyte[])` CoapMessagingLayer - Added a `running` flag - Added `begin()` which sets the running flag (ours) to `true`, it then creates and opens a `Socket` and then starts the reading loop - Added `send(CoapPacket)` whcih wire-encoded the packet and then sends it over our `Socket` - Added `close()` which sets the running flag to false, shutsdown the `Socket` (unblocking any blocking receives) and then closes the `Socket` (releasing the bound datagram port) - Removed references to the `CoapClient`'s now-non-existent `Socket` --- source/doap/client/client.d | 25 +++------------ source/doap/client/messaging.d | 58 ++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/source/doap/client/client.d b/source/doap/client/client.d index 6f0d78d..df3232c 100644 --- a/source/doap/client/client.d +++ b/source/doap/client/client.d @@ -24,13 +24,6 @@ public class CoapClient */ package bool running; - /** - * The datagram socket - * - * TODO: Move this into the messaging layer - */ - package Socket socket; - /** * The messaging layer which provides * request-response message match-ups @@ -94,18 +87,11 @@ public class CoapClient */ private void init() { - // TODO: IF connect fails then don't start messaging - this.socket = new Socket(this.address.addressFamily(), SocketType.DGRAM, ProtocolType.UDP); - // this.socket.blocking(true); - this.socket.connect(address); - // Set status to running this.running = true; - - // Start the messaging layer - this.messaging.start(); + this.messaging.begin(); } /** @@ -121,11 +107,8 @@ public class CoapClient // Set status to not running this.running = false; - // Shutdown the socket (stopping the messaging layer) - this.socket.shutdown(SocketShutdown.BOTH); - - // Unbind (disallow incoming datagrams to source port (from device)) - this.socket.close(); + // Shutdown the messaging layer + this.messaging.close(); // TODO: We must wake up other sleeprs with an error // (somehow, pass it in, flag set) @@ -229,7 +212,7 @@ public class CoapClient private void transmitRequest(CoapRequest request) { // Encode the request packet and send it - this.socket.send(request.getRequestPacket().getBytes()); + this.messaging.send(request.getRequestPacket()); // Now start ticking the timer request.startTime(); diff --git a/source/doap/client/messaging.d b/source/doap/client/messaging.d index cd26434..2f13977 100644 --- a/source/doap/client/messaging.d +++ b/source/doap/client/messaging.d @@ -13,6 +13,8 @@ import std.stdio; import std.socket : Socket, SocketSet; import std.socket : Address; +import std.socket : Socket, Address, SocketType, ProtocolType, getAddress, parseAddress, InternetAddress, SocketShutdown; + // TODO: Generalize this and then make // ... a UDP version of it @@ -30,6 +32,16 @@ class CoapMessagingLayer : Thread */ private CoapClient client; + /** + * Running status + */ + private bool running; + + /** + * The datagram socket + */ + private Socket socket; + /** * Constructs a new messaging layer instance * associated with the provided client @@ -49,11 +61,51 @@ class CoapMessagingLayer : Thread * * Returns: the endpoint address */ - protected final Address getEndpointAddress() + protected final Address getEndpointAddress() // Final in Interface { return this.client.address; } + public void begin() // Candidate for Interface + { + // TODO: Handle socket errors nicely? + + // Set status to running + this.running = true; + + + // TODO: IF connect fails then don't start messaging + this.socket = new Socket(getEndpointAddress().addressFamily(), SocketType.DGRAM, ProtocolType.UDP); + // this.socket.blocking(true); + this.socket.connect(getEndpointAddress()); + + + // Start the thread (TODO: In future hide threading) + this.start(); + } + + public void send(CoapPacket packet) // Candidate for Interface + { + // Encode the packet and send the bytes + ubyte[] encodedPacket = packet.getBytes(); + this.socket.send(encodedPacket); + } + + public void close() // Candidate for Interface + { + // Set status to not running + this.running = false; + + // Shutdown the socket (stopping the messaging layer) + this.socket.shutdown(SocketShutdown.BOTH); + + // Unbind (disallow incoming datagrams to source port (from device)) + this.socket.close(); + + // Wait till the reading-loop thread exits + this.join(); + } + /** * Reading loop which reads datagrams * from the socket @@ -101,13 +153,13 @@ class CoapMessagingLayer : Thread SocketFlags flags = cast(SocketFlags)(SocketFlags.PEEK | MSG_TRUNC); byte[] data; data.length = 1; // At least one else never does underlying recv() - ptrdiff_t dgramSize = client.socket.receive(data, flags); + ptrdiff_t dgramSize = this.socket.receive(data, flags); // If we have received something then dequeue it of the peeked length if(dgramSize > 0) { data.length = dgramSize; - client.socket.receive(data); + this.socket.receive(data); writeln("received size: ", dgramSize); writeln("received bytes: ", data); From 3dc5fe4febb34c8b821dadf8ef1772290bd69c22 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 17:24:28 +0200 Subject: [PATCH 4/5] CoapMessagingLayer - Added a TODO --- source/doap/client/messaging.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/doap/client/messaging.d b/source/doap/client/messaging.d index 2f13977..d31c022 100644 --- a/source/doap/client/messaging.d +++ b/source/doap/client/messaging.d @@ -35,7 +35,7 @@ class CoapMessagingLayer : Thread /** * Running status */ - private bool running; + private bool running; // TODO: Check volatility /** * The datagram socket From 114e780be5defaad49a3a06fa8042e88d782531f Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Fri, 22 Sep 2023 17:36:45 +0200 Subject: [PATCH 5/5] CoapMessagingLayer - Documented `begin()`, `send(CoapPacket)` and `close()` --- source/doap/client/messaging.d | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/doap/client/messaging.d b/source/doap/client/messaging.d index d31c022..1e5ff3e 100644 --- a/source/doap/client/messaging.d +++ b/source/doap/client/messaging.d @@ -66,6 +66,11 @@ class CoapMessagingLayer : Thread return this.client.address; } + /** + * Starts the messaging layer by starting + * the underlying transport and then the + * reader loop + */ public void begin() // Candidate for Interface { // TODO: Handle socket errors nicely? @@ -84,6 +89,13 @@ class CoapMessagingLayer : Thread this.start(); } + /** + * Transmit the provided packet + * + * Params: + * packet = the `CoapPacket` + * to transmit + */ public void send(CoapPacket packet) // Candidate for Interface { // Encode the packet and send the bytes @@ -91,6 +103,15 @@ class CoapMessagingLayer : Thread this.socket.send(encodedPacket); } + /** + * Stops the messaging layer by + * stopping the underlying network + * transport and therefore the + * reading loop + * + * Blocks till the reading loop + * has terminated + */ public void close() // Candidate for Interface { // Set status to not running