Browse Source

Implement "comm", a fairly close port of M0o+'s version

Brian Starkey 2 years ago
parent
commit
3bdad9eb2b
2 changed files with 325 additions and 32 deletions
  1. 1
    1
      CMakeLists.txt
  2. 324
    31
      main.c

+ 1
- 1
CMakeLists.txt View File

19
 target_include_directories(picowota PRIVATE ${CMAKE_CURRENT_LIST_DIR})
19
 target_include_directories(picowota PRIVATE ${CMAKE_CURRENT_LIST_DIR})
20
 
20
 
21
 target_link_libraries(picowota
21
 target_link_libraries(picowota
22
-	pico_cyw43_arch_lwip_threadsafe_background
22
+	pico_cyw43_arch_lwip_poll
23
 	pico_stdlib
23
 	pico_stdlib
24
 )
24
 )

+ 324
- 31
main.c View File

25
 
25
 
26
 #define MAX_LEN 2048
26
 #define MAX_LEN 2048
27
 
27
 
28
+#define COMM_MAX_NARG     5
29
+#define COMM_MAX_DATA_LEN 1024
30
+
31
+#define COMM_RSP_OK       (('O' << 0) | ('K' << 8) | ('O' << 16) | ('K' << 24))
32
+#define COMM_RSP_ERR      (('E' << 0) | ('R' << 8) | ('R' << 16) | ('!' << 24))
33
+#define CMD_SYNC          (('S' << 0) | ('Y' << 8) | ('N' << 16) | ('C' << 24))
34
+#define RSP_SYNC          (('W' << 0) | ('O' << 8) | ('T' << 16) | ('A' << 24))
35
+
36
+struct comm_command {
37
+	uint32_t opcode;
38
+	uint32_t nargs;
39
+	uint32_t resp_nargs;
40
+	uint32_t (*size)(uint32_t *args_in, uint32_t *data_len_out, uint32_t *resp_data_len_out);
41
+	uint32_t (*handle)(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out);
42
+};
43
+
28
 enum conn_state {
44
 enum conn_state {
29
 	CONN_STATE_WAIT_FOR_SYNC,
45
 	CONN_STATE_WAIT_FOR_SYNC,
30
 	CONN_STATE_READ_OPCODE,
46
 	CONN_STATE_READ_OPCODE,
32
 	CONN_STATE_READ_DATA,
48
 	CONN_STATE_READ_DATA,
33
 	CONN_STATE_HANDLE,
49
 	CONN_STATE_HANDLE,
34
 	CONN_STATE_WRITE_RESP,
50
 	CONN_STATE_WRITE_RESP,
35
-	CONN_STATE_ERROR,
51
+	CONN_STATE_WRITE_ERROR,
36
 	CONN_STATE_CLOSED,
52
 	CONN_STATE_CLOSED,
37
 };
53
 };
38
 
54
 
39
-struct tcp_ctx {
55
+struct tcp_comm_ctx {
40
 	struct tcp_pcb *serv_pcb;
56
 	struct tcp_pcb *serv_pcb;
41
 	volatile bool serv_done;
57
 	volatile bool serv_done;
58
+	enum conn_state conn_state;
42
 
59
 
43
 	struct tcp_pcb *conn_pcb;
60
 	struct tcp_pcb *conn_pcb;
44
-	uint8_t buf[MAX_LEN];
45
-	size_t bytes_remaining;
46
-	enum conn_state conn_state;
61
+	uint8_t buf[(sizeof(uint32_t) * (1 + COMM_MAX_NARG)) + COMM_MAX_DATA_LEN];
62
+	uint16_t rx_bytes_received;
63
+	uint16_t rx_bytes_remaining;
64
+
65
+	uint16_t tx_bytes_sent;
66
+	uint16_t tx_bytes_remaining;
67
+
68
+	uint32_t resp_data_len;
69
+
70
+	const struct comm_command *cmd;
71
+	const struct comm_command *const *cmds;
72
+	unsigned int n_cmds;
73
+	uint32_t sync_opcode;
47
 };
74
 };
