Skip to content

Commit 5208f0c

Browse files
committed
feat(srv/nbus2): Handle socket binding
1 parent 03b0831 commit 5208f0c

File tree

4 files changed

+174
-116
lines changed

4 files changed

+174
-116
lines changed

services/nbus2/nbus2.c

+109-25
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "blake2s-siv.h"
1818
#include "halfsiphash.h"
1919
#include <chacha20.h>
20-
#include "pbuf.h"
2120

2221
#define MODULE_NAME "nbus"
2322

@@ -245,34 +244,25 @@ static nbus_ret_t nbus_pbuf_receive_data(struct nbus_pbuf *self, Nbus *nbus) {
245244
}
246245

247246

248-
static nbus_ret_t nbus_pbuf_send(struct nbus_pbuf *self, void *buf, size_t len, uint8_t dst_id[4], uint8_t dst_ep) {
249-
if ((len + 24) > self->buf_size) {
250-
return NBUS_RET_FAILED;
251-
}
252-
memcpy(self->buf + 24, buf, len);
253-
self->buf_len = len + 24;
247+
static nbus_ret_t nbus_pbuf_transmit(struct nbus_pbuf *self, Nbus *nbus) {
254248

255249
self->buf[8] = 'n';
256250
self->buf[9] = '2';
257251

258-
self->buf[10] = len / 256;
259-
self->buf[11] = len % 256;
252+
self->buf[10] = (self->buf_len - 24) / 256;
253+
self->buf[11] = (self->buf_len - 24) % 256;
260254

261255
self->buf[12] = nbus_tx_counter / 256;
262256
self->buf[13] = nbus_tx_counter % 256;
263257
nbus_tx_counter++;
264258

265-
/* Set IDs and endpoints. */
266-
self->buf[14] = (dst_ep & 0xf) << 4 | (nbus_my_ep & 0xf);
267-
self->buf[15] = 0;
268-
memcpy(self->buf + 16, dst_id, 4);
269-
memcpy(self->buf + 20, nbus_my_id, 4);
270-
271-
return NBUS_RET_OK;
272-
}
259+
/* buf[14] are endpoints. */
273260

261+
/* Clear flags */
262+
/** @todo set flags */
263+
self->buf[15] = 0;
274264

275-
static nbus_ret_t nbus_pbuf_transmit(struct nbus_pbuf *self, Nbus *nbus) {
265+
/* buf[16-23] are destination and source id. */
276266

277267
/* Compute SIV first */
278268
halfsiphash(self->buf + 8, self->buf_len - 8, self->km, self->buf, 8);
@@ -302,6 +292,18 @@ static nbus_ret_t nbus_pbuf_dispatch(Nbus *self, struct nbus_pbuf *pbuf) {
302292
/* Try to match the socket naively. Receive everything for now. */
303293
for (size_t i = 0; i < NBUS_SOCKET_COUNT; i++) {
304294
if (self->sockets[i].used && self->sockets[i].enabled) {
295+
/* If the socket is locally bound, check the destination ID. */
296+
if (memcmp(self->sockets[i].local_id, (uint8_t[4]){0, 0, 0, 0}, 4)) {
297+
uint8_t dst_addr[4] = {0};
298+
uint8_t dst_ep = 0;
299+
nbus_pbuf_get_destination(pbuf, dst_addr, &dst_ep);
300+
if (memcmp(dst_addr, self->sockets[i].local_id, 4) || dst_ep != self->sockets[i].local_ep) {
301+
/* Not ours, not interested. */
302+
continue;
303+
}
304+
305+
}
306+
305307
if (xQueueSend(self->sockets[i].rx_queue, &pbuf, 0) != pdTRUE) {
306308
/* Couldn't queue the pbuf, treat as failed reception. */
307309
break;
@@ -433,13 +435,35 @@ static datagram_ret_t nbus_socket_write(Datagram *datagram, const void *buf, siz
433435
(void)len;
434436
(void)msg;
435437

438+
/* Socket must be bound to a local ID and EP. */
439+
if (!memcmp(self->local_id, (uint8_t[4]){0, 0, 0, 0}, 4)) {
440+
return DATAGRAM_RET_FAILED;
441+
}
442+
436443
struct nbus_pbuf *pbuf = nbus_pbuf_allocate(self->parent);
437444
if (pbuf == NULL) {
438445
return DATAGRAM_RET_FAILED;
439446
}
440447

441-
uint8_t dstid[4] = {0, 0, 0, 1};
442-
nbus_pbuf_send(pbuf, buf, len, dstid, 1);
448+
/* Check if there is space required for the whole datagram. */
449+
if ((len + 24) > pbuf->buf_size) {
450+
nbus_pbuf_release(self->parent, pbuf);
451+
return DATAGRAM_RET_FAILED;
452+
}
453+
454+
/* Set all required packet fields + copy data. */
455+
nbus_pbuf_set_source(pbuf, self->local_id, self->local_ep);
456+
if (memcmp(self->remote_id, (uint8_t[4]){0, 0, 0, 0}, 4)) {
457+
nbus_pbuf_set_destination(pbuf, self->remote_id, self->remote_ep);
458+
} else if (msg != NULL && msg->addr_size == 4 && memcmp(msg->dst_addr, (uint8_t[4]){0, 0, 0, 0}, 4)) {
459+
nbus_pbuf_set_destination(pbuf, msg->dst_addr, msg->dst_port);
460+
} else {
461+
/* Cannot determine destination ID. */
462+
nbus_pbuf_release(self->parent, pbuf);
463+
return DATAGRAM_RET_FAILED;
464+
}
465+
memcpy(pbuf->buf + 24, buf, len);
466+
pbuf->buf_len = len + 24;
443467

444468
if (xQueueSend(self->tx_queue, &pbuf, 0) != pdTRUE) {
445469
nbus_pbuf_release(self->parent, pbuf);
@@ -475,7 +499,13 @@ static datagram_ret_t nbus_socket_read(Datagram *datagram, void *buf, size_t *le
475499

476500
/* Interested in metadata? */
477501
if (msg != NULL) {
478-
/** @todo */
502+
msg->addr_size = 4;
503+
uint8_t dst_ep = 0;
504+
uint8_t src_ep = 0;
505+
nbus_pbuf_get_destination(pbuf, msg->dst_addr, &dst_ep);
506+
msg->dst_port = dst_ep;
507+
nbus_pbuf_get_source(pbuf, msg->src_addr, &src_ep);
508+
msg->src_port = src_ep;
479509
}
480510

481511
/* Not needed anymore. */
@@ -617,6 +647,56 @@ nbus_ret_t nbus_pbuf_release(Nbus *self, struct nbus_pbuf *pbuf) {
617647
}
618648

619649

650+
nbus_ret_t nbus_pbuf_set_destination(struct nbus_pbuf *self, const uint8_t id[4], uint8_t ep) {
651+
self->buf[14] &= ~0xf0;
652+
self->buf[14] |= (ep & 0x0f) << 4;
653+
memcpy(&(self->buf[16]), id, 4);
654+
655+
return NBUS_RET_OK;
656+
}
657+
658+
659+
nbus_ret_t nbus_pbuf_set_source(struct nbus_pbuf *self, const uint8_t id[4], uint8_t ep) {
660+
self->buf[14] &= ~0x0f;
661+
self->buf[14] |= ep & 0x0f;
662+
memcpy(&(self->buf[20]), id, 4);
663+
664+
return NBUS_RET_OK;
665+
}
666+
667+
668+
nbus_ret_t nbus_pbuf_get_destination(struct nbus_pbuf *self, uint8_t id[4], uint8_t *ep) {
669+
memcpy(id, &(self->buf[16]), 4);
670+
*ep = self->buf[14] >> 4;
671+
672+
return NBUS_RET_OK;
673+
}
674+
675+
676+
nbus_ret_t nbus_pbuf_get_source(struct nbus_pbuf *self, uint8_t id[4], uint8_t *ep) {
677+
memcpy(id, &(self->buf[20]), 4);
678+
*ep = self->buf[14] >> 0x0f;
679+
680+
return NBUS_RET_OK;
681+
}
682+
683+
684+
static nbus_ret_t nbus_pbuf_send(struct nbus_pbuf *self, void *buf, size_t len, uint8_t dst_id[4], uint8_t dst_ep) {
685+
if ((len + 24) > self->buf_size) {
686+
return NBUS_RET_FAILED;
687+
}
688+
memcpy(self->buf + 24, buf, len);
689+
self->buf_len = len + 24;
690+
691+
692+
/* Set IDs and endpoints. */
693+
self->buf[14] = (dst_ep & 0xf) << 4 | (nbus_my_ep & 0xf);
694+
memcpy(self->buf + 16, dst_id, 4);
695+
memcpy(self->buf + 20, nbus_my_id, 4);
696+
697+
return NBUS_RET_OK;
698+
}
699+
620700

621701
/* ******************************************** nbus socket manipulation **********************************************/
622702

@@ -638,11 +718,11 @@ struct nbus_socket *nbus_socket_allocate(Nbus *self) {
638718
/** @todo do not enable until bound */
639719
self->sockets[i].enabled = true;
640720

641-
self->sockets[i].local_id = 0;
642-
self->sockets[i].local_id_mask = 0;
721+
memset(self->sockets[i].local_id, 0, 4);
722+
memset(self->sockets[i].local_id_mask, 0, 4);
643723
self->sockets[i].local_ep = 0;
644-
self->sockets[i].remote_id = 0;
645-
self->sockets[i].remote_id_mask = 0;
724+
memset(self->sockets[i].remote_id, 0, 4);
725+
memset(self->sockets[i].remote_id_mask, 0, 4);
646726
self->sockets[i].remote_ep = 0;
647727

648728
self->sockets[i].datagram.vmt = &nbus_socket_vmt;
@@ -679,6 +759,10 @@ nbus_ret_t nbus_socket_bind(struct nbus_socket *socket, const uint8_t *id, uint8
679759
(void)id;
680760
(void)ep;
681761

762+
memcpy(socket->local_id, id, 4);
763+
memcpy(socket->local_id_mask, (uint8_t[4]){0xff, 0xff, 0xff, 0xff}, 4);
764+
socket->local_ep = ep;
765+
682766
return NBUS_RET_OK;
683767

684768
}

services/nbus2/nbus2.h

+65-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <interfaces/datagram.h>
1414
#include "blake2s-siv.h"
1515
#include <main.h>
16-
#include "pbuf.h"
1716

1817

1918
#define NBUS_TIMEOUT_MS 10000
@@ -23,6 +22,12 @@
2322
#define NBUS_SOCKET_TX_QUEUE_LEN 2
2423
#define NBUS_SOCKET_RX_QUEUE_LEN 2
2524

25+
/** Key length in bytes for packet encryption. */
26+
#define NBUS_PBUF_KE_LEN 16
27+
28+
/** Key length in bytes for packet MAC/SIV generation. */
29+
#define NBUS_PBUF_KM_LEN 16
30+
2631
typedef enum {
2732
NBUS_RET_OK = 0,
2833
NBUS_RET_FAILED,
@@ -43,15 +48,66 @@ struct nbus_socket {
4348
QueueHandle_t tx_queue;
4449
QueueHandle_t rx_queue;
4550

46-
uint8_t *local_id;
47-
uint8_t *local_id_mask;
51+
uint8_t local_id[4];
52+
uint8_t local_id_mask[4];
4853
uint32_t local_ep;
4954

50-
uint8_t *remote_id;
51-
uint8_t *remote_id_mask;
55+
uint8_t remote_id[4];
56+
uint8_t remote_id_mask[4];
5257
uint32_t remote_ep;
5358
};
5459

60+
enum nbus_pbuf_state {
61+
/**
62+
* Packet buffer resides in the pool of free buffers usually owned
63+
* by the service implementing the interface. The pool is the sole
64+
* owner of the buffer. No operations nor access are possible.
65+
*/
66+
NBUS_PBUF_STATE_EMPTY = 0,
67+
68+
/**
69+
* Packet buffer was returned by the allocator factory function/method.
70+
* Now the owner is whoever received the returned pointer. After using
71+
* the buffer, it must be manually freed.
72+
*/
73+
NBUS_PBUF_STATE_ALLOCATED,
74+
75+
/**
76+
* The buffer may not be freed immediately. Wait for garbage collection.
77+
*/
78+
NBUS_PBUF_STATE_GC,
79+
};
80+
81+
struct nbus_pbuf {
82+
enum nbus_pbuf_state state;
83+
84+
uint8_t ke[NBUS_PBUF_KE_LEN];
85+
uint8_t km[NBUS_PBUF_KM_LEN];
86+
87+
/**
88+
* Preallocated packet/datagram buffer. More complex allocators may
89+
* allocate the requested number of bytes.
90+
*/
91+
uint8_t *buf;
92+
93+
/**
94+
* The allocated buffer size in bytes.
95+
*/
96+
size_t buf_size;
97+
98+
/**
99+
* Length of the packet in the buffer (that is, number of bytes actually used.
100+
*/
101+
size_t buf_len;
102+
103+
/**
104+
* Semaphore handle to allow waiting on the packet buffer (when receiving
105+
* and sending packets/datagrams)
106+
*/
107+
SemaphoreHandle_t s;
108+
109+
};
110+
55111
typedef struct nbus {
56112
Stream *stream;
57113
const uint8_t *mac_key;
@@ -74,6 +130,10 @@ nbus_ret_t nbus_set_mac_key(Nbus *self, const uint8_t *mac_key, size_t mac_key_l
74130

75131
struct nbus_pbuf *nbus_pbuf_allocate(Nbus *self);
76132
nbus_ret_t nbus_pbuf_release(Nbus *self, struct nbus_pbuf *pbuf);
133+
nbus_ret_t nbus_pbuf_set_destination(struct nbus_pbuf *self, const uint8_t id[4], uint8_t ep);
134+
nbus_ret_t nbus_pbuf_set_source(struct nbus_pbuf *self, const uint8_t id[4], uint8_t ep);
135+
nbus_ret_t nbus_pbuf_get_destination(struct nbus_pbuf *self, uint8_t id[4], uint8_t *ep);
136+
nbus_ret_t nbus_pbuf_get_source(struct nbus_pbuf *self, uint8_t id[4], uint8_t *ep);
77137

78138
struct nbus_socket *nbus_socket_allocate(Nbus *self);
79139
nbus_ret_t nbus_socket_release(Nbus *self, struct nbus_socket *socket);

services/nbus2/pbuf.c

-9
This file was deleted.

services/nbus2/pbuf.h

-77
This file was deleted.

0 commit comments

Comments
 (0)