Skip to content

Instantly share code, notes, and snippets.

@pokgak
Last active April 19, 2020 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pokgak/195b61e15eadffe2a211cf3866eb7a55 to your computer and use it in GitHub Desktop.
Save pokgak/195b61e15eadffe2a211cf3866eb7a55 to your computer and use it in GitHub Desktop.
sock_dtls + sock_async v2
diff --git a/examples/dtls-sock/Makefile b/examples/dtls-sock/Makefile
index 4f22d50df..fb1c55608 100644
--- a/examples/dtls-sock/Makefile
+++ b/examples/dtls-sock/Makefile
@@ -16,7 +16,10 @@ USEMODULE += gnrc_netdev_default
USEMODULE += auto_init_gnrc_netif
# Specify the mandatory networking modules for IPv6 and UDP
USEMODULE += gnrc_ipv6_default
+USEMODULE += gnrc_sock_async
USEMODULE += gnrc_sock_udp
+USEMODULE += sock_async_event
+USEMODULE += event_thread_medium
# Use tinydtls for sock_dtls
USEMODULE += tinydtls_sock_dtls
diff --git a/examples/dtls-sock/dtls-client.c b/examples/dtls-sock/dtls-client.c
index 76c524a86..39af8db87 100644
--- a/examples/dtls-sock/dtls-client.c
+++ b/examples/dtls-sock/dtls-client.c
@@ -18,6 +18,8 @@
#include <stdio.h>
+#include "event/thread.h"
+#include "net/sock/async/event.h"
#include "net/sock/udp.h"
#include "net/sock/dtls.h"
#include "net/ipv6/addr.h"
@@ -56,6 +58,9 @@ static const credman_credential_t credential = {
static const uint8_t psk_id_0[] = PSK_DEFAULT_IDENTITY;
static const uint8_t psk_key_0[] = PSK_DEFAULT_KEY;
+static bool handshake_done = false;
+static bool received_message_back = false;
+
static const credman_credential_t credential = {
.type = CREDMAN_TYPE_PSK,
.tag = SOCK_DTLS_CLIENT_TAG,
@@ -68,6 +73,41 @@ static const credman_credential_t credential = {
};
#endif
+static uint8_t _rcv_buf[512];
+
+static void _dtls_handler(sock_dtls_t *sock, sock_async_flags_t type, void *arg)
+{
+ (void)arg;
+ if (type & SOCK_ASYNC_CONN_RDY) {
+ puts("Session became ready");
+ handshake_done = true;
+ }
+ else if (type & SOCK_ASYNC_CONN_FIN) {
+ puts("Session was destroyed");
+ }
+ else if (type & SOCK_ASYNC_CONN_RECV) {
+ puts("Peer tries to create session");
+ }
+ else if (type & SOCK_ASYNC_MSG_RECV) {
+ sock_dtls_session_t session = { 0 };
+
+ puts("client received message in callback!");
+ if (sock_dtls_recv(sock, &session, _rcv_buf, sizeof(_rcv_buf), 0) < 0) {
+ printf("Error receiving DTLS message\n");
+ }
+ else {
+ printf("Received DTLS message\n");
+ received_message_back = true;
+ }
+ }
+ else if (type & SOCK_ASYNC_MSG_SENT) {
+ puts("DTLS message was sent");
+ }
+ else if (type & SOCK_ASYNC_PATH_PROP) {
+ puts("Path property changed");
+ }
+}
+
static int client_send(char *addr_str, char *data, size_t datalen)
{
ssize_t res;
@@ -115,6 +155,7 @@ static int client_send(char *addr_str, char *data, size_t datalen)
return -1;
}
+ sock_dtls_event_init(&dtls_sock, &event_queue_medium, _dtls_handler, NULL);
res = credman_add(&credential);
if (res < 0 && res != CREDMAN_EXIST) {
/* ignore duplicate credentials */
@@ -130,19 +171,21 @@ static int client_send(char *addr_str, char *data, size_t datalen)
return -1;
}
+ while (!handshake_done) {
+ xtimer_sleep(1);
+ puts("waiting for handshake process");
+ }
+
if (sock_dtls_send(&dtls_sock, &session, data, datalen) < 0) {
puts("Error sending data");
}
else {
printf("Sent DTLS message\n");
+ }
- uint8_t rcv[512];
- if (sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv), SOCK_NO_TIMEOUT) < 0) {
- printf("Error receiving DTLS message\n");
- }
- else {
- printf("Received DTLS message\n");
- }
+ while (!received_message_back) {
+ xtimer_sleep(1);
+ puts("waiting for received message process");
}
puts("Terminating");
diff --git a/examples/dtls-sock/dtls-server.c b/examples/dtls-sock/dtls-server.c
index b2c5004c0..537dea1e1 100644
--- a/examples/dtls-sock/dtls-server.c
+++ b/examples/dtls-sock/dtls-server.c
@@ -18,6 +18,8 @@
#include <stdio.h>
+#include "event/thread.h"
+#include "net/sock/async/event.h"
#include "net/sock/udp.h"
#include "net/sock/dtls.h"
#include "net/credman.h"
@@ -31,14 +33,8 @@
#endif
#define SOCK_DTLS_SERVER_TAG (10)
-#define DTLS_STOP_SERVER_MSG 0x4001 /* Custom IPC type msg. */
#define READER_QUEUE_SIZE (8U)
-char _dtls_server_stack[THREAD_STACKSIZE_MAIN +
- THREAD_EXTRA_STACKSIZE_PRINTF];
-
-static kernel_pid_t _dtls_server_pid = KERNEL_PID_UNDEF;
-
#ifdef CONFIG_DTLS_ECC
static const ecdsa_public_key_t other_pubkeys[] = {
{ .x = ecdsa_pub_key_x, .y = ecdsa_pub_key_y },
@@ -73,23 +69,66 @@ static const credman_credential_t credential = {
};
#endif
-void *dtls_server_wrapper(void *arg)
+static bool msg_echo_done = false;
+static uint8_t _rcv_buf[512];
+static sock_dtls_session_t _session = {0};
+static msg_t _reader_queue[READER_QUEUE_SIZE];
+static sock_dtls_t sock;
+static sock_udp_t udp_sock;
+static sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
+
+static void _dtls_handler(sock_dtls_t *sock, sock_async_flags_t type, void *arg)
{
- (void) arg;
+ (void)arg;
+ if (type & SOCK_ASYNC_CONN_RDY) {
+ puts("Session became ready");
+ }
+ else if (type & SOCK_ASYNC_CONN_FIN) {
+ puts("Session was destroyed");
+ }
+ else if (type & SOCK_ASYNC_CONN_RECV) {
+ puts("New session from peer");
+ }
+ else if (type & SOCK_ASYNC_MSG_RECV) {
+ ssize_t recvd = sock_dtls_recv(sock, &_session, _rcv_buf, sizeof(_rcv_buf), 0);
+ if (recvd < 0) {
+ printf("Error receiving DTLS message\n");
+ }
+ else if (recvd > 0) {
+ printf("Received DTLS message - echo! %s\n", _rcv_buf);
+ if (sock_dtls_send(sock, &_session, "hello", sizeof("hello")) < 0) {
+ printf("Error echoing DTLS message\n");
+ }
+ else {
+ puts("setti msg_echo done true");
+ msg_echo_done = true;
+ }
+ }
+ else {
+ printf("Received empty DTLS message");
+ }
+ }
+ else if (type & SOCK_ASYNC_MSG_SENT) {
+ puts("DTLS message was sent");
+ if (msg_echo_done) {
+ sock_dtls_session_destroy(sock, &_session);
+ sock_dtls_close(sock);
+ sock_udp_close(sock->udp_sock);
+ puts("Terminating");
+ }
+ }
+ else if (type & SOCK_ASYNC_PATH_PROP) {
+ puts("Path property changed");
+ }
+}
+static void start_server(void)
+{
ssize_t res;
- bool active = true;
- msg_t _reader_queue[READER_QUEUE_SIZE];
- msg_t msg;
- uint8_t rcv[512];
/* Prepare (thread) messages reception */
msg_init_queue(_reader_queue, READER_QUEUE_SIZE);
- sock_dtls_session_t session;
- sock_dtls_t sock;
- sock_udp_t udp_sock;
- sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
local.port = DTLS_DEFAULT_PORT;
sock_udp_create(&udp_sock, &local, NULL, 0);
@@ -97,86 +136,15 @@ void *dtls_server_wrapper(void *arg)
SOCK_DTLS_1_2, SOCK_DTLS_SERVER);
if (res < 0) {
puts("Error creating DTLS sock");
- return NULL;
+ return;
}
+ sock_dtls_event_init(&sock, &event_queue_medium, _dtls_handler, NULL);
res = credman_add(&credential);
if (res < 0 && res != CREDMAN_EXIST) {
/* ignore duplicate credentials */
printf("Error cannot add credential to system: %d\n", (int)res);
- return NULL;
}
-
- while (active) {
- if ((msg_try_receive(&msg) == 1) && (msg.type == DTLS_STOP_SERVER_MSG)) {
- active = false;
- }
- else {
- res = sock_dtls_recv(&sock, &session, rcv, sizeof(rcv),
- 10 * US_PER_SEC);
- if (res < 0) {
- if (res != -ETIMEDOUT) {
- printf("Error receiving UDP over DTLS %d", (int)res);
- }
- continue;
- }
- printf("Received %d bytes -- (echo!)\n", (int)res);
- res = sock_dtls_send(&sock, &session, rcv, (size_t)res);
- if (res < 0) {
- printf("Error resending DTLS message: %d", (int)res);
- }
- }
- }
-
- sock_dtls_session_destroy(&sock, &session);
- sock_dtls_close(&sock);
- sock_udp_close(&udp_sock);
- puts("Terminating");
- msg_reply(&msg, &msg); /* Basic answer to the main thread */
- return NULL;
-}
-
-static void start_server(void)
-{
- /* Only one instance of the server */
- if (_dtls_server_pid != KERNEL_PID_UNDEF) {
- puts("Error: server already running");
- return;
- }
-
- /* Start the server thread */
- _dtls_server_pid = thread_create(_dtls_server_stack,
- sizeof(_dtls_server_stack),
- THREAD_PRIORITY_MAIN - 1,
- THREAD_CREATE_STACKTEST,
- dtls_server_wrapper, NULL, "dtls_server");
-
- /* Uncommon but better be sure */
- if (_dtls_server_pid < 0) {
- printf("ERROR: failed to create thread: %d\n", _dtls_server_pid);
- _dtls_server_pid = KERNEL_PID_UNDEF;
- }
-}
-
-static void stop_server(void)
-{
- /* check if server is running at all */
- if (_dtls_server_pid == KERNEL_PID_UNDEF) {
- puts("Error: DTLS server is not running");
- return;
- }
-
- /* prepare the stop message */
- msg_t m;
- m.type = DTLS_STOP_SERVER_MSG;
-
- puts("Stopping server...");
-
- /* send the stop message to thread AND wait for (any) answer */
- msg_send_receive(&m, &m, _dtls_server_pid);
-
- _dtls_server_pid = KERNEL_PID_UNDEF;
- puts("Success: DTLS server stopped");
}
int dtls_server_cmd(int argc, char **argv)
@@ -189,7 +157,7 @@ int dtls_server_cmd(int argc, char **argv)
start_server();
}
else if (strcmp(argv[1], "stop") == 0) {
- stop_server();
+ // stop_server();
}
else {
printf("Error: invalid command. Usage: %s start | stop\n", argv[0]);
diff --git a/pkg/tinydtls/contrib/sock_dtls.c b/pkg/tinydtls/contrib/sock_dtls.c
index 87e10862b..0c4ae0121 100644
--- a/pkg/tinydtls/contrib/sock_dtls.c
+++ b/pkg/tinydtls/contrib/sock_dtls.c
@@ -107,6 +107,11 @@ static int _write(struct dtls_context_t *ctx, session_t *session, uint8_t *buf,
if (res < 0) {
DEBUG("sock_dtls: failed to send DTLS record: %d\n", (int)res);
}
+ #ifdef SOCK_HAS_ASYNC
+ if ((res >= 0) && (sock->async_cb != NULL)) {
+ sock->async_cb(sock, SOCK_ASYNC_MSG_SENT, sock->async_cb_arg);
+ }
+ #endif /* SOCK_HAS_ASYNC */
return res;
}
@@ -306,8 +311,6 @@ int sock_dtls_create(sock_dtls_t *sock, sock_udp_t *udp_sock,
int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
sock_dtls_session_t *remote)
{
- uint8_t rcv_buffer[DTLS_HANDSHAKE_BUFSIZE];
- msg_t msg;
ssize_t res;
assert(sock);
@@ -331,6 +334,9 @@ int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
return 0;
}
+#ifndef SOCK_HAS_ASYNC
+ uint8_t rcv_buffer[512];
+ msg_t msg;
/* receive all handshake messages or timeout if timer expires */
while (!mbox_try_get(&sock->mbox, &msg) ||
msg.type != DTLS_EVENT_CONNECTED) {
@@ -352,6 +358,7 @@ int sock_dtls_session_create(sock_dtls_t *sock, const sock_udp_ep_t *ep,
return res;
}
}
+#endif /* SOCK_HAS_ASYNC */
return 0;
}
@@ -368,37 +375,8 @@ ssize_t sock_dtls_send(sock_dtls_t *sock, sock_dtls_session_t *remote,
assert(sock);
assert(remote);
assert(data);
-
- /* check if session exists, if not create session first then send */
- if (!dtls_get_peer(sock->dtls_ctx, &remote->dtls_session)) {
- /* no session with remote, creating new session.
- * This will also create new peer for this session */
- res = dtls_connect(sock->dtls_ctx, &remote->dtls_session);
- if (res < 0) {
- DEBUG("sock_dtls: error initiating handshake\n");
- return -ENOMEM;
- }
- else if (res > 0) {
- /* handshake initiated, wait until connected or timed out */
-
- msg_t msg;
- do {
- res = xtimer_msg_receive_timeout(&msg, 3 * DTLS_HANDSHAKE_TIMEOUT);
- }
- while ((res != -1) && (msg.type != DTLS_EVENT_CONNECTED));
- if (res == -1) {
- DEBUG("sock_dtls: handshake process timed out\n");
-
- /* deletes peer created in dtls_connect() before */
- dtls_peer_t *peer = dtls_get_peer(sock->dtls_ctx, &remote->dtls_session);
- dtls_reset_peer(sock->dtls_ctx, peer);
- return -EHOSTUNREACH;
- }
- }
- }
-
res = dtls_write(sock->dtls_ctx, &remote->dtls_session, (uint8_t *)data,
- len);
+ len);
#ifdef SOCK_HAS_ASYNC
if ((res >= 0) && (sock->async_cb != NULL)) {
sock->async_cb(sock, SOCK_ASYNC_MSG_SENT, sock->async_cb_arg);
@@ -480,10 +458,6 @@ ssize_t sock_dtls_recv(sock_dtls_t *sock, sock_dtls_session_t *remote,
timeout = (time_passed > timeout) ? 0: timeout - time_passed;
}
- _ep_to_session(&remote->ep, &remote->dtls_session);
- res = dtls_handle_message(sock->dtls_ctx, &remote->dtls_session,
- (uint8_t *)data, res);
-
if (sock->buf != NULL) {
return _copy_buffer(sock, remote, data, max_len);
}
@@ -525,11 +499,12 @@ static void _session_to_ep(const session_t *session, sock_udp_ep_t *ep)
#ifdef SOCK_HAS_ASYNC
void _udp_cb(sock_udp_t *udp_sock, sock_async_flags_t flags, void *ctx)
{
+ puts("udb cb called");
if (flags & SOCK_ASYNC_MSG_RECV) {
sock_dtls_t *sock = ctx;
sock_dtls_session_t remote;
- void *data;
- void *data_ctx;
+ void *data = NULL;
+ void *data_ctx = NULL;
ssize_t res = sock_udp_recv_buf(udp_sock, &data, &data_ctx, 0,
&remote.ep);
@@ -538,11 +513,11 @@ void _udp_cb(sock_udp_t *udp_sock, sock_async_flags_t flags, void *ctx)
return;
}
- if (sock->buf_ctx != NULL) {
- DEBUG("sock_dtls: unable to store buffer asynchronously\n");
- _check_more_chunks(udp_sock, &data, &data_ctx, &remote.ep);
- return;
- }
+ // if (data_ctx != NULL) {
+ // DEBUG("sock_dtls: unable to store buffer asynchronously\n");
+ // _check_more_chunks(udp_sock, &data, &data_ctx, &remote.ep);
+ // return;
+ // }
_ep_to_session(&remote.ep, &remote.dtls_session);
sock->buf_ctx = data_ctx;
res = dtls_handle_message(sock->dtls_ctx, &remote.dtls_session,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment