From 9e6e6c89f67e74a60728a780f981f290a1c52dd5 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 25 Jan 2023 19:51:52 +0100 Subject: [PATCH 01/12] tools/zep_dispatch: topogen: fix node naming --- dist/tools/zep_dispatch/topogen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index bfe8647eb5..d15f4a772f 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -66,8 +66,8 @@ static void node_name(struct node *n, unsigned idx) do { uint8_t rem = idx % 26; + idx /= 26; *s++ = 'A' + rem; - idx -= rem; } while (idx && s != end); *s = 0; } From f68781deb4bb9689142af09181e3c933ca4de7f9 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 30 Jan 2023 21:40:19 +0100 Subject: [PATCH 02/12] tools/zep_dispatch: topogen: add binary mode --- dist/tools/zep_dispatch/topogen.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index d15f4a772f..0bab2e2dc2 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -154,7 +154,7 @@ static void _calc_connections(struct node *nodes, unsigned num) } } -static void _print_distance(struct node *nodes, unsigned num, bool recursive) +static void _print_distance(struct node *nodes, unsigned num, bool recursive, bool binary) { struct node *start = nodes; @@ -164,12 +164,19 @@ static void _print_distance(struct node *nodes, unsigned num, bool recursive) double to_node = node_distance_weight(start, n); double from_node = node_distance_weight(n, start); - if (to_node > 0 || from_node > 0) { + if (binary) { + if (to_node >= 0.5) { + printf("%s\t%s\n", start->name, n->name); + } + if (from_node >= 0.5) { + printf("%s\t%s\n", n->name, start->name); + } + } else if (to_node > 0 || from_node > 0) { printf("%s\t%s\t%.2f\t%.2f\n", start->name, n->name, to_node, from_node); } if (recursive) { - _print_distance(n, num - i, false); + _print_distance(n, num - i, false, binary); } } } @@ -183,6 +190,7 @@ static void _print_help(const char *name) " [-r ]" " [-v ]" " [-n ]" + " [-b]" "\n", name); } @@ -196,10 +204,14 @@ int main(int argc, char** argv) unsigned range = 25; unsigned var = 0; unsigned num = 10; + bool binary = false; char c; - while ((c = getopt(argc, argv, "s:w:h:r:v:n:")) != -1) { + while ((c = getopt(argc, argv, "s:w:h:r:v:n:b")) != -1) { switch (c) { + case 'b': + binary = true; + break; case 's': seed = atoi(optarg); break; @@ -231,7 +243,7 @@ int main(int argc, char** argv) printf("# seed = %u\n", seed); puts("# Connections"); - _print_distance(w.nodes, w.num_nodes, true); + _print_distance(w.nodes, w.num_nodes, true, binary); puts(""); puts(""); puts("# Node\tX\tY\trange\tcolor"); From eec1d85cf3a376233a7563bbac1c972867148615 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 7 Feb 2023 15:43:03 +0100 Subject: [PATCH 03/12] tools/zep_dispatch: fix packet transmission to multiple nodes --- dist/tools/zep_dispatch/topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/tools/zep_dispatch/topology.c b/dist/tools/zep_dispatch/topology.c index c12824478c..2fee4e6c2b 100644 --- a/dist/tools/zep_dispatch/topology.c +++ b/dist/tools/zep_dispatch/topology.c @@ -232,7 +232,7 @@ void topology_send(const topology_t *t, int sock, if (memcmp(&super->a->addr, src_addr, sizeof(*src_addr)) == 0) { /* packet loss */ if (random() > super->weight_a_b * RAND_MAX) { - return; + continue; } zep_set_lqi(buffer, super->weight_a_b * 0xFF); sendto(sock, buffer, len, 0, @@ -242,7 +242,7 @@ void topology_send(const topology_t *t, int sock, else if (memcmp(&super->b->addr, src_addr, sizeof(*src_addr)) == 0) { /* packet loss */ if (random() > super->weight_b_a * RAND_MAX) { - return; + continue; } zep_set_lqi(buffer, super->weight_b_a * 0xFF); sendto(sock, buffer, len, 0, From c9f70902404d09e8a725fcbca83191d3cbb77f6f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 7 Feb 2023 15:43:53 +0100 Subject: [PATCH 04/12] tools/zep_dispatch: count rx/tx frames --- dist/tools/zep_dispatch/main.c | 22 ++++++++++-------- dist/tools/zep_dispatch/topology.c | 36 ++++++++++++++++++++++++++++++ dist/tools/zep_dispatch/topology.h | 7 ++++++ 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/dist/tools/zep_dispatch/main.c b/dist/tools/zep_dispatch/main.c index deafe6ef13..7764618804 100644 --- a/dist/tools/zep_dispatch/main.c +++ b/dist/tools/zep_dispatch/main.c @@ -133,15 +133,18 @@ static topology_t topology; static const char *graphviz_file = "example.gv"; static void _info_handler(int signal) { - if (signal != SIGUSR1) { - return; - } - - if (topology_print(graphviz_file, &topology)) { - fprintf(stderr, "can't open %s\n", graphviz_file); - } - else { - printf("graph written to %s\n", graphviz_file); + switch (signal) { + case SIGUSR1: + if (topology_print(graphviz_file, &topology)) { + fprintf(stderr, "can't open %s\n", graphviz_file); + } + else { + printf("graph written to %s\n", graphviz_file); + } + break; + case SIGUSR2: + topology_print_stats(&topology, true); + break; } } @@ -257,6 +260,7 @@ int main(int argc, char **argv) if (graphviz_file) { signal(SIGUSR1, _info_handler); } + signal(SIGUSR2, _info_handler); struct addrinfo *server_addr; int res = getaddrinfo(argv[0], argv[1], diff --git a/dist/tools/zep_dispatch/topology.c b/dist/tools/zep_dispatch/topology.c index 2fee4e6c2b..9f3c39f050 100644 --- a/dist/tools/zep_dispatch/topology.c +++ b/dist/tools/zep_dispatch/topology.c @@ -26,6 +26,8 @@ struct node { char name[NODE_NAME_MAX_LEN]; uint8_t mac[HW_ADDR_MAX_LEN]; struct sockaddr_in6 addr; + uint32_t num_tx; + uint32_t num_rx; uint8_t mac_len; }; @@ -182,6 +184,26 @@ int topology_print(const char *file, const topology_t *t) return 0; } +void topology_print_stats(const topology_t *t, bool reset) +{ + uint32_t tx_total = 0; + + puts("{ nodes: ["); + for (list_node_t *node = t->nodes.next; node; node = node->next) { + struct node *super = container_of(node, struct node, next); + + tx_total += super->num_tx; + + printf("\t{ name: %s, tx: %u, rx: %u }%c\n", + super->name, super->num_tx, super->num_rx, node->next ? ',' : ' '); + if (reset) { + super->num_tx = 0; + super->num_rx = 0; + } + } + printf("], tx_total: %u }\n", tx_total); +} + int topology_parse(const char *file, topology_t *out) { FILE *in; @@ -217,6 +239,8 @@ void topology_send(const topology_t *t, int sock, const struct sockaddr_in6 *src_addr, void *buffer, size_t len) { + struct node *sender = NULL; + if (t->has_sniffer) { sendto(sock, buffer, len, 0, (struct sockaddr *)&t->sniffer_addr, sizeof(t->sniffer_addr)); @@ -230,6 +254,11 @@ void topology_send(const topology_t *t, int sock, } if (memcmp(&super->a->addr, src_addr, sizeof(*src_addr)) == 0) { + if (sender == NULL) { + sender = super->a; + sender->num_tx++; + } + /* packet loss */ if (random() > super->weight_a_b * RAND_MAX) { continue; @@ -238,8 +267,14 @@ void topology_send(const topology_t *t, int sock, sendto(sock, buffer, len, 0, (struct sockaddr *)&super->b->addr, sizeof(super->b->addr)); + super->b->num_rx++; } else if (memcmp(&super->b->addr, src_addr, sizeof(*src_addr)) == 0) { + if (sender == NULL) { + sender = super->b; + sender->num_tx++; + } + /* packet loss */ if (random() > super->weight_b_a * RAND_MAX) { continue; @@ -248,6 +283,7 @@ void topology_send(const topology_t *t, int sock, sendto(sock, buffer, len, 0, (struct sockaddr *)&super->a->addr, sizeof(super->a->addr)); + super->a->num_rx++; } } } diff --git a/dist/tools/zep_dispatch/topology.h b/dist/tools/zep_dispatch/topology.h index 9b3d61d989..16733a29e2 100644 --- a/dist/tools/zep_dispatch/topology.h +++ b/dist/tools/zep_dispatch/topology.h @@ -48,6 +48,13 @@ int topology_parse(const char *file, topology_t *out); */ int topology_print(const char *file_out, const topology_t *t); +/** + * @brief Print send / receive statistics + * + * @param[in] t The topology to render + */ +void topology_print_stats(const topology_t *t, bool reset); + /** * @brief Populate a spot in the topology with a connected node * From b4efc378a08a2918f64356fdb419847c2c6ae7a9 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 15 Feb 2023 16:51:53 +0100 Subject: [PATCH 05/12] tools/zep_dispatch: topogen: add support for generating grid topology --- dist/tools/zep_dispatch/topogen.c | 43 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index 0bab2e2dc2..5e4a8c130f 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -27,6 +27,7 @@ struct world { unsigned h; unsigned num_nodes; struct node *nodes; + bool grid; }; static unsigned random_range(unsigned lower, unsigned upper) @@ -35,13 +36,31 @@ static unsigned random_range(unsigned lower, unsigned upper) return lower + rand() % range; } -static struct node *node_generate(struct node *n, const struct world *w, - unsigned range) +static struct node *node_generate(struct node *node, const struct world *w, + unsigned range, unsigned idx) { - n->x = random_range(0, w->w); - n->y = random_range(0, w->h); - n->r = range; - return n; + if (w->grid) { + float width = w->w; + float height = w->h; + float num = w->num_nodes; + + /* https://math.stackexchange.com/a/1039514 */ + float n_x = sqrtf(num * width/height + + powf(width - height, 2)/(4 * height*height)) + - (width - height)/2; + float n_y = num / n_x; + + unsigned step_x = width / n_x; + unsigned step_y = height / n_y; + + node->x = (idx * step_x + step_x / 2) % w->w; + node->y = ((idx * step_x + step_x / 2) / w->w) * step_y + step_y / 2; + } else { + node->x = random_range(0, w->w); + node->y = random_range(0, w->h); + } + node->r = range; + return node; } static double node_distance(const struct node *a, const struct node *b) @@ -82,7 +101,7 @@ static void world_gen(struct world *w, unsigned num_nodes, w->nodes = calloc(num_nodes, sizeof(*w->nodes)); for (unsigned i = 0; i < num_nodes; ++i) { - node_generate(&w->nodes[i], w, random_range(range - var, range + var)); + node_generate(&w->nodes[i], w, random_range(range - var, range + var), i); node_name(&w->nodes[i], i); } } @@ -205,13 +224,17 @@ int main(int argc, char** argv) unsigned var = 0; unsigned num = 10; bool binary = false; + bool grid = false; char c; - while ((c = getopt(argc, argv, "s:w:h:r:v:n:b")) != -1) { + while ((c = getopt(argc, argv, "s:w:h:r:v:n:bg")) != -1) { switch (c) { case 'b': binary = true; break; + case 'g': + grid = true; + break; case 's': seed = atoi(optarg); break; @@ -238,7 +261,9 @@ int main(int argc, char** argv) srand(seed); - struct world w; + struct world w = { + .grid = grid, + }; world_gen(&w, num, width, height, range, var); printf("# seed = %u\n", seed); From 1c1562438452cd1a27ee6ad8cab410cc9e7af67a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 27 Sep 2023 14:24:36 +0200 Subject: [PATCH 06/12] tools/zep_dispatch: allow list of nodes in topo file --- dist/tools/zep_dispatch/topology.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dist/tools/zep_dispatch/topology.c b/dist/tools/zep_dispatch/topology.c index 9f3c39f050..740cea9aa6 100644 --- a/dist/tools/zep_dispatch/topology.c +++ b/dist/tools/zep_dispatch/topology.c @@ -90,15 +90,20 @@ static bool _parse_line(char *line, list_node_t *nodes, list_node_t *edges) return true; } - char *a = strtok(line, "\t "); + char *a = strtok(line, "\n\t "); char *b = strtok(NULL, "\n\t "); char *e_ab = strtok(NULL, "\n\t "); char *e_ba = strtok(NULL, "\n\t "); - if (a == NULL || b == NULL) { + if (a == NULL) { return false; } + if (b == NULL) { + _find_or_create_node(nodes, a); + return true; + } + /* add node with a defined MAC address */ if (strcmp(b, ":=") == 0) { struct node *n = _find_or_create_node(nodes, a); @@ -332,7 +337,9 @@ bool topology_add(topology_t *t, const uint8_t *mac, uint8_t mac_len, return false; } - printf("adding node %s\n", _fmt_addr(addr_str, sizeof(addr_str), mac, mac_len)); + printf("adding node %s as %s\n", + _fmt_addr(addr_str, sizeof(addr_str), mac, mac_len), + (char *)empty->name); /* add new node to empty spot */ memcpy(empty->mac, mac, sizeof(empty->mac)); From 875bf98280a394d6e090b5cb39dd5cbd2fe0932f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 4 Oct 2023 16:30:43 +0200 Subject: [PATCH 07/12] tools/zep_dispatch: topogen: fix distance calculation --- dist/tools/zep_dispatch/topogen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index 5e4a8c130f..6a22c45256 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -70,7 +70,7 @@ static double node_distance(const struct node *a, const struct node *b) static double node_distance_weight(const struct node *a, const struct node *b) { - double w = 1 - node_distance(a, b) / a->r; + double w = 1 - pow(node_distance(a, b), 2) / pow(a->r, 2); if (w < 0) { return 0; From 61992fe1a79269d741e52535706ae65ea97930d3 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 4 Oct 2023 16:31:34 +0200 Subject: [PATCH 08/12] tools/zep_dispatch: add support for PIDFILE --- dist/tools/zep_dispatch/main.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/dist/tools/zep_dispatch/main.c b/dist/tools/zep_dispatch/main.c index 7764618804..755f666a6c 100644 --- a/dist/tools/zep_dispatch/main.c +++ b/dist/tools/zep_dispatch/main.c @@ -131,6 +131,7 @@ static void dispatch_loop(int sock, int tap, dispatch_cb_t dispatch, void *ctx) static topology_t topology; static const char *graphviz_file = "example.gv"; +static const char *pidfile; static void _info_handler(int signal) { switch (signal) { @@ -145,6 +146,13 @@ static void _info_handler(int signal) case SIGUSR2: topology_print_stats(&topology, true); break; + case SIGINT: + case SIGTERM: + if (pidfile) { + unlink(pidfile); + } + exit(0); + break; } } @@ -193,6 +201,7 @@ static void _print_help(const char *progname) fprintf(stderr, "\noptional arguments:\n"); fprintf(stderr, "\t-t \tLoad toplogy from file\n"); + fprintf(stderr, "\t-p \tStore PID in file\n"); fprintf(stderr, "\t-s \tRandom seed used to simulate packet loss\n"); fprintf(stderr, "\t-g \tFile to dump topology as Graphviz visualisation on SIGUSR1\n"); fprintf(stderr, "\t-w \tSend frames to virtual 802.15.4 " @@ -213,7 +222,7 @@ int main(int argc, char **argv) .ai_flags = AI_NUMERICHOST, }; - while ((c = getopt(argc, argv, "t:s:g:w:")) != -1) { + while ((c = getopt(argc, argv, "t:s:g:w:p:")) != -1) { switch (c) { case 't': topo_file = optarg; @@ -230,6 +239,9 @@ int main(int argc, char **argv) return tap_fd; } break; + case 'p': + pidfile = optarg; + break; default: _print_help(progname); exit(1); @@ -261,6 +273,8 @@ int main(int argc, char **argv) signal(SIGUSR1, _info_handler); } signal(SIGUSR2, _info_handler); + signal(SIGTERM, _info_handler); + signal(SIGINT, _info_handler); struct addrinfo *server_addr; int res = getaddrinfo(argv[0], argv[1], @@ -286,6 +300,14 @@ int main(int argc, char **argv) freeaddrinfo(server_addr); + if (pidfile) { + FILE *pf = fopen(pidfile, "w"); + if (pf) { + fprintf(pf, "%u", getpid()); + fclose(pf); + } + } + if (topology.flat) { dispatch_loop(sock, tap_fd, _send_flat, &topology.nodes); } From b85b7937c3fe77225dd9ecd089ec7cdc0cd9fe35 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sat, 7 Oct 2023 16:06:57 +0200 Subject: [PATCH 09/12] tools/zep_dispatch: topogen: use numeric names --- dist/tools/zep_dispatch/topogen.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index 6a22c45256..293624ed6e 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -13,6 +13,10 @@ #include #include +#ifndef CONFIG_USE_NUMERIC_NAMES +#define CONFIG_USE_NUMERIC_NAMES 1 +#endif + struct node { char name[8]; int x; @@ -80,6 +84,11 @@ static double node_distance_weight(const struct node *a, const struct node *b) static void node_name(struct node *n, unsigned idx) { + if (CONFIG_USE_NUMERIC_NAMES) { + snprintf(n->name, sizeof(n->name), "n%03u", (uint16_t)idx + 1); + return; + } + char *s = n->name; const char *end = s + sizeof(n->name) - 1; From 2e19c2d71238e6f38bd56c3ddaf08a384aa2e2b8 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sat, 7 Oct 2023 16:07:43 +0200 Subject: [PATCH 10/12] tools/zep_dispatch: topogen: place first node at origin --- dist/tools/zep_dispatch/topogen.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index 293624ed6e..171888dfd7 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -113,6 +113,12 @@ static void world_gen(struct world *w, unsigned num_nodes, node_generate(&w->nodes[i], w, random_range(range - var, range + var), i); node_name(&w->nodes[i], i); } + + if (!w->grid) { + /* place first node at origin */ + w->nodes[0].x = 0; + w->nodes[0].y = 0; + } } static unsigned _color(const struct node *n, unsigned base) From f7e6a4ada27f196e7e9c8eff6a7d9e57377a9c85 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sat, 7 Oct 2023 16:08:08 +0200 Subject: [PATCH 11/12] tools/zep_dispatch: topogen: print list of nodes --- dist/tools/zep_dispatch/topogen.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index 171888dfd7..52b6df5d20 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -192,6 +192,12 @@ static void _print_distance(struct node *nodes, unsigned num, bool recursive, bo { struct node *start = nodes; + if (recursive) { + for (unsigned i = 0; i < num; ++i) { + printf("%s\n", nodes[i].name); + } + } + for (unsigned i = 1; i < num; ++i) { struct node *n = &nodes[i]; From ba8130e69f84159c2bc583ff4abaa27f1b887b36 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 17 Dec 2023 17:31:21 +0100 Subject: [PATCH 12/12] tools/zep_dispatch: topogen: add help text --- dist/tools/zep_dispatch/topogen.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dist/tools/zep_dispatch/topogen.c b/dist/tools/zep_dispatch/topogen.c index 52b6df5d20..b5a01b4ee4 100644 --- a/dist/tools/zep_dispatch/topogen.c +++ b/dist/tools/zep_dispatch/topogen.c @@ -230,8 +230,18 @@ static void _print_help(const char *name) " [-r ]" " [-v ]" " [-n ]" - " [-b]" + " [-b][-g]" "\n", name); + + puts("\nOptions:"); + puts("\t-s \trandom seed used for topology generation"); + puts("\t-w \twidth of the 2D topology"); + puts("\t-h \theight of the 2D topology"); + puts("\t-r \tRadio range of the nodes"); + puts("\t-v \tmaximal random variance of radio range"); + puts("\t-n \tnumber of nodes in the topology"); + puts("\t-b\t\tbinary links: link quality is rounded to 100% or 0%"); + puts("\t-g\t\tnodes are organized as a grid"); } int main(int argc, char** argv)