9 #include "../src/meshlink.h"
12 static struct sync_flag accept_flag;
13 static struct sync_flag close_flag;
16 meshlink_handle_t *mesh;
17 meshlink_channel_t *channel;
21 static void server_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
24 // We expect no data from clients, apart from disconnections.
27 meshlink_channel_t **c = mesh->priv;
30 for(int i = 0; i < 3; i++) {
33 meshlink_channel_close(mesh, channel);
42 set_sync_flag(&close_flag, true);
46 static void client_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
50 // We expect always the same amount of data from the server.
53 struct client *client = mesh->priv;
54 client->received += len;
57 static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
59 struct client *client = mesh->priv;
61 if(reachable && !strcmp(node->name, "server")) {
62 assert(!client->channel);
63 client->channel = meshlink_channel_open_ex(mesh, node, 1, client_receive_cb, NULL, 0, MESHLINK_CHANNEL_UDP);
64 assert(client->channel);
68 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
73 assert(meshlink_channel_get_flags(mesh, channel) == MESHLINK_CHANNEL_UDP);
74 meshlink_set_channel_receive_cb(mesh, channel, server_receive_cb);
77 meshlink_channel_t **c = mesh->priv;
79 for(int i = 0; i < 3; i++) {
84 set_sync_flag(&accept_flag, true);
95 meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_cb);
97 // Open four new meshlink instance, the server and three peers.
99 const char *names[3] = {"foo", "bar", "baz"};
100 struct client clients[3];
101 meshlink_channel_t *channels[3] = {NULL, NULL, NULL};
102 memset(clients, 0, sizeof(clients));
104 assert(meshlink_destroy("channels_udp_conf.0"));
105 meshlink_handle_t *server = meshlink_open("channels_udp_conf.0", "server", "channels-udp", DEV_CLASS_BACKBONE);
107 meshlink_enable_discovery(server, false);
108 server->priv = channels;
109 meshlink_set_channel_accept_cb(server, accept_cb);
110 assert(meshlink_start(server));
112 for(int i = 0; i < 3; i++) {
114 snprintf(dir, sizeof(dir), "channels_udp_conf.%d", i + 1);
115 assert(meshlink_destroy(dir));
116 clients[i].mesh = meshlink_open(dir, names[i], "channels-udp", DEV_CLASS_STATIONARY);
117 assert(clients[i].mesh);
118 clients[i].mesh->priv = &clients[i];
119 meshlink_enable_discovery(clients[i].mesh, false);
120 link_meshlink_pair(server, clients[i].mesh);
121 meshlink_set_node_status_cb(clients[i].mesh, status_cb);
122 assert(meshlink_start(clients[i].mesh));
125 // Wait for all three channels to connect
127 assert(wait_sync_flag(&accept_flag, 10));
129 for(int i = 0; i < 3; i++) {
131 assert(clients[i].channel);
134 // Stream packets from server to clients for 5 seconds at 40 Mbps (1 kB * 500 Hz)
137 memset(data, 'U', sizeof(data));
139 for(int j = 0; j < 2500; j++) {
140 for(int i = 0; i < 3; i++) {
141 assert(meshlink_channel_send(server, channels[i], data, sizeof(data)) == sizeof(data));
144 const struct timespec req = {0, 2000000};
145 clock_nanosleep(CLOCK_MONOTONIC, 0, &req, NULL);
148 // Let the clients close the channels
150 for(int i = 0; i < 3; i++) {
151 meshlink_channel_close(clients[i].mesh, clients[i].channel);
152 meshlink_set_node_status_cb(clients[i].mesh, NULL);
155 assert(wait_sync_flag(&close_flag, 10));
157 // Check that the clients have received (most of) the data
159 for(int i = 0; i < 3; i++) {
160 fprintf(stderr, "%s received %zu\n", clients[i].mesh->name, clients[i].received);
163 for(int i = 0; i < 3; i++) {
164 assert(clients[i].received >= 2400000);
165 assert(clients[i].received <= 2500000);
170 for(int i = 0; i < 3; i++) {
171 meshlink_close(clients[i].mesh);
174 meshlink_close(server);