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 log_cb(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) {
22 static struct timeval tv0;
26 gettimeofday(&tv0, NULL);
29 gettimeofday(&tv, NULL);
30 fprintf(stderr, "%u.%.03u ", (unsigned int)(tv.tv_sec - tv0.tv_sec), (unsigned int)tv.tv_usec / 1000);
33 fprintf(stderr, "(%s) ", mesh->name);
36 fprintf(stderr, "[%d] %s\n", level, text);
39 static void server_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
42 // We expect no data from clients, apart from disconnections.
45 meshlink_channel_t **c = mesh->priv;
48 for(int i = 0; i < 3; i++) {
51 fprintf(stderr, "server received channel %d closure from %s\n", i, channel->node->name);
53 meshlink_channel_close(mesh, channel);
62 set_sync_flag(&close_flag, true);
66 static void client_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
70 // We expect always the same amount of data from the server.
73 struct client *client = mesh->priv;
74 client->received += len;
77 static void status_cb(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
79 struct client *client = mesh->priv;
83 if(!strcmp(node->name, "server")) {
84 assert(!client->channel);
85 client->channel = meshlink_channel_open_ex(mesh, node, 1, client_receive_cb, NULL, 0, MESHLINK_CHANNEL_UDP);
86 assert(client->channel);
90 static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
95 assert(meshlink_channel_get_flags(mesh, channel) == MESHLINK_CHANNEL_UDP);
96 meshlink_set_channel_receive_cb(mesh, channel, server_receive_cb);
99 meshlink_channel_t **c = mesh->priv;
101 for(int i = 0; i < 3; i++) {
103 fprintf(stderr, "server accepted channel %d from %s\n", i, channel->node->name);
107 set_sync_flag(&accept_flag, true);
118 //meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_cb);
120 // Open two new meshlink instance.
122 const char *names[3] = {"foo", "bar", "baz"};
123 struct client clients[3];
124 meshlink_channel_t *channels[3] = {NULL, NULL, NULL};
125 memset(clients, 0, sizeof(clients));
127 meshlink_handle_t *server = meshlink_open("channels_udp_conf.0", "server", "channels-udp", DEV_CLASS_BACKBONE);
129 meshlink_enable_discovery(server, false);
130 server->priv = channels;
131 meshlink_set_channel_accept_cb(server, accept_cb);
132 assert(meshlink_start(server));
134 for(int i = 0; i < 3; i++) {
136 snprintf(dir, sizeof(dir), "channels_udp_conf.%d", i + 1);
137 clients[i].mesh = meshlink_open(dir, names[i], "channels-udp", DEV_CLASS_STATIONARY);
138 assert(clients[i].mesh);
139 clients[i].mesh->priv = &clients[i];
140 meshlink_enable_discovery(clients[i].mesh, false);
141 link_meshlink_pair(server, clients[i].mesh);
142 meshlink_set_node_status_cb(clients[i].mesh, status_cb);
143 assert(meshlink_start(clients[i].mesh));
146 // Wait for all three channels to connect
148 assert(wait_sync_flag(&accept_flag, 10));
150 for(int i = 0; i < 3; i++) {
152 assert(clients[i].channel);
155 // Stream packets from server to clients for 5 seconds at 40 Mbps (1 kB * 500 Hz)
159 for(int j = 0; j < 2500; j++) {
160 for(int i = 0; i < 3; i++) {
161 assert(meshlink_channel_send(server, channels[i], data, sizeof(data)) == sizeof(data));
164 const struct timespec req = {0, 2000000};
165 clock_nanosleep(CLOCK_MONOTONIC, 0, &req, NULL);
168 // Let the clients close the channels
170 for(int i = 0; i < 3; i++) {
171 meshlink_channel_close(clients[i].mesh, clients[i].channel);
172 meshlink_set_node_status_cb(clients[i].mesh, NULL);
175 assert(wait_sync_flag(&close_flag, 10));
177 // Check that the clients have received (most of) the data
179 for(int i = 0; i < 3; i++) {
180 fprintf(stderr, "%s received %zu\n", clients[i].mesh->name, clients[i].received);
183 for(int i = 0; i < 3; i++) {
184 assert(clients[i].received >= 2400000);
185 assert(clients[i].received <= 2500000);
190 for(int i = 0; i < 3; i++) {
191 meshlink_close(clients[i].mesh);
194 meshlink_close(server);