allocate internal structure
authorLaurent Mazet <mazet@softndesign.org>
Thu, 27 Mar 2025 23:17:43 +0000 (00:17 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Thu, 27 Mar 2025 23:17:43 +0000 (00:17 +0100)
morep.c

diff --git a/morep.c b/morep.c
index 4f2323ca2fe317c3bb295f63864b4b75a204d229..47e962dcf9c7c0e3eb5a3bacd19986450d6a1554 100644 (file)
--- a/morep.c
+++ b/morep.c
 
 #include "morep.h"
 
+#define MAC_ADDR_STRING 18
+
 /**
    MOREP address structure
 */
 typedef struct {
     char ifname[32];
-    char mac_address[18];
+    char mac_address[MAC_ADDR_STRING];
     uint16_t ether_type;
     uint8_t mac[6];
 } MOREP_addr_t;
 
 #define MAX_MOREP_NUMBER 256
+#define ETHER_PREAMBLE 14
 #define MAX_ETHER_SIZE 1500 /* 9000 for jumbo frame */
+#define MOREP_PREAMBLE 4
 #define MAX_FRAGMENTS 15
 
 /**
@@ -47,7 +51,7 @@ typedef struct {
 */
 typedef struct {
     int len;
-    uint8_t buffer[MAX_ETHER_SIZE - 4];
+    uint8_t *buffer;
     int status;
 } MOREP_fragment_t;
 
@@ -57,21 +61,37 @@ typedef struct {
 typedef struct {
     int sock;
     uint8_t seqnum;
-    uint8_t tx_buffer[MAX_ETHER_SIZE + 14];
-    uint8_t rx_buffer[MAX_ETHER_SIZE + 14];
-    MOREP_fragment_t fragment_list[MAX_FRAGMENTS];
+    uint8_t *tx_buffer;
+    uint8_t *rx_buffer;
+    int used;
 } MOREP_descriptor_t ;
 
 /**
    List of private descriptor associated to each connected MORE.
 */
 
-MOREP_descriptor_t *MOREP_list[MAX_MOREP_NUMBER] = { 0 };
+MOREP_descriptor_t *MOREP_list[MAX_MOREP_NUMBER] = {0};
 
 /**
-   Init flag
+    List of fragments.
 */
-static int __init = 1;
+MOREP_fragment_t *fragment_list[MAX_FRAGMENTS] = {0};
+
+void alloc_all_moreps ()
+{
+    VERBOSE (morep, TRACE, FPRINTF (stdout, "alloc_all_moreps\n"));
+
+    int i;
+    for (i = 0; i < MAX_MOREP_NUMBER; i++) {
+        MOREP_list[i] = (MOREP_descriptor_t *) calloc (sizeof (MOREP_descriptor_t), 1);
+        MOREP_list[i]->tx_buffer = (uint8_t *) calloc (1, ETHER_PREAMBLE + MAX_ETHER_SIZE);
+        MOREP_list[i]->rx_buffer = (uint8_t *) calloc (1, ETHER_PREAMBLE + MAX_ETHER_SIZE);
+    }
+    for (i = 0; i < MAX_FRAGMENTS; i++) {
+        fragment_list[i] = (MOREP_fragment_t *) calloc (sizeof (MOREP_fragment_t), 1);
+        fragment_list[i]->buffer = (uint8_t *) calloc (1, ETHER_PREAMBLE + MAX_ETHER_SIZE);
+    }
+}
 
 void free_all_moreps (void)
 {
@@ -79,9 +99,24 @@ void free_all_moreps (void)
 
     int i;
     for (i = 0; i < MAX_MOREP_NUMBER; i++) {
+        if (MOREP_list[i]) {
+            free (MOREP_list[i]->tx_buffer);
+            free (MOREP_list[i]->rx_buffer);
+        }
         free (MOREP_list[i]);
-        MOREP_list[i] = NULL;
     }
+    for (i = 0; i < MAX_FRAGMENTS; i++) {
+        if (fragment_list[i]) {
+            free (fragment_list[i]->buffer);
+        }
+        free (fragment_list[i]);
+    }
+}
+
+void __attribute__((constructor)) _init_morep_ (void)
+{
+    alloc_all_moreps ();
+    atexit (free_all_moreps);
 }
 
 int parse_ifname (MOREP_addr_t *addr, char *url)
@@ -134,7 +169,7 @@ int parse_mac (MOREP_addr_t *addr, char *url)
         }
     }
 
-    if (j != 18) {
+    if (j != ETHER_PREAMBLE + MOREP_PREAMBLE) {
         VERBOSE (morep, WARNING, PRINTF ("can't parse mac address '%s'(%d) \n", url, j));
         return -1;
     }
@@ -214,13 +249,13 @@ void mactoa (char *str, uint8_t *mac)
     str[17] = '\0';
 }
 
