From dcf30472717f02a4857426e9ebdea30ae53622cb Mon Sep 17 00:00:00 2001
From: "david.maul" <david.maul@informatik.hs-fulda.de>
Date: Thu, 13 Feb 2025 21:18:37 +0100
Subject: [PATCH] fix: prepare message only once for sending

---
 kernel/kmod.c | 72 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 46 insertions(+), 26 deletions(-)

diff --git a/kernel/kmod.c b/kernel/kmod.c
index 387109c..7dfff87 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -17,7 +17,7 @@
 #define SLOTS 4
 #define SLOT_INTERVAL_NS 10000000
 
-#define MAX_VALUES 16
+#define MAX_MEASUREMENTS 16
 
 #define BAUD_RATE 9600
 #define BIT_TIME_US (1000000 / BAUD_RATE)
@@ -28,6 +28,7 @@ static struct class *class = NULL;
 static struct cdev mycdev;
 
 typedef struct packet {
+  uint8_t magic;
   data_t data;
   uint32_t crc;
 } packet_t;
@@ -42,19 +43,48 @@ static struct task_struct *timed_thread;
 static DECLARE_WAIT_QUEUE_HEAD(wq);
 static atomic_t wake_counter = ATOMIC_INIT(0);
 
+#define SEND_BUFFER_SIZE 4096
+
+static uint8_t send_buffer[SEND_BUFFER_SIZE];
+static size_t send_buffer_size = 0;
+
 static int slot = 0;
 
 static int device_open(struct inode *inode, struct file *file) { return 0; }
 
 static int device_release(struct inode *inode, struct file *file) { return 0; }
 
-static uint32_t calculate_crc32(const data_t *data) {
-  uint32_t crc = crc32(0, (void *)&data->sender_id, sizeof(uint8_t));
-  crc = crc32(crc, (void *)&data->count, sizeof(uint8_t));
-  crc = crc32(crc, (void *)&data->measurements, sizeof(measurement_t) * data->count);
+static uint32_t calculate_crc32(const packet_t *packet) {
+  uint32_t crc = crc32(0, (void *)&packet->data.sender_id, sizeof(uint8_t));
+  crc = crc32(crc, (void *)&packet->data.count, sizeof(uint8_t));
+  crc = crc32(crc, (void *)&packet->data.measurements,
+              sizeof(measurement_t) * packet->data.count);
   return crc;
 }
 
+static void prepare_for_sending(void) {
+  packet->crc = calculate_crc32(packet);
+
+  send_buffer[0] = packet->magic;
+  send_buffer[1] = packet->data.sender_id;
+  send_buffer[2] = packet->data.count;
+
+  uint8_t *bytes = (uint8_t *)packet->data.measurements;
+
+  for (size_t i = 0; i < sizeof(measurement_t) * packet->data.count; i++) {
+    send_buffer[bytes[3 + i]] = bytes[i];
+  }
+
+  bytes = (uint8_t *)&packet->crc;
+
+  for (size_t i = 0; i < sizeof(uint32_t); i++) {
+    send_buffer[3 + sizeof(measurement_t) * packet->data.count + i] = bytes[i];
+  }
+
+  send_buffer_size =
+      3 + sizeof(measurement_t) * packet->data.count + sizeof(uint32_t);
+}
+
 static ssize_t device_write(struct file *filp, const char *input, size_t length,
                             loff_t *offset) {
   if (length != sizeof(data_t)) {
@@ -62,8 +92,8 @@ static ssize_t device_write(struct file *filp, const char *input, size_t length,
     return -EFAULT;
   }
 
-  if (((data_t *)input)->count >= MAX_VALUES) {
-    printk(KERN_ALERT "lkm: Tried to write more messages than allowed\n");
+  if (((data_t *)input)->count >= MAX_MEASUREMENTS) {
+    printk(KERN_ALERT "lkm: Tried to write more measurements than allowed\n");
     return -EFAULT;
   }
 
@@ -84,7 +114,7 @@ static ssize_t device_write(struct file *filp, const char *input, size_t length,
     return -EFAULT;
   }
 
-  packet->crc = calculate_crc32(&packet->data);
+  prepare_for_sending();
 
   printk(KERN_INFO "lkm: received write of size %zu\n", length);
 
@@ -123,23 +153,9 @@ static inline void send_byte(uint8_t byte) {
 }
 
 static void send_data(const packet_t *packet) {
-  send_byte(0xAA);
-  /*
-send_byte(packet->data.sensor_id);
-send_byte(packet->data.count);
-
-uint8_t *bytes = (uint8_t *)packet->data.values;
-
-for (size_t i = 0; i < sizeof(message_t) * packet->data.count; i++) {
-  send_byte(bytes[i]);
-}
-
-bytes = (uint8_t *)&packet->crc;
-
-for (size_t i = 0; i < sizeof(uint32_t); i++) {
-  send_byte(bytes[i]);
-}
-*/
+  for (size_t i = 0; i < send_buffer_size; i++) {
+    send_byte(send_buffer[i]);
+  }
 }
 
 static int timed_thread_fn(void *args) {
@@ -166,16 +182,20 @@ static int __init lkm_init(void) {
     return -EFAULT;
   }
 
+  packet->magic = 0xAA;
   packet->data.sender_id = SENDER_ID;
   packet->data.count = 0;
 
-  packet->data.measurements = (measurement_t *)vmalloc(sizeof(measurement_t) * MAX_VALUES);
+  packet->data.measurements =
+      (measurement_t *)vmalloc(sizeof(measurement_t) * MAX_MEASUREMENTS);
 
   if (packet->data.measurements == NULL) {
     vfree(packet);
     return -EFAULT;
   }
 
+  prepare_for_sending();
+
   // Dynamically allocate major number
   if (alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME) < 0) {
     vfree(packet->data.measurements);
-- 
GitLab