#include "../src/meshlink.h"
#include "utils.h"
+#define SMALL_SIZE 512
+#define SMALL_COUNT 2500
+#define LARGE_SIZE 131072
+
static struct sync_flag accept_flag;
-static struct sync_flag close_flag;
struct client {
meshlink_handle_t *mesh;
meshlink_channel_t *channel;
size_t received;
bool got_large_packet;
+ struct sync_flag close_flag;
};
-static void server_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
- (void)data;
-
- // We expect no data from clients, apart from disconnections.
- assert(len == 0);
-
- meshlink_channel_t **c = mesh->priv;
- int count = 0;
-
- for(int i = 0; i < 3; i++) {
- if(c[i] == channel) {
- c[i] = NULL;
- meshlink_channel_close(mesh, channel);
- }
-
- if(c[i]) {
- count++;
- }
- }
+static void client_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
+ assert(mesh->priv);
+ struct client *client = mesh->priv;
- if(!count) {
- set_sync_flag(&close_flag, true);
+ if(!data && !len) {
+ set_sync_flag(&client->close_flag, true);
+ meshlink_channel_close(mesh, channel);
+ return;
}
-}
-
-static void client_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
- (void)channel;
- (void)data;
// We expect always the same amount of data from the server.
- assert(mesh->priv);
- struct client *client = mesh->priv;
- assert(len == 512 || len == 65536);
+ assert(len == 512 || len == LARGE_SIZE);
client->received += len;
- if(len == 65536) {
+ if(len == LARGE_SIZE) {
client->got_large_packet = true;
}
}
assert(port == 1);
assert(meshlink_channel_get_flags(mesh, channel) == MESHLINK_CHANNEL_UDP);
- meshlink_set_channel_receive_cb(mesh, channel, server_receive_cb);
assert(mesh->priv);
meshlink_channel_t **c = mesh->priv;
int main(void) {
init_sync_flag(&accept_flag);
- init_sync_flag(&close_flag);
meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_cb);
char dir[100];
snprintf(dir, sizeof(dir), "channels_udp_conf.%d", i + 1);
assert(meshlink_destroy(dir));
+ init_sync_flag(&clients[i].close_flag);
clients[i].mesh = meshlink_open(dir, names[i], "channels-udp", DEV_CLASS_STATIONARY);
assert(clients[i].mesh);
clients[i].mesh->priv = &clients[i];
// Check that we can send up to 65535 bytes without errors
- char large_data[65536] = "";
+ char large_data[LARGE_SIZE] = "";
for(int i = 0; i < 3; i++) {
- assert(meshlink_channel_send(server, channels[i], large_data, sizeof(large_data) + 1) == -1);
assert(meshlink_channel_send(server, channels[i], large_data, sizeof(large_data)) == sizeof(large_data));
}
- // Assert that packets larger than 64 kiB are not allowed
+ // Assert that packets larger than 16 MiB are not allowed
- assert(meshlink_channel_send(server, channels[0], large_data, 65537) == -1);
+ assert(meshlink_channel_send(server, channels[0], large_data, 16777216) == -1);
// Stream packets from server to clients for 5 seconds at 40 Mbps (1 kB * 500 Hz)
- char data[512];
+ char data[SMALL_SIZE];
memset(data, 'U', sizeof(data));
- for(int j = 0; j < 2500; j++) {
+ for(int j = 0; j < SMALL_COUNT; j++) {
+ const struct timespec req = {0, 2000000};
+ nanosleep(&req, NULL);
+
for(int i = 0; i < 3; i++) {
assert(meshlink_channel_send(server, channels[i], data, sizeof(data)) == sizeof(data));
}
-
- const struct timespec req = {0, 2000000};
- nanosleep(&req, NULL);
}
- // Let the clients close the channels
+ // Shutdown the write side of the server's channels
for(int i = 0; i < 3; i++) {
- meshlink_channel_close(clients[i].mesh, clients[i].channel);
- meshlink_set_node_status_cb(clients[i].mesh, NULL);
+ meshlink_channel_shutdown(server, channels[i], SHUT_WR);
}
- assert(wait_sync_flag(&close_flag, 10));
+ // Wait for the clients to finish reading all the data
+
+ for(int i = 0; i < 3; i++) {
+ assert(wait_sync_flag(&clients[i].close_flag, 10));
+ }
// Check that the clients have received (most of) the data
}
for(int i = 0; i < 3; i++) {
- assert(clients[i].received >= 1000000);
- assert(clients[i].received <= 1345536);
+ size_t max_received = SMALL_SIZE * SMALL_COUNT + LARGE_SIZE;
+ assert(clients[i].received >= max_received / 2);
+ assert(clients[i].received <= max_received);
assert(clients[i].got_large_packet);
}