-int alloc_morep ()
+int find_unused_morep ()
 {
-    VERBOSE (morep, TRACE, PRINTF ("alloc_morep\n"));
+    VERBOSE (morep, TRACE, PRINTF ("find_unused_morep\n"));
 
     int i;
     for (i = 0; i < MAX_MOREP_NUMBER; i++) {
-        if (MOREP_list[i] == NULL) {
+        if (MOREP_list[i]->used == 0) {
             break;
         }
     }
@@ -228,15 +263,20 @@ int alloc_morep ()
         VERBOSE (morep, WARNING, PRINTF ("can't find avaliable morep descriptor\n"));
         return -1;
     }
+    MOREP_list[i]->used = 1;
 
-    MOREP_list[i] = (MOREP_descriptor_t *) calloc (sizeof (MOREP_descriptor_t), 1);
-    assert (MOREP_list[i]);
-
-    VERBOSE (morep, DEBUG, PRINTF ("allocated morep: %d\n", i));
+    VERBOSE (morep, DEBUG, PRINTF ("find morep: %d\n", i));
 
     return i;
 }
 
+void release_morep (int i)
+{
+    VERBOSE (morep, TRACE, PRINTF ("release_morep\n"));
+
+    MOREP_list[i]->used = 0;
+}
+
 int MOREP_Connect (char *url)
 {
     VERBOSE (morep, TRACE, PRINTF ("MOREP_Connect\n"));
@@ -281,12 +321,12 @@ int MOREP_Connect (char *url)
     }
 
     /* info message */
-    char lmac[18] = {0};
+    char lmac[MAC_ADDR_STRING] = {0};
     mactoa (lmac, sock_addr.sll_addr);
     VERBOSE (morep, INFO, PRINTF ("I/O on %s local=[%s]\n", addr.ifname, lmac));
 
     /* store connection */