48
 
75
 
49
-static err_t tcp_conn_close(struct tcp_ctx *ctx)
76
+#define COMM_BUF_OPCODE(_buf)       ((uint32_t *)((uint8_t *)(_buf)))
77
+#define COMM_BUF_ARGS(_buf)         ((uint32_t *)((uint8_t *)(_buf) + sizeof(uint32_t)))
78
+#define COMM_BUF_BODY(_buf, _nargs) ((uint8_t *)(_buf) + (sizeof(uint32_t) * ((_nargs) + 1)))
79
+
80
+static const struct comm_command *find_command_desc(struct tcp_comm_ctx *ctx, uint32_t opcode)
81
+{
82
+	unsigned int i;
83
+
84
+	for (i = 0; i < ctx->n_cmds; i++) {
85
+		if (ctx->cmds[i]->opcode == opcode) {
86
+			return ctx->cmds[i];
87
+		}
88
+	}
89
+
90
+	return NULL;
91
+}
92
+
93
+static bool is_error(uint32_t status)
94
+{
95
+	return status == COMM_RSP_ERR;
96
+}
97
+
98
+static int tcp_conn_sync_begin(struct tcp_comm_ctx *ctx);
99
+static int tcp_conn_sync_complete(struct tcp_comm_ctx *ctx);
100
+static int tcp_conn_opcode_begin(struct tcp_comm_ctx *ctx);
101
+static int tcp_conn_opcode_complete(struct tcp_comm_ctx *ctx);
102
+static int tcp_conn_args_begin(struct tcp_comm_ctx *ctx);
103
+static int tcp_conn_args_complete(struct tcp_comm_ctx *ctx);
104
+static int tcp_conn_data_begin(struct tcp_comm_ctx *ctx, uint32_t data_len);
105
+static int tcp_conn_data_complete(struct tcp_comm_ctx *ctx);
106
+static int tcp_conn_response_begin(struct tcp_comm_ctx *ctx);
107
+static int tcp_conn_response_complete(struct tcp_comm_ctx *ctx);
108
+static int tcp_conn_error_begin(struct tcp_comm_ctx *ctx);
109
+
110
+static int tcp_conn_sync_begin(struct tcp_comm_ctx *ctx)
111
+{
112
+	ctx->conn_state = CONN_STATE_WAIT_FOR_SYNC;
113
+	ctx->rx_bytes_received = 0;
114
+	ctx->rx_bytes_remaining = sizeof(uint32_t);
115
+
116
+	DEBUG_printf("sync_begin %d\n", ctx->rx_bytes_remaining);
117
+}
118
+
119
+static int tcp_conn_sync_complete(struct tcp_comm_ctx *ctx)
120
+{
121
+	if (ctx->sync_opcode != *COMM_BUF_OPCODE(ctx->buf)) {
122
+		DEBUG_printf("sync not correct: %c%c%c%c\n", ctx->buf[0], ctx->buf[1], ctx->buf[2], ctx->buf[3]);
123
+		return tcp_conn_error_begin(ctx);
124
+	}
125
+
126
+	return tcp_conn_opcode_complete(ctx);
127
+}
128
+
129
+static int tcp_conn_opcode_begin(struct tcp_comm_ctx *ctx)
130
+{
131
+	ctx->conn_state = CONN_STATE_READ_OPCODE;
132
+	ctx->rx_bytes_received = 0;
133
+	ctx->rx_bytes_remaining = sizeof(uint32_t);
134
+
135
+	return 0;
136
+}
137
+
138
+static int tcp_conn_opcode_complete(struct tcp_comm_ctx *ctx)
139
+{
140
+	ctx->cmd = find_command_desc(ctx, *COMM_BUF_OPCODE(ctx->buf));
141
+	if (!ctx->cmd) {
142
+		DEBUG_printf("no command for '%c%c%c%c'\n", ctx->buf[0], ctx->buf[1], ctx->buf[2], ctx->buf[3]);
143
+		return tcp_conn_error_begin(ctx);
144
+	} else {
145
+		DEBUG_printf("got command '%c%c%c%c'\n", ctx->buf[0], ctx->buf[1], ctx->buf[2], ctx->buf[3]);
146
+	}
147
+
148
+	return tcp_conn_args_begin(ctx);
149
+}
150
+
151
+static int tcp_conn_args_begin(struct tcp_comm_ctx *ctx)
152
+{
153
+	ctx->conn_state = CONN_STATE_READ_ARGS;
154
+	ctx->rx_bytes_received = 0;
155
+	ctx->rx_bytes_remaining = ctx->cmd->nargs * sizeof(uint32_t);
156
+
157
+	if (ctx->cmd->nargs == 0) {
158
+		return tcp_conn_args_complete(ctx);
159
+	}
160
+
161
+	return 0;
162
+}
163
+
164
+static int tcp_conn_args_complete(struct tcp_comm_ctx *ctx)
165
+{
166
+	const struct comm_command *cmd = ctx->cmd;
167
+
168
+	uint32_t data_len = 0;
169
+
170
+	if (cmd->size) {
171
+		uint32_t status = cmd->size(COMM_BUF_ARGS(ctx->buf),
172
+					    &data_len,
173
+					    &ctx->resp_data_len);
174
+		if (is_error(status)) {
175
+			return tcp_conn_error_begin(ctx);
176
+		}
177
+	}
178
+
179
+	return tcp_conn_data_begin(ctx, data_len);
180
+}
181
+
182
+static int tcp_conn_data_begin(struct tcp_comm_ctx *ctx, uint32_t data_len)
183
+{
184
+	const struct comm_command *cmd = ctx->cmd;
185
+
186
+	ctx->conn_state = CONN_STATE_READ_DATA;
187
+	ctx->rx_bytes_received = 0;
188
+	ctx->rx_bytes_remaining = data_len;
189
+
190
+	if (data_len == 0) {
191
+		return tcp_conn_data_complete(ctx);
192
+	}
193
+
194
+
195
+	return 0;
196
+}
197
+
198
+static int tcp_conn_data_complete(struct tcp_comm_ctx *ctx)
199
+{
200
+	const struct comm_command *cmd = ctx->cmd;
201
+
202
+	if (cmd->handle) {
203
+		uint32_t status = cmd->handle(COMM_BUF_ARGS(ctx->buf),
204
+					      COMM_BUF_BODY(ctx->buf, cmd->nargs),
205
+					      COMM_BUF_ARGS(ctx->buf),
206
+					      COMM_BUF_BODY(ctx->buf, cmd->resp_nargs));
207
+		if (is_error(status)) {
208
+			return tcp_conn_error_begin(ctx);
209
+		}
210
+
211
+		*COMM_BUF_OPCODE(ctx->buf) = status;
212
+	} else {
213
+		// TODO: Should we just assert(desc->handle)?
214
+		*COMM_BUF_OPCODE(ctx->buf) = COMM_RSP_OK;
215
+	}
216
+
217
+	return tcp_conn_response_begin(ctx);
218
+}
219
+
220
+static int tcp_conn_response_begin(struct tcp_comm_ctx *ctx)
221
+{
222
+	ctx->conn_state = CONN_STATE_WRITE_RESP;
223
+	ctx->tx_bytes_sent = 0;
224
+	ctx->tx_bytes_remaining = ctx->resp_data_len + ((ctx->cmd->resp_nargs + 1) * sizeof(uint32_t));
225
+
226
+	err_t err = tcp_write(ctx->conn_pcb, ctx->buf, ctx->tx_bytes_remaining, 0);
227
+	if (err != ERR_OK) {
228
+		return -1;
229
+	}
230
+
231
+	return 0;
232
+}
233
+
234
+static int tcp_conn_error_begin(struct tcp_comm_ctx *ctx)
235
+{
236
+	ctx->conn_state = CONN_STATE_WRITE_ERROR;
237
+	ctx->tx_bytes_sent = 0;
238
+	ctx->tx_bytes_remaining = sizeof(uint32_t);
239
+
240
+	*COMM_BUF_OPCODE(ctx->buf) = COMM_RSP_ERR;
241
+
242
+	err_t err = tcp_write(ctx->conn_pcb, ctx->buf, ctx->tx_bytes_remaining, 0);
243
+	if (err != ERR_OK) {
244
+		return -1;
245
+	}
246
+
247
+	return 0;
248
+}
249
+
250
+
251
+static int tcp_conn_response_complete(struct tcp_comm_ctx *ctx)
252
+{
253
+	return tcp_conn_opcode_begin(ctx);
254
+}
255
+
256
+static int tcp_conn_rx_complete(struct tcp_comm_ctx *ctx)
257
+{
258
+	switch (ctx->conn_state) {
259
+	case CONN_STATE_WAIT_FOR_SYNC:
260
+		return tcp_conn_sync_complete(ctx);
261
+	case CONN_STATE_READ_OPCODE:
262
+		return tcp_conn_opcode_complete(ctx);
263
+	case CONN_STATE_READ_ARGS:
264
+		return tcp_conn_args_complete(ctx);
265
+	case CONN_STATE_READ_DATA:
266
+		return tcp_conn_data_complete(ctx);
267
+	default:
268
+		return -1;
269
+	}
270
+}
271
+
272
+static int tcp_conn_tx_complete(struct tcp_comm_ctx *ctx)
273
+{
274
+	switch (ctx->conn_state) {
275
+	case CONN_STATE_WRITE_RESP:
276
+		return tcp_conn_response_complete(ctx);
277
+	case CONN_STATE_WRITE_ERROR:
278
+		return -1;
279
+	default:
280
+		return -1;
281
+	}
282
+}
283
+
284
+static err_t tcp_conn_close(struct tcp_comm_ctx *ctx)
50
 {
285
 {
51
 	err_t err = ERR_OK;
286
 	err_t err = ERR_OK;
52
 
287
 
76
 
311
 
77
 static err_t tcp_server_close(void *arg)
312
 static err_t tcp_server_close(void *arg)
78
 {
313
 {
79
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
314
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
80
 	err_t err = ERR_OK;
315
 	err_t err = ERR_OK;
81
 
316
 
82
 	err = tcp_conn_close(ctx);
317
 	err = tcp_conn_close(ctx);
104
 
339
 
105
 static void tcp_server_complete(void *arg, int status)
340
 static void tcp_server_complete(void *arg, int status)
106
 {
341
 {
107
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
342
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
108
 	if (status == 0) {
343
 	if (status == 0) {
109
 		DEBUG_printf("server completed normally\n");
344
 		DEBUG_printf("server completed normally\n");
110
 	} else {
345
 	} else {
117
 
352
 
118
 static err_t tcp_conn_complete(void *arg, int status)
353
 static err_t tcp_conn_complete(void *arg, int status)
119
 {
354
 {
120
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
355
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
121
 	if (status == 0) {
356
 	if (status == 0) {
122
 		DEBUG_printf("conn completed normally\n");
357
 		DEBUG_printf("conn completed normally\n");
123
 	} else {
358
 	} else {
128
 
363
 
129
 static err_t tcp_conn_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
364
 static err_t tcp_conn_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
130
 {
365
 {
131
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
366
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
132
 	DEBUG_printf("tcp_server_sent %u\n", len);
367
 	DEBUG_printf("tcp_server_sent %u\n", len);
133
 
368
 
369
+	cyw43_arch_lwip_check();
370
+	if (len > ctx->tx_bytes_remaining) {
371
+		DEBUG_printf("tx len %d > remaining %d\n", len, ctx->tx_bytes_remaining);
372
+		return tcp_conn_complete(ctx, ERR_ARG);
373
+	}
374
+
375
+	ctx->tx_bytes_remaining -= len;
376
+	ctx->tx_bytes_sent += len;
377
+
378
+	if (ctx->tx_bytes_remaining == 0) {
379
+		int res = tcp_conn_tx_complete(ctx);
380
+		if (res) {
381
+			return tcp_conn_complete(ctx, ERR_ARG);
382
+		}
383
+	}
384
+
134
 	return ERR_OK;
385
 	return ERR_OK;
135
 }
386
 }
136
 
387
 
137
 static err_t tcp_conn_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
388
 static err_t tcp_conn_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
138
 {
389
 {
139
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
390
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
140
 	if (!p) {
391
 	if (!p) {
392
+		DEBUG_printf("no pbuf\n");
141
 		return tcp_conn_complete(ctx, 0);
393
 		return tcp_conn_complete(ctx, 0);
142
 	}
394
 	}
143
 
395
 
148
 	if (p->tot_len > 0) {
400
 	if (p->tot_len > 0) {
149
 		DEBUG_printf("tcp_server_recv %d err %d\n", p->tot_len, err);
401
 		DEBUG_printf("tcp_server_recv %d err %d\n", p->tot_len, err);
150
 
402
 
403
+		size_t to_copy = p->tot_len > ctx->rx_bytes_remaining ? ctx->rx_bytes_remaining : p->tot_len;
404
+
151
 		// Receive the buffer
405
 		// Receive the buffer
152
-		pbuf_copy_partial(p, ctx->buf, p->tot_len, 0);
406
+		if (pbuf_copy_partial(p, ctx->buf + ctx->rx_bytes_received, to_copy, 0) != to_copy) {
407
+			DEBUG_printf("wrong copy len\n");
408
+			return tcp_conn_complete(ctx, ERR_ARG);
409
+		}
153
 
410
 
154
-		ctx->buf[p->tot_len] = '\0';
155
-		printf("%s\n", ctx->buf);
411
+		ctx->rx_bytes_received += to_copy;
412
+		ctx->rx_bytes_remaining -= to_copy;
156
 		tcp_recved(tpcb, p->tot_len);
413
 		tcp_recved(tpcb, p->tot_len);
414
+
415
+		if (ctx->rx_bytes_remaining == 0) {
416
+			int res = tcp_conn_rx_complete(ctx);
417
+			if (res) {
418
+				return tcp_conn_complete(ctx, ERR_ARG);
419
+			}
420
+		}
157
 	}
421
 	}
158
 	pbuf_free(p);
422
 	pbuf_free(p);
159
 
423
 
168
 
432
 
169
 static void tcp_conn_err(void *arg, err_t err)
433
 static void tcp_conn_err(void *arg, err_t err)
170
 {
434
 {
171
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
435
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
172
 
436
 
173
 	DEBUG_printf("tcp_conn_err %d\n", err);
437
 	DEBUG_printf("tcp_conn_err %d\n", err);
174
 
438
 
175
 	ctx->conn_pcb = NULL;
439
 	ctx->conn_pcb = NULL;
176
 	ctx->conn_state = CONN_STATE_CLOSED;
440
 	ctx->conn_state = CONN_STATE_CLOSED;
177
-	ctx->bytes_remaining = 0;
441
+	ctx->rx_bytes_remaining = 0;
178
 	cyw43_arch_gpio_put (0, false);
442
 	cyw43_arch_gpio_put (0, false);
179
 }
443
 }
180
 
444
 
181
-static void tcp_conn_wait_for_sync(struct tcp_ctx *ctx)
182
-{
183
-	ctx->conn_state = CONN_STATE_WAIT_FOR_SYNC;
184
-	ctx->bytes_remaining = 4;
185
-}
186
-
187
-static void tcp_conn_init(struct tcp_ctx *ctx, struct tcp_pcb *pcb)
445
+static void tcp_conn_init(struct tcp_comm_ctx *ctx, struct tcp_pcb *pcb)
188
 {
446
 {
189
 	ctx->conn_pcb = pcb;
447
 	ctx->conn_pcb = pcb;
190
 	tcp_arg(pcb, ctx);
448
 	tcp_arg(pcb, ctx);
449
+
450
+	cyw43_arch_gpio_put (0, true);
451
+
452
+	tcp_conn_sync_begin(ctx);
453
+
191
 	tcp_sent(pcb, tcp_conn_sent);
454
 	tcp_sent(pcb, tcp_conn_sent);
192
 	tcp_recv(pcb, tcp_conn_recv);
455
 	tcp_recv(pcb, tcp_conn_recv);
193
 	tcp_poll(pcb, tcp_conn_poll, POLL_TIME_S * 2);
456
 	tcp_poll(pcb, tcp_conn_poll, POLL_TIME_S * 2);
194
 	tcp_err(pcb, tcp_conn_err);
457
 	tcp_err(pcb, tcp_conn_err);
195
-
196
-	cyw43_arch_gpio_put (0, true);
197
-
198
-	tcp_conn_wait_for_sync(ctx);
199
 }
458
 }
200
 
459
 
201
 static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err)
460
 static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err)
202
 {
461
 {
203
-	struct tcp_ctx *ctx = (struct tcp_ctx *)arg;
462
+	struct tcp_comm_ctx *ctx = (struct tcp_comm_ctx *)arg;
204
 
463
 
205
 	if (err != ERR_OK || client_pcb == NULL) {
464
 	if (err != ERR_OK || client_pcb == NULL) {
206
 		DEBUG_printf("Failure in accept\n");
465
 		DEBUG_printf("Failure in accept\n");
220
 	return ERR_OK;
479
 	return ERR_OK;
221
 }
480
 }
222
 
481
 
223
-static err_t tcp_server_listen(struct tcp_ctx *ctx)
482
+static err_t tcp_server_listen(struct tcp_comm_ctx *ctx)
224
 {
483
 {
225
 	DEBUG_printf("Starting server at %s on port %u\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), TCP_PORT);
484
 	DEBUG_printf("Starting server at %s on port %u\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), TCP_PORT);
226
 
485
 
251
 	return ERR_OK;
510
 	return ERR_OK;
252
 }
511
 }
253
 
512
 
513
+static uint32_t handle_sync(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
514
+{
515
+	return RSP_SYNC;
516
+}
517
+
518
+const struct comm_command util_sync_cmd = {
519
+	.opcode = CMD_SYNC,
520
+	.nargs = 0,
521
+	.resp_nargs = 0,
522
+	.size = NULL,
523
+	.handle = &handle_sync,
524
+};
525
+
526
+static void tcp_comm_init(struct tcp_comm_ctx *ctx, const struct comm_command *const *cmds,
527
+		unsigned int n_cmds, uint32_t sync_opcode)
528
+{
529
+	unsigned int i;
530
+	for (i = 0; i < n_cmds; i++) {
531
+		assert(cmds[i]->nargs <= MAX_NARG);
532
+		assert(cmds[i]->resp_nargs <= MAX_NARG);
533
+	}
534
+
535
+	memset(ctx, 0, sizeof(*ctx));
536
+	ctx->cmds = cmds;
537
+	ctx->n_cmds = n_cmds;
538
+	ctx->sync_opcode = sync_opcode;
539
+}
540
+
254
 int main()
541
 int main()
255
 {
542
 {
256
 	stdio_init_all();
543
 	stdio_init_all();
272
 		printf("Connected.\n");
559
 		printf("Connected.\n");
273
 	}
560
 	}
274
 
561
 
275
-	struct tcp_ctx tcp = { 0 };
562
+	struct tcp_comm_ctx tcp;
563
+	const struct comm_command *cmds[] = {
564
+		&util_sync_cmd,
565
+	};
566
+
567
+	tcp_comm_init(&tcp, cmds, 1, CMD_SYNC);
276
 
568
 
277
 	for ( ; ; ) {
569
 	for ( ; ; ) {
278
 		err_t err = tcp_server_listen(&tcp);
570
 		err_t err = tcp_server_listen(&tcp);
283
 		}
575
 		}
284
 
576
 
285
 		while (!tcp.serv_done) {
577
 		while (!tcp.serv_done) {
286
-			sleep_ms(1000);
578
+			cyw43_arch_poll();
579
+			sleep_ms(10);
287
 		}
580
 		}
288
 	}
581
 	}
289
 
582
 

Loading…
Cancel
Save