WIP: handle packets from the TUN device in digipeater

This is only a backup commit.
This commit is contained in:
Thomas Kolb 2024-11-10 23:13:31 +01:00
parent 816d753cfb
commit e4961bf519
5 changed files with 84 additions and 2 deletions

View file

@ -13,7 +13,7 @@ HOSTID="$1"
DEV=hamnet70 DEV=hamnet70
sudo ip tuntap add dev $DEV mode tun user $(whoami) sudo ip tuntap add dev $DEV mode tun pi user $(whoami)
sudo ip link set dev $DEV txqueuelen 16 # default is 500 sudo ip link set dev $DEV txqueuelen 16 # default is 500
sudo ip link set dev $DEV up sudo ip link set dev $DEV up
sudo ip address add dev $DEV fd73::$HOSTID/64 sudo ip address add dev $DEV fd73::$HOSTID/64

View file

@ -3,6 +3,7 @@
#include "connection_list.h" #include "connection_list.h"
#include "layer2/connection.h"
#include "results.h" #include "results.h"
#define SEQ_NR_MASK 0xF #define SEQ_NR_MASK 0xF
@ -177,3 +178,23 @@ result_t connection_list_delete_closed(connection_list_t *list)
return OK; return OK;
} }
bool connection_list_can_enqueue_packet(connection_list_t *list)
{
if(!list->head) {
return false; // no entries -> no free space
}
connection_list_entry_t *entry = list->head;
while(entry) {
if(!connection_can_enqueue_packet(&entry->connection)) {
return false;
}
entry = entry->next;
}
return true;
}

View file

@ -83,4 +83,10 @@ result_t connection_list_delete_head(connection_list_t *list);
*/ */
result_t connection_list_delete_closed(connection_list_t *list); result_t connection_list_delete_closed(connection_list_t *list);
/*!\brief Determine if a packet can be enqueued in all queues.
*
* \returns False if any queue is full, true otherwise.
*/
bool connection_list_can_enqueue_packet(connection_list_t *list);
#endif // CONNECTION_LIST_H #endif // CONNECTION_LIST_H

View file

@ -1,4 +1,7 @@
#include "layer2/packet_queue.h" #include <poll.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#define LOGGER_MODULE_NAME "digi" #define LOGGER_MODULE_NAME "digi"
#include "logger.h" #include "logger.h"
@ -10,6 +13,7 @@
#include "layer2/connection_list.h" #include "layer2/connection_list.h"
#include "layer2/ham64.h" #include "layer2/ham64.h"
#include "layer2/packet_structs.h" #include "layer2/packet_structs.h"
#include "layer2/packet_queue.h"
#include "results.h" #include "results.h"
#include "utils.h" #include "utils.h"
@ -175,6 +179,54 @@ result_t digipeater_handle_packet(digipeater_ctx_t *ctx, const uint8_t *buf, siz
} }
result_t digipeater_fill_packet_queues_from_tundev(digipeater_ctx_t *ctx, int tun_fd)
{
// first check if any queue is already full, so we don't have to drop packets
// from the TUN device queue.
if(!connection_list_can_enqueue_packet(&ctx->conn_list)) {
LOG(LVL_DEBUG, "No free space in queues.");
return OK; // do nothing
}
struct pollfd pfd_tun;
memset(&pfd_tun, 0, sizeof(pfd_tun));
pfd_tun.fd = tun_fd;
pfd_tun.events = POLLIN;
while(true) {
int ret = poll(&pfd_tun, 1, 0 /* timeout */);
if(ret < 0) {
LOG(LVL_ERR, "poll: %s", strerror(errno));
return ERR_SYSCALL;
} else if(ret == 0) {
// no more packets
break;
} else {
// a packet is available -> read it
static const size_t packetbuf_size = 2048;
uint8_t packetbuf[packetbuf_size];
ret = read(tun_fd, packetbuf, packetbuf_size);
if(ret < 0) {
LOG(LVL_ERR, "read: %s", strerror(errno));
return ERR_SYSCALL;
} else if(ret == 0) {
// no more data, should not happen
break;
}
LOG(LVL_DUMP, "TUN Flags: 0x%04x", *(uint16_t*)packetbuf);
LOG(LVL_DUMP, "TUN Proto: 0x%04x", *((uint16_t*)packetbuf + 1));
// FIXME:
//ERR_CHECK(connection_list_enqueue_packet(entry->connection, packetbuf, ret));
}
}
return OK;
}
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();

View file

@ -260,6 +260,9 @@ int main(int argc, char **argv)
break; break;
} }
LOG(LVL_DUMP, "TUN Flags: 0x%04x", *(uint16_t*)packetbuf);
LOG(LVL_DUMP, "TUN Proto: 0x%04x", *((uint16_t*)packetbuf + 1));
RESULT_CHECK(connection_enqueue_packet(&l2conn, packetbuf, ret)); RESULT_CHECK(connection_enqueue_packet(&l2conn, packetbuf, ret));
} }
} }