13 #include "../src/meshlink.h"
16 #define SMALL_SIZE 512
17 #define SMALL_COUNT 2500
18 #define LARGE_SIZE 131072
22 static struct channel {
23 meshlink_channel_t *channel;
25 struct sync_flag open_flag;
26 struct sync_flag close_flag;
27 } channels[NCHANNELS];
29 static size_t received[NCHANNELS];
31 static struct sync_flag pmtu_flag;
33 static void a_pmtu_cb(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t pmtu) {
36 if(pmtu >= SMALL_SIZE && !strcmp(node->name, "b")) {
37 set_sync_flag(&pmtu_flag, true);
41 static void a_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
42 struct channel *info = channel->priv;
46 set_sync_flag(&info->close_flag, true);
47 meshlink_channel_close(mesh, channel);
52 static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
57 meshlink_channel_shutdown(mesh, channel, SHUT_WR);
60 static void b_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
62 meshlink_channel_close(mesh, channel);
67 size_t *rx = channel->priv;
71 static bool b_accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint16_t port, const void *data, size_t len) {
80 channel->priv = &received[i++];
82 meshlink_set_channel_receive_cb(mesh, channel, b_receive_cb);
86 static void a_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len) {
89 meshlink_set_channel_poll_cb(mesh, channel, NULL);
91 struct channel *info = channel->priv;
94 set_sync_flag(&info->open_flag, true);
98 meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_cb);
100 meshlink_handle_t *a, *b;
101 open_meshlink_pair(&a, &b, "channels-mixed");
103 meshlink_set_channel_accept_cb(b, b_accept_cb);
104 meshlink_set_node_pmtu_cb(a, a_pmtu_cb);
105 start_meshlink_pair(a, b);
107 // Create a number of TCP and UDP channels
109 meshlink_node_t *nb = meshlink_get_node(a, "b");
111 for(int i = 0; i < NCHANNELS; i++) {
112 channels[i].udp = i % 2 == 1;
113 init_sync_flag(&channels[i].open_flag);
114 init_sync_flag(&channels[i].close_flag);
115 channels[i].channel = meshlink_channel_open_ex(a, nb, PORT, a_receive_cb, &channels[i], 0, channels[i].udp ? MESHLINK_CHANNEL_UDP : MESHLINK_CHANNEL_TCP);
116 meshlink_set_channel_poll_cb(a, channels[i].channel, a_poll_cb);
117 assert(channels[i].channel);
120 // Wait for all channels to connect
122 for(int i = 0; i < NCHANNELS; i++) {
123 assert(wait_sync_flag(&channels[i].open_flag, 10));
126 // Wait for PMTU to finish
128 assert(wait_sync_flag(&pmtu_flag, 10));
130 // Send data on all channels
132 size_t size = SMALL_SIZE * SMALL_COUNT;
133 char *data = malloc(size);
134 memset(data, 'U', size);
136 for(int i = 0; i < NCHANNELS; i++) {
137 assert(meshlink_channel_aio_send(a, channels[i].channel, data, size, aio_cb, &channels[i]));
140 // Wait for the other end to close the channels
142 for(int i = 0; i < NCHANNELS; i++) {
143 assert(wait_sync_flag(&channels[i].close_flag, 10));
146 // Check that most of the data has been transmitted
148 for(int i = 0; i < NCHANNELS; i++) {
149 fprintf(stderr, "%d received %zu\n", i, received[i]);
152 int received_all = 0;
154 for(int i = 0; i < NCHANNELS; i++) {
155 assert(received[i] >= size / 2);
156 assert(received[i] <= size);
158 if(received[i] == size) {
163 assert(received_all >= NCHANNELS / 2);
167 close_meshlink_pair(a, b);