layer2: Remove event callbacks

Instead, connection and digipeater now update a event code passed by reference
to the maintain() function. This was the only place where the callback was
called before.

Minor side effect: maintain must be called multiple times if multiple events
trigger at the same time.
This commit is contained in:
Thomas Kolb 2024-12-03 22:18:46 +01:00
parent 49dacffde1
commit a0ccf9699a
5 changed files with 33 additions and 49 deletions

View file

@ -18,9 +18,7 @@
result_t connection_init(
connection_ctx_t *ctx,
const ham64_t *my_addr,
const ham64_t *peer_addr,
connection_event_callback_t event_cb,
void *user_ctx)
const ham64_t *peer_addr)
{
ctx->last_acked_seq = 0;
ctx->next_expected_seq = 0;
@ -32,14 +30,10 @@ result_t connection_init(
ctx->my_addr = *my_addr;
ctx->peer_addr = *peer_addr;
ctx->event_cb = event_cb;
uint64_t now = get_hires_time();
ctx->last_rx_time = now;
ctx->retransmit_time = 0;
ctx->user_context = user_ctx;
// calculate IPv6 address
struct in6_addr net_addr;
inet_pton(AF_INET6, IPV6_NET, &net_addr);
@ -518,14 +512,14 @@ bool connection_is_closed(const connection_ctx_t *ctx)
}
result_t connection_maintain(connection_ctx_t *ctx)
result_t connection_maintain(connection_ctx_t *ctx, connection_evt_t *evt)
{
uint64_t now = get_hires_time();
if(now > ctx->last_rx_time + HRTIME_MS(CONNECTION_TIMEOUT_MS)) {
LOG(LVL_INFO, "Connection timed out.");
ctx->conn_state = CONN_STATE_CLOSED;
ctx->event_cb(ctx, CONN_EVT_TIMEOUT, ctx->user_context);
*evt = CONN_EVT_TIMEOUT;
return OK;
}
@ -533,7 +527,8 @@ result_t connection_maintain(connection_ctx_t *ctx)
LOG(LVL_INFO, "Retransmit triggered.");
ctx->retransmit_time = 0;
connection_restart_tx(ctx);
ctx->event_cb(ctx, CONN_EVT_RETRANSMIT, ctx->user_context);
*evt = CONN_EVT_RETRANSMIT;
return OK;
}
return OK;

View file

@ -27,18 +27,14 @@ typedef enum {
} connection_state_t;
typedef enum {
CONN_EVT_NONE, //!< No event has occurred
CONN_EVT_TIMEOUT, //!< The connection timed out because no packets were received
CONN_EVT_RETRANSMIT, //!< Packet queue transmission is restarted
} connection_evt_t;
/*!\brief Type for a callback function that is called on various connection events. */
typedef void (*connection_event_callback_t)(struct connection_ctx_s *conn, connection_evt_t evt, void *user_ctx);
typedef struct connection_ctx_s {
connection_state_t conn_state; //!< State of the connection.
connection_event_callback_t event_cb; //!< Callback function for event signalling.
ham64_t my_addr; //!< The local link layer address.
ham64_t peer_addr; //!< The link layer address of the peer.
@ -54,8 +50,6 @@ typedef struct connection_ctx_s {
uint64_t retransmit_time; //!< Time when a retransmit shall be triggered.
uint64_t last_rx_time; //!< Time when a packet was last received and decoded.
void *user_context; //!< An arbitrary pointer that can set by the user.
} connection_ctx_t;
@ -64,16 +58,12 @@ typedef struct connection_ctx_s {
* \param ctx The connection context to initialize.
* \param my_addr The local link layer address.
* \param peer_addr The remote link layer address.
* \param event_cb Callback for connection events.
* \param user_ctx User context pointer (for arbitrary data).
* \returns OK if everything worked or a fitting error code.
*/
result_t connection_init(
connection_ctx_t *ctx,
const ham64_t *my_addr,
const ham64_t *peer_addr,
connection_event_callback_t event_cb,
void *user_ctx);
const ham64_t *peer_addr);
/*!\brief Destroy the given layer 2 connection context.
*/
@ -189,8 +179,11 @@ bool connection_is_closed(const connection_ctx_t *ctx);
/*!\brief Handle internal maintenance tasks.
*
* This should be called periodically to handle timeouts and retransmissions.
*
* \param ctx[in] The connection context.
* \param evt[out] Set to an event that occurred, or CONN_EVT_NONE.
*/
result_t connection_maintain(connection_ctx_t *ctx);
result_t connection_maintain(connection_ctx_t *ctx, connection_evt_t *evt);
/*!\brief Check if the given IPv6 peer address belongs to this connection.
*

View file

@ -17,23 +17,6 @@
#include "results.h"
#include "utils.h"
void conn_event_cb(struct connection_ctx_s *conn, connection_evt_t evt, void *user_ctx)
{
(void)conn;
digipeater_ctx_t *digi_ctx = user_ctx;
switch(evt) {
case CONN_EVT_TIMEOUT:
// connection has been closed by timeout -> clean up the list
connection_list_delete_closed(&digi_ctx->conn_list);
break;
default:
// do nothing
break;
}
}
static result_t digipeater_handle_beacon_responses(digipeater_ctx_t *ctx, const layer2_packet_header_t *header, const uint8_t *buf, size_t buf_len)
{
LOG(LVL_DEBUG, "Handling beacon response packet.");
@ -60,7 +43,7 @@ static result_t digipeater_handle_beacon_responses(digipeater_ctx_t *ctx, const
// and add it at the beginning of the connection list.
connection_ctx_t new_conn;
ERR_CHECK(connection_init(&new_conn, &ctx->my_addr, &header->src_addr, conn_event_cb, ctx));
ERR_CHECK(connection_init(&new_conn, &ctx->my_addr, &header->src_addr));
ERR_CHECK(connection_send_parameters(&new_conn));
@ -369,7 +352,19 @@ result_t digipeater_maintain(digipeater_ctx_t *ctx)
LOG(LVL_INFO, "No active connection -> force beacon state for packet handling.");
ctx->state = DIGIPEATER_STATE_BEACON;
} else {
ERR_CHECK(connection_maintain(&head->connection));
connection_evt_t evt;
ERR_CHECK(connection_maintain(&head->connection, &evt));
switch(evt) {
case CONN_EVT_TIMEOUT:
// connection has been closed by timeout -> clean up the list
connection_list_delete_closed(&ctx->conn_list);
break;
default:
// do nothing
break;
}
}
break;
}

View file

@ -26,14 +26,9 @@ typedef enum {
DIGIPEATER_EVT_INTERVAL_END, //!< The current cycle has ended and new packets should be transmitted.
} digipeater_evt_t;
/*!\brief Type for a callback function that is called when certain events occur. */
typedef void (*digipeater_evt_callback_t)(struct digipeater_ctx_s *digi, digipeater_evt_t evt);
typedef struct digipeater_ctx_s {
digipeater_state_t state; //!< Current operating state
digipeater_evt_callback_t event_cb; //!< Callback function for events.
ham64_t my_addr; //!< The local link layer address.
packet_queue_t oneshot_queue; //!< Queue for packets that are sent once and connection-independent

View file

@ -161,7 +161,7 @@ int main(int argc, char **argv)
ham64_t my_address, peer_address;
ham64_encode(MY_CALL, &my_address);
ham64_encode(PEER_CALL, &peer_address);
RESULT_CHECK(connection_init(&l2conn, &my_address, &peer_address, conn_evt_cb, NULL));
RESULT_CHECK(connection_init(&l2conn, &my_address, &peer_address));
// force connection into the established state
l2conn.conn_state = CONN_STATE_ESTABLISHED;
@ -232,7 +232,13 @@ int main(int argc, char **argv)
while(m_running) {
uint64_t now = get_hires_time();
RESULT_CHECK(connection_maintain(&l2conn));
connection_evt_t evt;
RESULT_CHECK(connection_maintain(&l2conn, &evt));
if(evt == CONN_EVT_TIMEOUT) {
LOG(LVL_ERR, "Connection timed out. Shutting down.");
break;
}
// fill the TX queue from the TUN device
while(connection_can_enqueue_packet(&l2conn)) {