13 #include "../src/meshlink.h"
16 static struct sync_flag accept_flag;
17 static struct sync_flag close_flag;
20 meshlink_handle_t *mesh;
21 meshlink_channel_t *channel;
23 bool got_large_packet;
26 static void server_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
29 // We expect no data from clients, apart from disconnections.
32 meshlink_channel_t **c = mesh->priv;
35 for(int i = 0; i < 3; i++) {
38 meshlink_channel_close(mesh, channel);
47 set_sync_flag(&close_flag, true);
51 static void client_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
55 // We expect always the same amount of data from the server.
57 struct client *client = mesh->priv;
58 assert(len == 512 || len == 65536);
59 client->received += len;
62 client->got_large_packet = true;
66 static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
68 struct client *client = mesh->priv;
70 if(reachable && !strcmp(node->name, "server")) {
71 assert(!client->channel);
72 client->channel = meshlink_channel_open_ex(mesh, node, 1, client_receive_cb, NULL, 0, MESHLINK_CHANNEL_UDP);
73 assert(client->channel);
77 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
82 assert(meshlink_channel_get_flags(mesh, channel) == MESHLINK_CHANNEL_UDP);
83 meshlink_set_channel_receive_cb(mesh, channel, server_receive_cb);
86 meshlink_channel_t **c = mesh->priv;
88 for(int i = 0; i < 3; i++) {
93 set_sync_flag(&accept_flag, true);
104 init_sync_flag(&accept_flag);
105 init_sync_flag(&close_flag);
107 meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_cb);
109 // Open four new meshlink instance, the server and three peers.
111 const char *names[3] = {"foo", "bar", "baz"};
112 struct client clients[3];
113 meshlink_channel_t *channels[3] = {NULL, NULL, NULL};
114 memset(clients, 0, sizeof(clients));
116 assert(meshlink_destroy("channels_udp_conf.0"));
117 meshlink_handle_t *server = meshlink_open("channels_udp_conf.0", "server", "channels-udp", DEV_CLASS_BACKBONE);
119 meshlink_enable_discovery(server, false);
120 server->priv = channels;
121 meshlink_set_channel_accept_cb(server, accept_cb);
122 assert(meshlink_start(server));
124 for(int i = 0; i < 3; i++) {
126 snprintf(dir, sizeof(dir), "channels_udp_conf.%d", i + 1);
127 assert(meshlink_destroy(dir));
128 clients[i].mesh = meshlink_open(dir, names[i], "channels-udp", DEV_CLASS_STATIONARY);
129 assert(clients[i].mesh);
130 clients[i].mesh->priv = &clients[i];
131 meshlink_enable_discovery(clients[i].mesh, false);
132 link_meshlink_pair(server, clients[i].mesh);
133 meshlink_set_node_status_cb(clients[i].mesh, status_cb);
134 assert(meshlink_start(clients[i].mesh));
137 // Wait for all three channels to connect
139 assert(wait_sync_flag(&accept_flag, 10));
141 for(int i = 0; i < 3; i++) {
143 assert(clients[i].channel);
146 // Check that we can send up to 65535 bytes without errors
148 char large_data[65536] = "";
150 for(int i = 0; i < 3; i++) {
151 assert(meshlink_channel_send(server, channels[i], large_data, sizeof(large_data) + 1) == -1);
152 assert(meshlink_channel_send(server, channels[i], large_data, sizeof(large_data)) == sizeof(large_data));
155 // Assert that packets larger than 64 kiB are not allowed
157 assert(meshlink_channel_send(server, channels[0], large_data, 65537) == -1);
159 // Stream packets from server to clients for 5 seconds at 40 Mbps (1 kB * 500 Hz)
162 memset(data, 'U', sizeof(data));
164 for(int j = 0; j < 2500; j++) {
165 for(int i = 0; i < 3; i++) {
166 assert(meshlink_channel_send(server, channels[i], data, sizeof(data)) == sizeof(data));
169 const struct timespec req = {0, 2000000};
170 nanosleep(&req, NULL);
173 // Let the clients close the channels
175 for(int i = 0; i < 3; i++) {
176 meshlink_channel_close(clients[i].mesh, clients[i].channel);
177 meshlink_set_node_status_cb(clients[i].mesh, NULL);
180 assert(wait_sync_flag(&close_flag, 10));
182 // Check that the clients have received (most of) the data
184 for(int i = 0; i < 3; i++) {
185 fprintf(stderr, "%s received %zu\n", clients[i].mesh->name, clients[i].received);
188 for(int i = 0; i < 3; i++) {
189 assert(clients[i].received >= 1000000);
190 assert(clients[i].received <= 1345536);
191 assert(clients[i].got_large_packet);
196 for(int i = 0; i < 3; i++) {
197 meshlink_close(clients[i].mesh);
200 meshlink_close(server);