shell: backends: telnet: Added support for echo option

Adding support for echo option if telnet commands are supported. This is
useful when the telnet client is in character mode. It allows to use the
arrow keys, ctrl-c and more. Something to keep in mind is that when
character mode is turned on by the client, network traffic is
considerably increased as each typed character is sent over the wire.

Note: echo mode is only supported if SHELL_TELNET_SUPPORT_COMMAND is
enabled.

Signed-off-by: David Corbeil <david.corbeil@dynon.com>
This commit is contained in:
David Corbeil 2023-09-27 13:28:39 -04:00 committed by Carles Cufí
commit 724c162821
3 changed files with 76 additions and 8 deletions

View file

@ -75,6 +75,29 @@ procedure:
to the shell.
Telnet Backend
==============
Enabling :kconfig:option:`CONFIG_SHELL_BACKEND_TELNET` will allow users to use telnet
as a shell backend. Connecting to it can be done using PuTTY or any ``telnet`` client.
For example:
.. code-block:: none
telnet <ip address> <port>
By default the telnet client won't handle telnet commands and configuration. Although
command support can be enabled with :kconfig:option:`CONFIG_SHELL_TELNET_SUPPORT_COMMAND`.
This will give the telnet client access to a very limited set of supported commands but
still can be turned on if needed. One of the command options it supports is the ``ECHO``
option. This will allow the client to be in character mode (character at a time),
similar to a UART backend in that regard. This will make the client send a character
as soon as it is typed having the effect of increasing the network traffic
considerably. For that cost, it will enable the line editing,
`tab completion <tab-feature_>`_, and `history <history-feature_>`_
features of the shell.
Commands
********
@ -428,6 +451,7 @@ These commands are activated by :kconfig:option:`CONFIG_SHELL_CMDS` set to ``y``
case of Bluetooth shell to limit the amount of transferred bytes.
* :command:`stats` - Shows shell statistics.
.. _tab-feature:
Tab Feature
***********
@ -448,6 +472,8 @@ the shell will do one of 3 possible things:
:align: center
:alt: Tab Feature usage example
.. _history-feature:
History Feature
***************

View file

@ -345,7 +345,11 @@ config SHELL_TELNET_SUPPORT_COMMAND
help
Current support is so limited it's not interesting to enable it.
However, if proven to be needed at some point, it will be possible
to extend such support.
to extend such support. It does have support for echo and "character
at a time" mode, which enable the history and line-editing features
of the shell.
IMPORTANT: This will increase network usage as a TCP packet will be
sent each time a character is typed in the telnet client.
module = SHELL_TELNET
default-timeout = 100

View file

@ -85,12 +85,52 @@ static void telnet_reply_ay_command(void)
telnet_command_send_reply((uint8_t *)alive, strlen(alive));
}
static int telnet_echo_set(const struct shell *sh, bool val)
{
int ret = shell_echo_set(sh_telnet->shell_context, val);
if (ret < 0) {
LOG_ERR("Failed to set echo to: %d, err: %d", val, ret);
}
return ret;
}
static void telnet_reply_dont_command(struct telnet_simple_command *cmd)
{
switch (cmd->opt) {
case NVT_OPT_ECHO:
int ret = telnet_echo_set(sh_telnet->shell_context, false);
if (ret >= 0) {
cmd->op = NVT_CMD_WONT;
} else {
cmd->op = NVT_CMD_WILL;
}
break;
default:
cmd->op = NVT_CMD_WONT;
break;
}
telnet_command_send_reply((uint8_t *)cmd,
sizeof(struct telnet_simple_command));
}
static void telnet_reply_do_command(struct telnet_simple_command *cmd)
{
switch (cmd->opt) {
case NVT_OPT_SUPR_GA:
cmd->op = NVT_CMD_WILL;
break;
case NVT_OPT_ECHO:
int ret = telnet_echo_set(sh_telnet->shell_context, true);
if (ret >= 0) {
cmd->op = NVT_CMD_WILL;
} else {
cmd->op = NVT_CMD_WONT;
}
break;
default:
cmd->op = NVT_CMD_WONT;
break;
@ -120,6 +160,9 @@ static void telnet_reply_command(struct telnet_simple_command *cmd)
case NVT_CMD_DO:
telnet_reply_do_command(cmd);
break;
case NVT_CMD_DONT:
telnet_reply_dont_command(cmd);
break;
default:
LOG_DBG("Operation %u not handled", cmd->op);
break;
@ -250,8 +293,6 @@ static void telnet_accept(struct net_context *client,
int error,
void *user_data)
{
int ret;
if (error) {
LOG_ERR("Error %d", error);
goto error;
@ -275,13 +316,10 @@ static void telnet_accept(struct net_context *client,
sh_telnet->client_ctx = client;
/* Disable echo - if command handling is enabled we reply that we don't
/* Disable echo - if command handling is enabled we reply that we
* support echo.
*/
ret = shell_echo_set(sh_telnet->shell_context, false);
if (ret < 0) {
LOG_ERR("Failed to disable echo, err: %d", ret);
}
(void)telnet_echo_set(sh_telnet->shell_context, false);
return;
error: