Skip to content
This repository was archived by the owner on Jun 27, 2019. It is now read-only.

Commit 1424f3e

Browse files
committed
comms: Turn sol-socket into a very simple BSD sockets wrapper
In order to port the functionality to other platforms that don't have BSD sockets, we need to wrap them on our own API first. And since sockets can be used on a wide variety of things, we need to start small and only with that we need. For now, wrap only the required functionality to make CoAP work. Signed-off-by: Iván Briano <[email protected]>
1 parent cd15d1c commit 1424f3e

File tree

3 files changed

+184
-88
lines changed

3 files changed

+184
-88
lines changed

src/lib/comms/sol-coap.c

Lines changed: 32 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,8 @@ struct sol_coap_server {
9090
struct sol_vector contexts;
9191
struct sol_ptr_vector pending; /* waiting pending replies */
9292
struct sol_ptr_vector outgoing; /* in case we need to retransmit */
93-
struct sol_fd *read_watch;
94-
struct sol_fd *write_watch;
93+
struct sol_socket *socket;
9594
int refcnt;
96-
int fd;
9795
};
9896

9997
struct resource_context {
@@ -127,7 +125,7 @@ struct outgoing {
127125
int counter; /* How many times this packet was retransmited. */
128126
};
129127

130-
static bool can_write(void *data, int fd, unsigned int active_flags);
128+
static bool on_can_write(void *data, struct sol_socket *s);
131129

132130
SOL_API uint8_t
133131
sol_coap_header_get_ver(const struct sol_coap_packet *pkt)
@@ -420,16 +418,6 @@ next_in_queue(struct sol_coap_server *server, int *idx)
420418
return NULL;
421419
}
422420

423-
static void
424-
wakeup_write(struct sol_coap_server *server)
425-
{
426-
if (server->write_watch)
427-
return;
428-
429-
server->write_watch = sol_fd_add(server->fd, SOL_FD_FLAGS_OUT, can_write, server);
430-
SOL_NULL_CHECK(server->write_watch);
431-
}
432-
433421
static bool
434422
timeout_cb(void *data)
435423
{
@@ -439,7 +427,7 @@ timeout_cb(void *data)
439427

440428
outgoing->timeout = NULL;
441429

442-
wakeup_write(server);
430+
sol_socket_set_on_write(server->socket, on_can_write, server);
443431

444432
sol_network_addr_to_str(&outgoing->cliaddr, addr, sizeof(addr));
445433

@@ -475,26 +463,21 @@ setup_timeout(struct sol_coap_server *server, struct outgoing *outgoing)
475463
}
476464

477465
static bool
478-
can_write(void *data, int fd, unsigned int active_flags)
466+
on_can_write(void *data, struct sol_socket *s)
479467
{
480468
struct sol_coap_server *server = data;
481469
struct outgoing *outgoing;
482470
int err;
483471
int idx;
484472

485-
if (active_flags & (SOL_FD_FLAGS_HUP | SOL_FD_FLAGS_ERR)) {
486-
SOL_WRN("server %p socket closed", server);
487-
goto remove_watch;
488-
}
489-
490473
if (sol_ptr_vector_get_len(&server->outgoing) == 0)
491-
goto remove_watch;
474+
return false;
492475

493476
outgoing = next_in_queue(server, &idx);
494477
if (!outgoing)
495-
goto remove_watch;
478+
return false;
496479

497-
err = sol_socket_sendmsg(server->fd, outgoing->pkt->buf,
480+
err = sol_socket_sendmsg(s, outgoing->pkt->buf,
498481
outgoing->pkt->payload.used, &outgoing->cliaddr);
499482
/* Eventually we are going to re-send it. */
500483
if (err == -EAGAIN)
@@ -505,7 +488,7 @@ can_write(void *data, int fd, unsigned int active_flags)
505488
sol_network_addr_to_str(&outgoing->cliaddr, addr, sizeof(addr));
506489
SOL_WRN("Could not send packet %d to %s (%d): %s", sol_coap_header_get_id(outgoing->pkt),
507490
addr, errno, sol_util_strerrora(errno));
508-
goto remove_watch;
491+
return false;
509492
}
510493

511494
if (sol_coap_header_get_type(outgoing->pkt) != SOL_COAP_TYPE_CON) {
@@ -516,13 +499,9 @@ can_write(void *data, int fd, unsigned int active_flags)
516499
}
517500

518501
if (sol_ptr_vector_get_len(&server->outgoing) == 0)
519-
goto remove_watch;
502+
return false;
520503

521504
return true;
522-
523-
remove_watch:
524-
server->write_watch = NULL;
525-
return false;
526505
}
527506

