digipeater: improve beacon handling
This commit is contained in:
parent
580e4005ed
commit
1c8e46f54a
|
@ -449,8 +449,6 @@ void connection_handle_ack(connection_ctx_t *ctx, uint8_t acked_seq, bool do_ack
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->next_packet_index = 0;
|
|
||||||
|
|
||||||
size_t packets_to_remove = 0;
|
size_t packets_to_remove = 0;
|
||||||
size_t packets_available = packet_queue_get_used_space(&ctx->packet_queue);
|
size_t packets_available = packet_queue_get_used_space(&ctx->packet_queue);
|
||||||
|
|
||||||
|
@ -464,13 +462,21 @@ void connection_handle_ack(connection_ctx_t *ctx, uint8_t acked_seq, bool do_ack
|
||||||
packets_to_remove++;
|
packets_to_remove++;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_queue_delete(&ctx->packet_queue, packets_to_remove);
|
if(packets_to_remove != 0) {
|
||||||
|
packet_queue_delete(&ctx->packet_queue, packets_to_remove);
|
||||||
|
|
||||||
packets_available = packet_queue_get_used_space(&ctx->packet_queue);
|
// send the next requested packet (all previous ones were deleted above).
|
||||||
|
assert(ctx->next_packet_index >= packets_to_remove);
|
||||||
|
ctx->next_packet_index -= packets_to_remove;
|
||||||
|
|
||||||
LOG(LVL_DEBUG, "handling ack for seq_nr %u, removed %zu packets, %zu packets remaining.", acked_seq, packets_to_remove, packets_available);
|
packets_available = packet_queue_get_used_space(&ctx->packet_queue);
|
||||||
|
|
||||||
ctx->retransmit_time = get_hires_time() + HRTIME_MS(RETRANSMIT_TIMEOUT_MS);
|
LOG(LVL_DEBUG, "handling ack for seq_nr %u, removed %zu packets, %zu packets remaining.", acked_seq, packets_to_remove, packets_available);
|
||||||
|
|
||||||
|
ctx->retransmit_time = get_hires_time() + HRTIME_MS(RETRANSMIT_TIMEOUT_MS);
|
||||||
|
} else {
|
||||||
|
LOG(LVL_DEBUG, "duplicate ACK for seq_nr %u", acked_seq);
|
||||||
|
}
|
||||||
|
|
||||||
if(do_ack && packets_available == 0) {
|
if(do_ack && packets_available == 0) {
|
||||||
// no packets left in queue, but an acknowledgement must be
|
// no packets left in queue, but an acknowledgement must be
|
||||||
|
|
|
@ -79,6 +79,25 @@ static result_t digipeater_handle_beacon_responses(digipeater_ctx_t *ctx, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t encode_beacon_packet(digipeater_ctx_t *ctx, uint8_t *buf, size_t buf_len)
|
||||||
|
{
|
||||||
|
// build a beacon packet
|
||||||
|
layer2_packet_header_t header;
|
||||||
|
|
||||||
|
ham64_t broadcast = {{0xFFFF, 0, 0, 0}, 1};
|
||||||
|
|
||||||
|
header.dst_addr = broadcast;
|
||||||
|
header.src_addr = ctx->my_addr;
|
||||||
|
header.msg_type = L2_MSG_TYPE_CONN_MGMT;
|
||||||
|
header.rx_seq_nr = 0; // unused
|
||||||
|
header.tx_seq_nr = 0; // unused
|
||||||
|
header.tx_request = 1;
|
||||||
|
|
||||||
|
uint8_t payload[1] = {CONN_MGMT_TYPE_BEACON};
|
||||||
|
return layer2_encode_packet(&header, payload, 1, buf, buf_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
result_t digipeater_init(digipeater_ctx_t *ctx, const ham64_t *my_addr, digipeater_data_callback_t data_cb)
|
result_t digipeater_init(digipeater_ctx_t *ctx, const ham64_t *my_addr, digipeater_data_callback_t data_cb)
|
||||||
{
|
{
|
||||||
ctx->my_addr = *my_addr;
|
ctx->my_addr = *my_addr;
|
||||||
|
@ -239,31 +258,11 @@ result_t digipeater_fill_packet_queues_from_tundev(digipeater_ctx_t *ctx, int tu
|
||||||
size_t digipeater_encode_next_packet(digipeater_ctx_t *ctx, uint8_t *buf, size_t buf_len, bool *end_burst)
|
size_t digipeater_encode_next_packet(digipeater_ctx_t *ctx, uint8_t *buf, size_t buf_len, bool *end_burst)
|
||||||
{
|
{
|
||||||
uint64_t now = get_hires_time();
|
uint64_t now = get_hires_time();
|
||||||
|
|
||||||
size_t packet_size = 0;
|
size_t packet_size = 0;
|
||||||
|
|
||||||
*end_burst = false;
|
*end_burst = false;
|
||||||
|
|
||||||
if(now > ctx->next_beacon_time) {
|
|
||||||
// build a beacon packet
|
|
||||||
layer2_packet_header_t header;
|
|
||||||
|
|
||||||
ham64_t broadcast = {{0xFFFF, 0, 0, 0}, 1};
|
|
||||||
|
|
||||||
header.dst_addr = broadcast;
|
|
||||||
header.src_addr = ctx->my_addr;
|
|
||||||
header.msg_type = L2_MSG_TYPE_CONN_MGMT;
|
|
||||||
header.rx_seq_nr = 0; // unused
|
|
||||||
header.tx_seq_nr = 0; // unused
|
|
||||||
header.tx_request = 1;
|
|
||||||
|
|
||||||
uint8_t payload[1] = {CONN_MGMT_TYPE_BEACON};
|
|
||||||
packet_size = layer2_encode_packet(&header, payload, 1, buf, buf_len);
|
|
||||||
|
|
||||||
ctx->state = DIGIPEATER_STATE_BEACON;
|
|
||||||
*end_burst = true;
|
|
||||||
return packet_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send packets from the one-shot queue
|
// send packets from the one-shot queue
|
||||||
const packet_queue_entry_t *queue_entry = packet_queue_get(&ctx->oneshot_queue, 0);
|
const packet_queue_entry_t *queue_entry = packet_queue_get(&ctx->oneshot_queue, 0);
|
||||||
if(queue_entry) {
|
if(queue_entry) {
|
||||||
|
@ -275,18 +274,27 @@ size_t digipeater_encode_next_packet(digipeater_ctx_t *ctx, uint8_t *buf, size_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull packets from the current connection
|
switch(ctx->state) {
|
||||||
|
case DIGIPEATER_STATE_BEACON:
|
||||||
|
packet_size = encode_beacon_packet(ctx, buf, buf_len);
|
||||||
|
*end_burst = true;
|
||||||
|
break;
|
||||||
|
|
||||||
connection_list_entry_t *head = connection_list_get_head(&ctx->conn_list);
|
case DIGIPEATER_STATE_CONN: {
|
||||||
if(!head) {
|
// pull packets from the current connection
|
||||||
return 0;
|
connection_list_entry_t *head = connection_list_get_head(&ctx->conn_list);
|
||||||
}
|
if(!head) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
connection_ctx_t *conn = &head->connection;
|
connection_ctx_t *conn = &head->connection;
|
||||||
if(connection_can_transmit(conn)) {
|
if(connection_can_transmit(conn)) {
|
||||||
packet_size = connection_encode_next_packet(conn, buf, buf_len, end_burst);
|
packet_size = connection_encode_next_packet(conn, buf, buf_len, end_burst);
|
||||||
|
|
||||||
ctx->state = DIGIPEATER_STATE_CONN;
|
ctx->state = DIGIPEATER_STATE_CONN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return packet_size;
|
return packet_size;
|
||||||
|
@ -301,6 +309,10 @@ bool digipeater_can_transmit(digipeater_ctx_t *ctx)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(packet_queue_get_used_space(&ctx->oneshot_queue) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
connection_list_entry_t *head = connection_list_get_head(&ctx->conn_list);
|
connection_list_entry_t *head = connection_list_get_head(&ctx->conn_list);
|
||||||
if(head) {
|
if(head) {
|
||||||
return connection_can_transmit(&head->connection);
|
return connection_can_transmit(&head->connection);
|
||||||
|
@ -320,12 +332,17 @@ result_t digipeater_end_interval(digipeater_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
uint64_t now = get_hires_time();
|
uint64_t now = get_hires_time();
|
||||||
|
|
||||||
// TODO: adjust the time based on connection activity; right now this results
|
if(now >= ctx->next_beacon_time) {
|
||||||
// in round-robin scheduling
|
ctx->next_beacon_time += HRTIME_MS(BEACON_INTERVAL_MS);
|
||||||
connection_list_reschedule_head(&ctx->conn_list, now + HRTIME_MS(MIN_INTERVAL_TIME_MS));
|
ctx->state = DIGIPEATER_STATE_BEACON;
|
||||||
|
} else {
|
||||||
|
// TODO: adjust the time based on connection activity; right now this results
|
||||||
|
// in round-robin scheduling
|
||||||
|
connection_list_reschedule_head(&ctx->conn_list, now + HRTIME_MS(MIN_INTERVAL_TIME_MS));
|
||||||
|
|
||||||
ctx->state = DIGIPEATER_STATE_CONN;
|
ctx->state = DIGIPEATER_STATE_CONN;
|
||||||
ctx->interval_end_time = now + HRTIME_MS(MIN_INTERVAL_TIME_MS);
|
ctx->interval_end_time = now + HRTIME_MS(MIN_INTERVAL_TIME_MS);
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ typedef enum {
|
||||||
} digipeater_state_t;
|
} digipeater_state_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
// FIXME: rename to Cycle
|
||||||
DIGIPEATER_EVT_INTERVAL_END, //!< The current interval has ended and new packets should be transmitted.
|
DIGIPEATER_EVT_INTERVAL_END, //!< The current interval has ended and new packets should be transmitted.
|
||||||
} digipeater_evt_t;
|
} digipeater_evt_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue