From a4f17d14743085c592f12ddde3430f84c5f8b2e7 Mon Sep 17 00:00:00 2001
From: Andriy Gelman <andriy.gelman@gmail.com>
Date: Mon, 4 Dec 2023 09:40:49 -0500
Subject: [PATCH] shell: telnet: don't close connection on EAGAIN

This error can occur if the tcp window size is full. Instead
of closing the connection the application should sleep and
retry sending the packet.

Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
---
 subsys/shell/backends/shell_telnet.c | 50 ++++++++++++++++++++--------
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/subsys/shell/backends/shell_telnet.c b/subsys/shell/backends/shell_telnet.c
index a4dab6272996c5a..8dbb9ee9b2d21ea 100644
--- a/subsys/shell/backends/shell_telnet.c
+++ b/subsys/shell/backends/shell_telnet.c
@@ -33,6 +33,8 @@ struct shell_telnet *sh_telnet;
 #define TELNET_MIN_COMMAND_LEN 2
 #define TELNET_WILL_DO_COMMAND_LEN 3
 
+#define TELNET_RETRY_SEND_SLEEP_MS 50
+
 /* Basic TELNET implementation. */
 
 static void telnet_end_client_connection(void)
@@ -64,17 +66,27 @@ static void telnet_sent_cb(struct net_context *client,
 
 static void telnet_command_send_reply(uint8_t *msg, uint16_t len)
 {
-	int err;
-
 	if (sh_telnet->client_ctx == NULL) {
 		return;
 	}
 
-	err = net_context_send(sh_telnet->client_ctx, msg, len, telnet_sent_cb,
-			       K_FOREVER, NULL);
-	if (err < 0) {
-		LOG_ERR("Failed to send command %d, shutting down", err);
-		telnet_end_client_connection();
+	for (;;) {
+		int err;
+
+		err = net_context_send(sh_telnet->client_ctx, msg, len, telnet_sent_cb,
+				       K_FOREVER, NULL);
+
+		if (err == -EAGAIN) {
+			k_sleep(K_MSEC(TELNET_RETRY_SEND_SLEEP_MS));
+			continue;
+		}
+
+		if (err < 0) {
+			LOG_ERR("Failed to send command %d, shutting down", err);
+			telnet_end_client_connection();
+		}
+
+		break;
 	}
 }
 
@@ -185,13 +197,23 @@ static int telnet_send(void)
 		return -ENOTCONN;
 	}
 
-	err = net_context_send(sh_telnet->client_ctx, sh_telnet->line_out.buf,
-			       sh_telnet->line_out.len, telnet_sent_cb,
-			       K_FOREVER, NULL);
-	if (err < 0) {
-		LOG_ERR("Failed to send %d, shutting down", err);
-		telnet_end_client_connection();
-		return err;
+	for (;;) {
+		err = net_context_send(sh_telnet->client_ctx, sh_telnet->line_out.buf,
+				       sh_telnet->line_out.len, telnet_sent_cb,
+				       K_FOREVER, NULL);
+
+		if (err == -EAGAIN) {
+			k_sleep(K_MSEC(TELNET_RETRY_SEND_SLEEP_MS));
+			continue;
+		}
+
+		if (err < 0) {
+			LOG_ERR("Failed to send %d, shutting down", err);
+			telnet_end_client_connection();
+			return err;
+		}
+
+		break;
 	}
 
 	/* We reinitialize the line buffer */