528507
static int
@@ -549,7 +528,7 @@ enqueue_packet(struct sol_coap_server *server, struct sol_coap_packet *pkt,
549528

550529
outgoing->pkt = sol_coap_packet_ref(pkt);
551530

552-
wakeup_write(server);
531+
sol_socket_set_on_write(server->socket, on_can_write, server);
553532

554533
return 0;
555534
}
@@ -1213,24 +1192,18 @@ respond_packet(struct sol_coap_server *server, struct sol_coap_packet *req,
12131192
}
12141193

12151194
static bool
1216-
on_receive_data(void *data, int fd, unsigned int active_flags)
1195+
on_can_read(void *data, struct sol_socket *s)
12171196
{
12181197
struct sol_coap_server *server = data;
12191198
struct sol_network_link_addr cliaddr;
12201199
struct sol_coap_packet *pkt;
12211200
ssize_t len;
12221201
int err;
12231202

1224-
if (active_flags & (SOL_FD_FLAGS_HUP | SOL_FD_FLAGS_ERR)) {
1225-
SOL_WRN("server %p socket closed", server);
1226-
server->read_watch = NULL;
1227-
return false;
1228-
}
1229-
12301203
pkt = sol_coap_packet_new(NULL);
12311204
SOL_NULL_CHECK(pkt, true); /* It may possible that in the next round there is enough memory. */
12321205

1233-
len = sol_socket_recvmsg(fd, pkt->buf, pkt->payload.size, &cliaddr);
1206+
len = sol_socket_recvmsg(s, pkt->buf, pkt->payload.size, &cliaddr);
12341207
if (len < 0) {
12351208
SOL_WRN("Could not read from socket (%d): %s", errno, sol_util_strerrora(errno));
12361209
coap_packet_free(pkt);
@@ -1286,10 +1259,7 @@ sol_coap_server_destroy(struct sol_coap_server *server)
12861259
struct outgoing *o;
12871260
uint16_t i;
12881261

1289-
if (server->read_watch)
1290-
sol_fd_del(server->read_watch);
1291-
if (server->write_watch)
1292-
sol_fd_del(server->write_watch);
1262+
sol_socket_del(server->socket);
12931263

12941264
SOL_PTR_VECTOR_FOREACH_REVERSE_IDX (&server->outgoing, o, i) {
12951265
sol_ptr_vector_del(&server->outgoing, i);
@@ -1323,7 +1293,7 @@ sol_coap_server_unref(struct sol_coap_server *server)
13231293
}
13241294

13251295
static int
1326-
join_mcast_groups(int fd, const struct sol_network_link *link)
1296+
join_mcast_groups(struct sol_socket *s, const struct sol_network_link *link)
13271297
{
13281298
struct sol_network_link_addr groupaddr = { };
13291299
struct sol_network_link_addr *addr;
@@ -1337,18 +1307,18 @@ join_mcast_groups(int fd, const struct sol_network_link *link)
13371307

13381308
if (addr->family == AF_INET) {
13391309
sol_network_addr_from_str(&groupaddr, IPV4_ALL_COAP_NODES_GROUP);
1340-
if (sol_socket_join_group(fd, link->index, &groupaddr) < 0)
1310+
if (sol_socket_join_group(s, link->index, &groupaddr) < 0)
13411311
return -errno;
13421312

13431313
continue;
13441314
}
13451315

13461316
sol_network_addr_from_str(&groupaddr, IPV6_ALL_COAP_NODES_SCOPE_LOCAL);
1347-
if (sol_socket_join_group(fd, link->index, &groupaddr) < 0)
1317+
if (sol_socket_join_group(s, link->index, &groupaddr) < 0)
13481318
return -errno;
13491319

13501320
sol_network_addr_from_str(&groupaddr, IPV6_ALL_COAP_NODES_SCOPE_SITE);
1351-
if (sol_socket_join_group(fd, link->index, &groupaddr) < 0)
1321+
if (sol_socket_join_group(s, link->index, &groupaddr) < 0)
13521322
return -errno;
13531323
}
13541324

@@ -1366,58 +1336,53 @@ network_event(void *data, const struct sol_network_link *link, enum sol_network_
13661336
if (!(link->flags & SOL_NETWORK_LINK_RUNNING) && !(link->flags & SOL_NETWORK_LINK_MULTICAST))
13671337
return;
13681338

1369-
join_mcast_groups(server->fd, link);
1339+
join_mcast_groups(server->socket, link);
13701340
}
13711341

13721342
SOL_API struct sol_coap_server *
13731343
sol_coap_server_new(int port)
13741344
{
1375-
static bool network_init;
13761345
struct sol_network_link_addr servaddr = { .family = AF_INET6,
13771346
.port = port };
13781347
const struct sol_vector *links;
13791348
struct sol_network_link *link;
13801349
struct sol_coap_server *server;
1381-
int fd;
1350+
struct sol_socket *s;
13821351
uint16_t i;
13831352

13841353
SOL_LOG_INTERNAL_INIT_ONCE;
13851354

1386-
if (!network_init) {
1387-
network_init = sol_network_init();
1388-
if (!network_init) {
1389-
SOL_WRN("Network could not be initialized");
1390-
return NULL;
1391-
}
1392-
}
1393-
1394-
fd = socket(servaddr.family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1395-
if (fd < 0) {
1355+
s = sol_socket_new(servaddr.family, SOL_SOCKET_UDP, 0);
1356+
if (!s) {
13961357
SOL_WRN("Could not create socket (%d): %s", errno, sol_util_strerrora(errno));
13971358
return NULL;
13981359
}
13991360

1400-
if (sol_socket_bind(fd, &servaddr) < 0) {
1361+
if (sol_socket_bind(s, &servaddr) < 0) {
14011362
SOL_WRN("Could not bind socket (%d): %s", errno, sol_util_strerrora(errno));
1402-
close(fd);
1363+
sol_socket_del(s);
14031364
return NULL;
14041365
}
14051366

14061367
server = calloc(1, sizeof(*server));
14071368
if (!server) {
1408-
close(fd);
1369+
sol_socket_del(s);
14091370
return NULL;
14101371
}
1372+
14111373
server->refcnt = 1;
14121374

14131375
sol_vector_init(&server->contexts, sizeof(struct resource_context));
14141376

14151377
sol_ptr_vector_init(&server->pending);
14161378
sol_ptr_vector_init(&server->outgoing);
14171379

1418-
server->fd = fd;
1419-
server->read_watch = sol_fd_add(fd, SOL_FD_FLAGS_IN, on_receive_data, server);
1420-
SOL_NULL_CHECK_GOTO(server->read_watch, error);
1380+
server->socket = s;
1381+
if (sol_socket_set_on_read(s, on_can_read, server) < 0) {
1382+
free(server);
1383+
sol_socket_del(s);
1384+
return NULL;
1385+
}
14211386

14221387
/* From man 7 ip:
14231388
*
@@ -1436,7 +1401,7 @@ sol_coap_server_new(int port)
14361401
/* Not considering an error,
14371402
* because direct packets will work still.
14381403
*/
1439-
if (join_mcast_groups(fd, link) < 0) {
1404+
if (join_mcast_groups(s, link) < 0) {
14401405
char *name = sol_network_link_get_name(link);
14411406
SOL_WRN("Could not join multicast group, iface %s (%d): %s",
14421407
name, errno, sol_util_strerrora(errno));
@@ -1450,11 +1415,6 @@ sol_coap_server_new(int port)
14501415
SOL_DBG("New server %p on port %d", server, port);
14511416

14521417
return server;
1453-
1454-
error:
1455-
close(fd);
1456-
free(server);
1457-
return NULL;
14581418
}
14591419

14601420
SOL_API int

0 commit comments

Comments
 (0)