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:
parent
49dacffde1
commit
a0ccf9699a
|
@ -18,9 +18,7 @@
|
||||||
result_t connection_init(
|
result_t connection_init(
|
||||||
connection_ctx_t *ctx,
|
connection_ctx_t *ctx,
|
||||||
const ham64_t *my_addr,
|
const ham64_t *my_addr,
|
||||||
const ham64_t *peer_addr,
|
const ham64_t *peer_addr)
|
||||||
connection_event_callback_t event_cb,
|
|
||||||
void *user_ctx)
|
|
||||||
{
|
{
|
||||||
ctx->last_acked_seq = 0;
|
ctx->last_acked_seq = 0;
|
||||||
ctx->next_expected_seq = 0;
|
ctx->next_expected_seq = 0;
|
||||||
|
@ -32,14 +30,10 @@ result_t connection_init(
|
||||||
ctx->my_addr = *my_addr;
|
ctx->my_addr = *my_addr;
|
||||||
ctx->peer_addr = *peer_addr;
|
ctx->peer_addr = *peer_addr;
|
||||||
|
|
||||||
ctx->event_cb = event_cb;
|
|
||||||
|
|
||||||
uint64_t now = get_hires_time();
|
uint64_t now = get_hires_time();
|
||||||
ctx->last_rx_time = now;
|
ctx->last_rx_time = now;
|
||||||
ctx->retransmit_time = 0;
|
ctx->retransmit_time = 0;
|
||||||
|
|
||||||
ctx->user_context = user_ctx;
|
|
||||||
|
|
||||||
// calculate IPv6 address
|
// calculate IPv6 address
|
||||||
struct in6_addr net_addr;
|
struct in6_addr net_addr;
|
||||||
inet_pton(AF_INET6, IPV6_NET, &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();
|
uint64_t now = get_hires_time();
|
||||||
|
|
||||||
if(now > ctx->last_rx_time + HRTIME_MS(CONNECTION_TIMEOUT_MS)) {
|
if(now > ctx->last_rx_time + HRTIME_MS(CONNECTION_TIMEOUT_MS)) {
|
||||||
LOG(LVL_INFO, "Connection timed out.");
|
LOG(LVL_INFO, "Connection timed out.");
|
||||||
ctx->conn_state = CONN_STATE_CLOSED;
|
ctx->conn_state = CONN_STATE_CLOSED;
|
||||||
ctx->event_cb(ctx, CONN_EVT_TIMEOUT, ctx->user_context);
|
*evt = CONN_EVT_TIMEOUT;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +527,8 @@ result_t connection_maintain(connection_ctx_t *ctx)
|
||||||
LOG(LVL_INFO, "Retransmit triggered.");
|
LOG(LVL_INFO, "Retransmit triggered.");
|
||||||
ctx->retransmit_time = 0;
|
ctx->retransmit_time = 0;
|
||||||
connection_restart_tx(ctx);
|
connection_restart_tx(ctx);
|
||||||
ctx->event_cb(ctx, CONN_EVT_RETRANSMIT, ctx->user_context);
|
*evt = CONN_EVT_RETRANSMIT;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
@ -27,18 +27,14 @@ typedef enum {
|
||||||
} connection_state_t;
|
} connection_state_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
CONN_EVT_NONE, //!< No event has occurred
|
||||||
CONN_EVT_TIMEOUT, //!< The connection timed out because no packets were received
|
CONN_EVT_TIMEOUT, //!< The connection timed out because no packets were received
|
||||||
CONN_EVT_RETRANSMIT, //!< Packet queue transmission is restarted
|
CONN_EVT_RETRANSMIT, //!< Packet queue transmission is restarted
|
||||||
} connection_evt_t;
|
} 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 {
|
typedef struct connection_ctx_s {
|
||||||
connection_state_t conn_state; //!< State of the connection.
|
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 my_addr; //!< The local link layer address.
|
||||||
ham64_t peer_addr; //!< The link layer address of the peer.
|
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 retransmit_time; //!< Time when a retransmit shall be triggered.
|
||||||
uint64_t last_rx_time; //!< Time when a packet was last received and decoded.
|
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;
|
} connection_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,16 +58,12 @@ typedef struct connection_ctx_s {
|
||||||
* \param ctx The connection context to initialize.
|
* \param ctx The connection context to initialize.
|
||||||
* \param my_addr The local link layer address.
|
* \param my_addr The local link layer address.
|
||||||
* \param peer_addr The remote 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.
|
* \returns OK if everything worked or a fitting error code.
|
||||||
*/
|
*/
|
||||||
result_t connection_init(
|
result_t connection_init(
|
||||||
connection_ctx_t *ctx,
|
connection_ctx_t *ctx,
|
||||||
const ham64_t *my_addr,
|
const ham64_t *my_addr,
|
||||||
const ham64_t *peer_addr,
|
const ham64_t *peer_addr);
|
||||||
connection_event_callback_t event_cb,
|
|
||||||
void *user_ctx);
|
|
||||||
|
|
||||||
/*!\brief Destroy the given layer 2 connection context.
|
/*!\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.
|
/*!\brief Handle internal maintenance tasks.
|
||||||
*
|
*
|
||||||
* This should be called periodically to handle timeouts and retransmissions.
|
* 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.
|
/*!\brief Check if the given IPv6 peer address belongs to this connection.
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,23 +17,6 @@
|
||||||
#include "results.h"
|
#include "results.h"
|
||||||
#include "utils.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)
|
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.");
|
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.
|
// and add it at the beginning of the connection list.
|
||||||
|
|
||||||
connection_ctx_t new_conn;
|
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));
|
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.");
|
LOG(LVL_INFO, "No active connection -> force beacon state for packet handling.");
|
||||||
ctx->state = DIGIPEATER_STATE_BEACON;
|
ctx->state = DIGIPEATER_STATE_BEACON;
|
||||||
} else {
|
} 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,9 @@ typedef enum {
|
||||||
DIGIPEATER_EVT_INTERVAL_END, //!< The current cycle has ended and new packets should be transmitted.
|
DIGIPEATER_EVT_INTERVAL_END, //!< The current cycle has ended and new packets should be transmitted.
|
||||||
} digipeater_evt_t;
|
} 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 {
|
typedef struct digipeater_ctx_s {
|
||||||
digipeater_state_t state; //!< Current operating state
|
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.
|
ham64_t my_addr; //!< The local link layer address.
|
||||||
|
|
||||||
packet_queue_t oneshot_queue; //!< Queue for packets that are sent once and connection-independent
|
packet_queue_t oneshot_queue; //!< Queue for packets that are sent once and connection-independent
|
||||||
|
|
|
@ -161,7 +161,7 @@ int main(int argc, char **argv)
|
||||||
ham64_t my_address, peer_address;
|
ham64_t my_address, peer_address;
|
||||||
ham64_encode(MY_CALL, &my_address);
|
ham64_encode(MY_CALL, &my_address);
|
||||||
ham64_encode(PEER_CALL, &peer_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
|
// force connection into the established state
|
||||||
l2conn.conn_state = CONN_STATE_ESTABLISHED;
|
l2conn.conn_state = CONN_STATE_ESTABLISHED;
|
||||||
|
@ -232,7 +232,13 @@ int main(int argc, char **argv)
|
||||||
while(m_running) {
|
while(m_running) {
|
||||||
uint64_t now = get_hires_time();
|
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
|
// fill the TX queue from the TUN device
|
||||||
while(connection_can_enqueue_packet(&l2conn)) {
|
while(connection_can_enqueue_packet(&l2conn)) {
|
||||||
|
|
Loading…
Reference in a new issue