#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
/**
*/
typedef struct {
int len;
- uint8_t buffer[MAX_ETHER_SIZE - 4];
+ uint8_t *buffer;
int status;
} MOREP_fragment_t;
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)
{
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)
}
}
- 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;
}
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;
}
}
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"));
}
/* 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);
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);
}
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;
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];
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));
}