Skip to content

Commit

Permalink
coap_io.c: Add in support for getting state of internal file descriptors
Browse files Browse the repository at this point in the history
Add in a new function coap_io_get_fds() to get the lists of (internal
to libcoap) file descriptors that are in a read or write pending state.
  • Loading branch information
mrdeep1 committed Dec 14, 2024
1 parent ebb8f07 commit 39b3d59
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 1 deletion.
20 changes: 20 additions & 0 deletions include/coap3/coap_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,26 @@ COAP_API void coap_io_do_epoll(coap_context_t *ctx, struct epoll_event *events,
*/
COAP_API coap_fd_t coap_socket_get_fd(coap_socket_t *socket);

/*
* Get the current libcoap usage of file descriptors that are in a read or write pending state.
*
* @param context The current CoAP context.
* @param read_fds Array to populate with file descriptors in the read pending state.
* @param have_read_fds Updated wth the number of fds found in read pending state.
* @param max_read_fds Maximum size of read_fds[] array.
* @param write_fds Array to populate with file descriptors in the write pending state.
* @param have_write_fds Updated wth the number of fds found in write pending state.
* @param max_write_fds Maximum size of write_fds[] array.
*
* @return @c 1 if successful, else @c 0 if error.
*/
COAP_API unsigned int coap_io_get_fds(coap_context_t *context, coap_fd_t read_fds[],
unsigned int *have_read_fds,
unsigned int max_read_fds,
coap_fd_t write_fds[],
unsigned int *have_write_fds,
unsigned int max_write_dfs);

/**
* Get the libcoap internal flags for a socket. This can be used to
* integrate libcoap in an external event loop instead of using one of its
Expand Down
22 changes: 22 additions & 0 deletions include/coap3/coap_net_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,28 @@ int coap_io_process_with_fds_lkd(coap_context_t *ctx, uint32_t timeout_ms,
fd_set *exceptfds);
#endif /* ! RIOT_VERSION && ! WITH_CONTIKI */

/*
* Get the current libcoap usage of file descriptors that are in a read or write pending state.
*
* Note: This function must be called in the locked state.
*
* @param context The current CoAP context.
* @param read_fds Array to populate with file descriptors in the read pending state.
* @param have_read_fds Updated wth the number of fds found in read pending state.
* @param max_read_fds Maximum size of read_fds[] array.
* @param write_fds Array to populate with file descriptors in the write pending state.
* @param have_write_fds Updated wth the number of fds found in write pending state.
* @param max_write_fds Maximum size of write_fds[] array.
*
* @return @c 1 if successful, else @c 0 if error.
*/
unsigned int coap_io_get_fds_lkd(coap_context_t *context, coap_fd_t read_fds[],
unsigned int *have_read_fds,
unsigned int max_read_fds,
coap_fd_t write_fds[],
unsigned int *have_write_fds,
unsigned int max_write_dfs);

/**
* Sends a CoAP message to given peer. The memory that is
* allocated for the pdu will be released by coap_send_lkd().
Expand Down
1 change: 1 addition & 0 deletions libcoap-3.map
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ global:
coap_insert_optlist;
coap_io_do_epoll;
coap_io_do_io;
coap_io_get_fds;
coap_io_pending;
coap_io_prepare_epoll;
coap_io_prepare_io;
Expand Down
1 change: 1 addition & 0 deletions libcoap-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ coap_host_is_unix_domain
coap_insert_optlist
coap_io_do_epoll
coap_io_do_io
coap_io_get_fds
coap_io_pending
coap_io_prepare_epoll
coap_io_prepare_io
Expand Down
1 change: 1 addition & 0 deletions man/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ install-man: install-man3 install-man5 install-man7
@echo ".so man3/coap_deprecated.3" > coap_set_event_handler.3
@echo ".so man3/coap_deprecated.3" > coap_write.3
@echo ".so man3/coap_io.3" > coap_io_pending.3
@echo ".so man3/coap_io.3" > coap_io_get_fds.3
@echo ".so man3/coap_io.3" > coap_can_exit.3
@echo ".so man3/coap_io.3" > coap_socket_get_fd.3
@echo ".so man3/coap_io.3" > coap_socket_get_flags.3
Expand Down
22 changes: 21 additions & 1 deletion man/coap_io.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ coap_io_do_io,
coap_io_prepare_epoll,
coap_io_do_epoll,
coap_io_pending,
coap_io_get_fds,
coap_can_exit,
coap_socket_get_fd,
coap_socket_get_flags,
Expand Down Expand Up @@ -51,6 +52,10 @@ size_t _nevents_)*;

*int coap_io_pending(coap_context_t *_context_)*;

*unsigned int coap_io_get_fds(coap_context_t *_context_, coap_fd_t _read_fds_[],
unsigned int *_have_read_fds_, unsigned int _max_read_fds_, coap_fd_t _write_fds_[],
unsigned int *_have_write_fds_, unsigned int _max_write_dfs_)*;

*int coap_can_exit(coap_context_t *_context_)*;

*coap_fd_t coap_socket_get_fd(coap_socket_t *socket);*
Expand All @@ -69,7 +74,7 @@ or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with
DESCRIPTION
-----------
After setting up all the contexts, resources, endpoints sessions etc., the
underlying CoAP and (D)TLS need to send (and possible re-send) created packets
underlying CoAP and (D)TLS need to send (and possibly re-send) created packets
as well as receive packets for processing.

The *coap_io_process*() function is the primary function applications should
Expand Down Expand Up @@ -204,6 +209,19 @@ The *coap_io_pending*() function checks to see if there are any outstanding
i/o requests / responses associated with _context_ as well as if Observe has
been set up (client only) and large transfers are in process.

*Function: coap_io_get_fds()*

The *coap_io_get_fds*() function is used to get all of the libcoap internally
used file descriptors associated with _context_ in a read or write pending state.

_read_fds_[] is a defined array to hold all the file descriptors that are in a
read pending state with a size of _max_read_fds_. _have_read_fds_ is returned
with the number of file descriptors in _read_fds_[].

_write_fds_[] is a defined array to hold all the file descriptors that are in a
write pending state with a size of _max_write_fds_. _have_write_fds_ is returned
with the number of file descriptors in _write_fds_[].

*Function: coap_can_exit()*

The *coap_can_exit*() function checks to see if there are any outstanding
Expand Down Expand Up @@ -241,6 +259,8 @@ milli-seconds that need to be waited before the function should next be called.

*coap_io_pending*() returns 1 if there is outstanding i/o else returns 0.

*coap_io_get_fds*() returns 1 if file descriptors returned, else returns 0.

*coap_can_exit*() returns 1 if there is nothing outstanding to transmit else
returns 0.

Expand Down
100 changes: 100 additions & 0 deletions src/coap_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,106 @@ coap_io_prepare_io_lkd(coap_context_t *ctx,
return (unsigned int)((timeout * 1000 + COAP_TICKS_PER_SECOND - 1) / COAP_TICKS_PER_SECOND);
}

/*
* return 0 Insufficient space to hold fds, or fds not supported
* 1 All fds found
*/
COAP_API unsigned int
coap_io_get_fds(coap_context_t *ctx,
coap_fd_t read_fds[],
unsigned int *have_read_fds,
unsigned int max_read_fds,
coap_fd_t write_fds[],
unsigned int *have_write_fds,
unsigned int max_write_fds) {
unsigned int ret;

coap_lock_lock(ctx, return 0);
ret = coap_io_get_fds_lkd(ctx, read_fds, have_read_fds, max_read_fds, write_fds,
have_write_fds, max_write_fds);
coap_lock_unlock(ctx);
return ret;
}

#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
static int
coap_add_fd(coap_fd_t fd, coap_fd_t this_fds[], unsigned int *have_this_fds,
unsigned int max_this_fds) {
if (*have_this_fds < max_this_fds) {
this_fds[(*have_this_fds)++] = fd;
return 1;
}
coap_log_warn("coap_io_get_fds: Insufficient space for new fd (%u >= %u)\n", *have_this_fds,
max_this_fds);
return 0;
}

/*
* return 0 Insufficient space to hold fds, or fds not supported
* 1 All fds found
*/
unsigned int
coap_io_get_fds_lkd(coap_context_t *ctx,
coap_fd_t read_fds[],
unsigned int *have_read_fds,
unsigned int max_read_fds,
coap_fd_t write_fds[],
unsigned int *have_write_fds,
unsigned int max_write_fds) {
*have_read_fds = 0;
*have_write_fds = 0;

#ifdef COAP_EPOLL_SUPPORT
if (!coap_add_fd(ctx->epfd, read_fds, have_read_fds, max_read_fds))
return 0;
if (!coap_add_fd(ctx->epfd, write_fds, have_write_fds, max_write_fds))
return 0;
return 1;
#else /* ! COAP_EPOLL_SUPPORT */
unsigned int i;

for (i = 0; i < ctx->num_sockets; i++) {
if (ctx->sockets[i]->flags & (COAP_SOCKET_WANT_READ|COAP_SOCKET_WANT_ACCEPT)) {
if (!coap_add_fd(ctx->sockets[i]->fd, read_fds, have_read_fds, max_read_fds))
return 0;
}
if (ctx->sockets[i]->flags & (COAP_SOCKET_WANT_WRITE|COAP_SOCKET_WANT_CONNECT)) {
if (!coap_add_fd(ctx->sockets[i]->fd, write_fds, have_write_fds, max_write_fds))
return 0;
}
}
return 1;
#endif /* ! COAP_EPOLL_SUPPORT */
}

#else /* ! WITH_LWIP && ! WITH_CONTIKI && ! RIOT_VERSION*/

/*
* return 0 Insufficient space to hold fds, or fds not supported
* 1 All fds found
*/
unsigned int
coap_io_get_fds_lkd(coap_context_t *ctx,
coap_fd_t read_fds[],
unsigned int *have_read_fds,
unsigned int max_read_fds,
coap_fd_t write_fds[],
unsigned int *have_write_fds,
unsigned int max_write_fds) {
(void)ctx;
(void)read_fds;
(void)max_read_fds;
(void)write_fds;
(void)max_write_fds;

*have_read_fds = 0;
*have_write_fds = 0;

coap_log_warn("coap_io_get_fds: Not supported\n");
return 0;
}
#endif /* WITH_LWIP || WITH_CONTIKI && ! RIOT_VERSION*/

#if !defined(WITH_LWIP) && !defined(CONTIKI) && !defined(RIOT_VERSION)
COAP_API int
coap_io_process(coap_context_t *ctx, uint32_t timeout_ms) {
Expand Down

0 comments on commit 39b3d59

Please sign in to comment.