13 #include "../src/meshlink.h"
18 meshlink_handle_t *mesh;
20 bool got_large_packet;
21 struct sync_flag accept_flag;
22 struct sync_flag close_flag;
25 static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
29 // We expect always the same amount of data from the server.
31 struct client *client = mesh->priv;
33 if(!data && len == 0) {
34 set_sync_flag(&client->close_flag, true);
35 meshlink_channel_close(mesh, channel);
39 assert(len == 512 || len == 65535);
40 client->received += len;
43 client->got_large_packet = true;
47 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
51 assert(meshlink_channel_get_flags(mesh, channel) == MESHLINK_CHANNEL_UDP);
54 struct client *client = mesh->priv;
56 meshlink_set_channel_receive_cb(mesh, channel, receive_cb);
57 set_sync_flag(&client->accept_flag, true);
63 meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_cb);
65 // Open four new meshlink instance, the server and three peers.
67 const char *names[3] = {"foo", "bar", "baz"};
68 struct client clients[3];
69 meshlink_channel_t *channels[3] = {NULL, NULL, NULL};
70 memset(clients, 0, sizeof(clients));
72 assert(meshlink_destroy("channels_udp_conf.0"));
73 meshlink_handle_t *server = meshlink_open("channels_udp_conf.0", "server", "channels-udp", DEV_CLASS_BACKBONE);
75 meshlink_enable_discovery(server, false);
76 server->priv = channels;
77 assert(meshlink_start(server));
79 for(int i = 0; i < 3; i++) {
81 snprintf(dir, sizeof(dir), "channels_udp_conf.%d", i + 1);
82 assert(meshlink_destroy(dir));
83 clients[i].mesh = meshlink_open(dir, names[i], "channels-udp", DEV_CLASS_STATIONARY);
84 assert(clients[i].mesh);
85 clients[i].mesh->priv = &clients[i];
86 meshlink_enable_discovery(clients[i].mesh, false);
87 meshlink_set_channel_accept_cb(clients[i].mesh, accept_cb);
88 link_meshlink_pair(server, clients[i].mesh);
89 assert(meshlink_start(clients[i].mesh));
94 for(int i = 0; i < 3; i++) {
95 meshlink_node_t *peer = meshlink_get_node(server, names[i]);
97 channels[i] = meshlink_channel_open_ex(server, peer, 1, NULL, NULL, 0, MESHLINK_CHANNEL_UDP);
101 // Wait for all three channels to connect
103 for(int i = 0; i < 3; i++) {
104 assert(wait_sync_flag(&clients[i].accept_flag, 10));
107 // Check that we can send up to 65535 bytes without errors
109 char large_data[65535] = "";
111 for(int i = 0; i < 3; i++) {
112 assert(meshlink_channel_send(server, channels[i], large_data, sizeof(large_data)) == sizeof(large_data));
115 // Check that we can send zero bytes without errors
117 for(int i = 0; i < 3; i++) {
118 assert(meshlink_channel_send(server, channels[i], large_data, 0) == 0);
121 // Assert that any larger packets are not allowed
123 assert(meshlink_channel_send(server, channels[0], large_data, 65536) == -1);
125 // Stream packets from server to clients for 5 seconds at 40 Mbps (1 kB * 500 Hz)
128 memset(data, 'U', sizeof(data));
130 for(int j = 0; j < 2500; j++) {
131 for(int i = 0; i < 3; i++) {
132 size_t result = meshlink_channel_send(server, channels[i], data, sizeof(data));
133 assert(result == sizeof(data));
136 const struct timespec req = {0, 2000000};
137 clock_nanosleep(CLOCK_MONOTONIC, 0, &req, NULL);
140 // Close the channels
142 for(int i = 0; i < 3; i++) {
143 meshlink_channel_close(server, channels[i]);
146 for(int i = 0; i < 3; i++) {
147 assert(wait_sync_flag(&clients[i].close_flag, 10));
150 // Check that the clients have received (most of) the data
152 for(int i = 0; i < 3; i++) {
153 fprintf(stderr, "%s received %zu\n", clients[i].mesh->name, clients[i].received);
156 bool got_large_packet = false;
158 for(int i = 0; i < 3; i++) {
159 assert(clients[i].received >= 1000000);
160 assert(clients[i].received <= 1345536);
161 got_large_packet |= clients[i].got_large_packet;
164 assert(got_large_packet);
168 for(int i = 0; i < 3; i++) {
169 meshlink_close(clients[i].mesh);
172 meshlink_close(server);