16 static struct sync_flag bar_reachable;
18 static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
21 if(reachable && !strcmp(node->name, "bar")) {
22 set_sync_flag(&bar_reachable, true);
27 init_sync_flag(&bar_reachable);
29 struct meshlink_node **nodes = NULL;
32 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
34 // Open new meshlink instances.
36 assert(meshlink_destroy("get_all_nodes_conf.1"));
37 assert(meshlink_destroy("get_all_nodes_conf.2"));
38 assert(meshlink_destroy("get_all_nodes_conf.3"));
40 meshlink_handle_t *mesh[3];
41 mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all-nodes", DEV_CLASS_BACKBONE);
44 mesh[1] = meshlink_open("get_all_nodes_conf.2", "bar", "get-all-nodes", DEV_CLASS_STATIONARY);
47 mesh[2] = meshlink_open("get_all_nodes_conf.3", "baz", "get-all-nodes", DEV_CLASS_STATIONARY);
50 // Check that we only know about ourself.
52 nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
54 assert(nodes[0] == meshlink_get_self(mesh[0]));
56 // We should never have been online.
58 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
61 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
63 assert(nodes[0] == meshlink_get_self(mesh[0]));
65 // Let nodes know about each other.
67 for(int i = 0; i < 3; i++) {
68 meshlink_enable_discovery(mesh[i], false);
69 assert(meshlink_set_canonical_address(mesh[i], meshlink_get_self(mesh[i]), "localhost", NULL));
70 char *data = meshlink_export(mesh[i]);
73 for(int j = 0; j < 3; j++) {
78 assert(meshlink_import(mesh[j], data));
82 // We should know about all nodes now, and their device class.
84 nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
87 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_BACKBONE, nodes, &nnodes);
89 assert(nodes[0] == meshlink_get_self(mesh[0]));
91 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
94 // But no node should have been online.
96 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
99 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
104 time_t foo_started = time(NULL);
105 assert(meshlink_start(mesh[0]));
107 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
109 assert(nodes[0] == meshlink_get_self(mesh[0]));
111 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
114 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_started - 1, -1, nodes, &nnodes);
116 assert(nodes[0] == meshlink_get_self(mesh[0]));
118 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
121 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
123 assert(nodes[0] == meshlink_get_self(mesh[0]));
125 // Start bar and wait for it to connect.
127 meshlink_set_node_status_cb(mesh[0], status_cb);
130 assert(meshlink_start(mesh[1]));
131 assert(wait_sync_flag(&bar_reachable, 20));
132 time_t bar_started = time(NULL);
134 // Validate time ranges.
136 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
139 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
141 assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
143 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
145 assert(nodes[0] == meshlink_get_self(mesh[0]));
147 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
149 assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
150 assert(nodes[1] == meshlink_get_self(mesh[0]));
154 meshlink_stop(mesh[1]);
156 time_t bar_stopped = time(NULL);
158 // Validate we can see when bar was reachable.
160 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
162 assert(nodes[0] == meshlink_get_self(mesh[0]));
164 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
166 assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
167 assert(nodes[1] == meshlink_get_self(mesh[0]));
169 // Close and restart foo, check that it remembers correctly.
171 meshlink_close(mesh[0]);
173 time_t foo_stopped = time(NULL);
174 mesh[0] = meshlink_open("get_all_nodes_conf.1", "foo", "get-all_nodes", DEV_CLASS_BACKBONE);
177 nodes = meshlink_get_all_nodes(mesh[0], nodes, &nnodes);
180 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_BACKBONE, nodes, &nnodes);
182 assert(nodes[0] == meshlink_get_self(mesh[0]));
184 nodes = meshlink_get_all_nodes_by_dev_class(mesh[0], DEV_CLASS_STATIONARY, nodes, &nnodes);
187 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, 0, nodes, &nnodes);
189 assert(nodes[0] == meshlink_get_node(mesh[0], "baz"));
191 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 0, -1, nodes, &nnodes);
194 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started - 1, nodes, &nnodes);
197 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], 1, foo_started + 1, nodes, &nnodes);
199 assert(nodes[0] == meshlink_get_self(mesh[0]));
201 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_started, bar_started, nodes, &nnodes);
203 assert(nodes[0] == meshlink_get_node(mesh[0], "bar"));
204 assert(nodes[1] == meshlink_get_self(mesh[0]));
206 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], bar_stopped, bar_stopped, nodes, &nnodes);
208 assert(nodes[0] == meshlink_get_self(mesh[0]));
210 nodes = meshlink_get_all_nodes_by_last_reachable(mesh[0], foo_stopped, -1, nodes, &nnodes);
215 for(int i = 0; i < 3; i++) {
216 meshlink_close(mesh[i]);