19 static struct sync_flag received;
20 static struct sync_flag bar_learned_baz;
21 static struct sync_flag baz_learned_bar;
23 static void receive_cb(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
27 if(len == 5 && !memcmp(data, "Hello", 5)) {
28 set_sync_flag(&received, true);
32 static void bar_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
36 if(!strcmp(node->name, "baz")) {
37 set_sync_flag(&bar_learned_baz, true);
41 static void baz_status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
45 if(!strcmp(node->name, "bar")) {
46 set_sync_flag(&baz_learned_bar, true);
51 init_sync_flag(&received);
52 init_sync_flag(&bar_learned_baz);
53 init_sync_flag(&baz_learned_bar);
55 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
57 // Create three instances.
59 const char *name[3] = {"foo", "bar", "baz"};
60 meshlink_handle_t *mesh[3];
63 for(int i = 0; i < 3; i++) {
65 assert(asprintf(&path, "trio_conf.%d", i) != -1 && path);
67 assert(meshlink_destroy(path));
68 mesh[i] = meshlink_open(path, name[i], "trio", DEV_CLASS_BACKBONE);
72 assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
74 data[i] = meshlink_export(mesh[i]);
78 // first node knows the two other nodes
80 for(int i = 1; i < 3; i++) {
81 assert(meshlink_import(mesh[i], data[0]));
82 assert(meshlink_import(mesh[0], data[i]));
84 assert(meshlink_get_node(mesh[i], name[0]));
85 assert(meshlink_get_node(mesh[0], name[i]));
88 // second and third node should not know each other yet
90 assert(!meshlink_get_node(mesh[1], name[2]));
91 assert(!meshlink_get_node(mesh[2], name[1]));
95 meshlink_set_node_status_cb(mesh[1], bar_status_cb);
96 meshlink_set_node_status_cb(mesh[2], baz_status_cb);
98 for(int i = 0; i < 3; i++) {
100 assert(meshlink_start(mesh[i]));
103 // the nodes should now learn about each other
105 assert(wait_sync_flag(&bar_learned_baz, 5));
106 assert(wait_sync_flag(&baz_learned_bar, 5));
108 // Send a packet, expect it is received
110 meshlink_set_receive_cb(mesh[1], receive_cb);
112 for(int i = 0; i < 15; i++) {
113 assert(meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5));
115 if(wait_sync_flag(&received, 1)) {
120 assert(wait_sync_flag(&received, 15));
122 // Check that the second and third node have autoconnected to each other
124 devtool_edge_t *edges = NULL;
126 assert_after((edges = devtool_get_all_edges(mesh[1], edges, &nedges), nedges == 3), 15);
129 // Stop the first node
131 meshlink_stop(mesh[0]);
134 // Communication should still be possible
136 set_sync_flag(&received, false);
138 for(int i = 0; i < 15; i++) {
139 assert(meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5));
141 if(wait_sync_flag(&received, 1)) {
146 assert(wait_sync_flag(&received, 15));
148 // Stop the other nodes
150 for(int i = 1; i < 3; i++) {
151 meshlink_stop(mesh[i]);
156 // Start just the other two nodes
158 for(int i = 1; i < 3; i++) {
159 assert(meshlink_start(mesh[i]));
162 assert(meshlink_get_node(mesh[1], name[2]));
163 assert(meshlink_get_node(mesh[2], name[1]));
165 // Communication should still be possible
167 set_sync_flag(&received, false);
169 for(int i = 0; i < 15; i++) {
170 assert(meshlink_send(mesh[2], meshlink_get_node(mesh[2], name[1]), "Hello", 5));
172 if(wait_sync_flag(&received, 1)) {
177 assert(wait_sync_flag(&received, 1));
181 for(int i = 0; i < 3; i++) {
182 meshlink_close(mesh[i]);