-    int index = alloc_morep ();
+    int index = find_unused_morep ();
     if (index >= 0) {
         MOREP_list[index]->sock = sock;
         memcpy (MOREP_list[index]->tx_buffer, (void *) addr.mac, 6);
@@ -329,10 +369,10 @@ int MOREP_Send (int index, uint8_t msgtype, uint8_t *buffer, int len)
         VERBOSE (morep, DEBUG, PRINTF ("flag/frag/length: %d/%d/%d\n", (pklen != len), nfrag, pklen));
         uint16_t msglen = htons (pklen | (nfrag << 11) | ((pklen != len) << 15));
         memcpy (morep->tx_buffer + 16, (void *) &msglen, 2);
-        VERBOSE (morep, DEBUG, PRINTF ("sent preamble: "); int i; for (i = 0; i < 18; i++) printf ("%02x:", morep->tx_buffer[i]); printf ("\n"));
+        VERBOSE (morep, DEBUG, PRINTF ("sent preamble: "); int i; for (i = 0; i < ETHER_PREAMBLE + MOREP_PREAMBLE; i++) printf ("%02x:", morep->tx_buffer[i]); printf ("\n"));
 
-        memcpy (morep->tx_buffer + 18, buffer, pklen);
-        int txlen = pklen + 18;
+        memcpy (morep->tx_buffer + ETHER_PREAMBLE + MOREP_PREAMBLE, buffer, pklen);
+        int txlen = pklen + ETHER_PREAMBLE + MOREP_PREAMBLE;
         if (txlen < 64) {
             VERBOSE (morep, DEBUG, PRINTF ("need padding: %d bytes\n",  64 - txlen));
             memset (morep->tx_buffer + txlen, 0, 64 - txlen);
@@ -361,8 +401,8 @@ int MOREP_Receive (int index, uint8_t *msgtype, uint8_t *buffer, int *len)
     }
     MOREP_descriptor_t *morep =  MOREP_list[index];
     for (i = 0; i < MAX_FRAGMENTS; i++) {
-        (morep->fragment_list + i)->len = 0;
-        //(morep->fragment_list + i)->status = 0;
+        fragment_list[i]->len = 0;
+        //fragment_list[i]->status = 0;
     }
 
     int rxmsgtype = -1;
@@ -371,7 +411,7 @@ int MOREP_Receive (int index, uint8_t *msgtype, uint8_t *buffer, int *len)
     int flag = 0;
     do {
         rxlen = recvfrom (morep->sock, morep->rx_buffer, sizeof (morep->rx_buffer), 0, NULL, 0);
-        VERBOSE (morep, DEBUG, PRINTF ("rec. preamble: "); int i; for (i = 0; i < 18; i++) printf ("%02x:", morep->rx_buffer[i]); printf ("\n"));
+        VERBOSE (morep, DEBUG, PRINTF ("rec. preamble: "); int i; for (i = 0; i < ETHER_PREAMBLE + MOREP_PREAMBLE; i++) printf ("%02x:", morep->rx_buffer[i]); printf ("\n"));
 
         /* sequence number */
         int pkgseqnum = morep->rx_buffer[15];
@@ -397,31 +437,33 @@ int MOREP_Receive (int index, uint8_t *msgtype, uint8_t *buffer, int *len)
         VERBOSE (morep, DEBUG, PRINTF ("flag/frag/length: %d/%d/%d\n", flag, pkgfrag, pkglen));
 
         /* check padding */
-        if (pkglen < 64 - 18) {
-            VERBOSE (morep, DEBUG, PRINTF ("padding of %d bytes\n", 64 - 18 - pkglen));
-            VERBOSE (morep, DEBUG, int _i; for (_i = pkglen + 18; _i < 64; _i++) if (morep->rx_buffer[_i] != 0) { VERBOSE (morep, WARNING, PRINTF ("incorrect padding (%d)\n", _i)); break; });
+        if (pkglen < 64 - ETHER_PREAMBLE + MOREP_PREAMBLE) {
+            VERBOSE (morep, DEBUG, PRINTF ("padding of %d bytes\n", 64 - ETHER_PREAMBLE + MOREP_PREAMBLE - pkglen));
+            VERBOSE (morep, DEBUG, int _i; for (_i = pkglen + ETHER_PREAMBLE + MOREP_PREAMBLE; _i < 64; _i++) if (morep->rx_buffer[_i] != 0) { VERBOSE (morep, WARNING, PRINTF ("incorrect padding (%d)\n", _i)); break; });
         }
-        if (((rxlen == 64) && (pkglen > 64 - 18)) || ((rxlen > 64) && (pkglen != rxlen - 18))) {
-            VERBOSE (morep, WARNING, PRINTF ("incorrect size (%d/%d)\n", pkglen, rxlen - 18));
-            pkglen = rxlen - 18;
+        if (((rxlen == 64) && (pkglen > 64 - ETHER_PREAMBLE + MOREP_PREAMBLE)) || ((rxlen > 64) && (pkglen != rxlen - ETHER_PREAMBLE + MOREP_PREAMBLE))) {
+            VERBOSE (morep, WARNING, PRINTF ("incorrect size (%d/%d)\n", pkglen, rxlen - ETHER_PREAMBLE + MOREP_PREAMBLE));
+            pkglen = rxlen - ETHER_PREAMBLE + MOREP_PREAMBLE;
         }
 
         /* store fragment */
         if (flag) {
             VERBOSE (morep, DEBUG, PRINTF ("storing fragment %d (%d bytes)\n", pkgfrag, pkglen));
-            MOREP_fragment_t *frag = morep->fragment_list + pkgfrag;
-            memcpy (frag->buffer, morep->rx_buffer + 18, pkglen);
-            frag->len = pkglen;
-            //frag->status = 1;
+            MOREP_fragment_t *frag = fragment_list[pkgfrag];
+            uint8_t *tmp = frag->buffer;
+            frag->buffer = morep->rx_buffer;
+            morep->rx_buffer = tmp;
+            frag-> len = pkglen;
+            // frag->status = 1;
         } else {
             rxlen = 0;
-            for (i = 0; (i < MAX_FRAGMENTS) && ((morep->fragment_list + i)->len != 0); i++) {
-                MOREP_fragment_t *frag = morep->fragment_list + i;
-                memcpy (buffer + rxlen, frag->buffer, frag->len);
+            for (i = 0; (i < MAX_FRAGMENTS) && (fragment_list[i]->len != 0); i++) {
+                MOREP_fragment_t *frag = fragment_list[i];
+                memcpy (buffer + rxlen, frag->buffer + ETHER_PREAMBLE + MOREP_PREAMBLE, frag->len);
                 rxlen += frag->len;
                 VERBOSE (morep, DEBUG, PRINTF ("gluing fragment %d (%d/%d bytes)\n", i, frag->len, rxlen));
             }
-            memcpy (buffer + rxlen, morep->rx_buffer + 18, pkglen);
+            memcpy (buffer + rxlen, morep->rx_buffer + ETHER_PREAMBLE + MOREP_PREAMBLE, pkglen);
             rxlen += pkglen;
             VERBOSE (morep, DEBUG, PRINTF ("last fragment (%d/%d bytes)\n", pkglen, rxlen));
         }