diff options
author | Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> | 2017-01-24 14:59:11 +0100 |
---|---|---|
committer | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2017-01-27 12:35:53 +0200 |
commit | 1d9402b3e334255e9ede0b323b4de3cd37fef82d (patch) | |
tree | a37379749774086e5d577c23d4f901d528d181f2 | |
parent | 587335c6cfb05e5c5104051e21d98f1ffcbfdafe (diff) |
drivers/console/telnet: Provide minimal input handling.
Telnet "Interpret As Command" (IAC) code is ignored.
Change-Id: I882397389d77b8adfcbce62fbd9654c0b0412ae3
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
-rw-r--r-- | drivers/console/telnet_console.c | 63 | ||||
-rw-r--r-- | include/drivers/console/telnet_console.h | 37 |
2 files changed, 100 insertions, 0 deletions
diff --git a/drivers/console/telnet_console.c b/drivers/console/telnet_console.c index d9a06d7a1..8c1840f60 100644 --- a/drivers/console/telnet_console.c +++ b/drivers/console/telnet_console.c @@ -24,6 +24,7 @@ #include <init.h> #include <misc/printk.h> +#include <console/console.h> #include <net/buf.h> #include <net/nbuf.h> #include <net/net_ip.h> @@ -38,6 +39,8 @@ #define TELNET_TIMEOUT K_MSEC(CONFIG_TELNET_CONSOLE_SEND_TIMEOUT) #define TELNET_THRESHOLD CONFIG_TELNET_CONSOLE_SEND_THRESHOLD +#define TELNET_MIN_MSG 2 + /* These 2 structures below are used to store the console output * before sending it to the client. This is done to keep some * reactivity: the ring buffer is non-protected, if first line has @@ -78,6 +81,9 @@ static struct net_context *client_cnx; static struct net_buf *out_buf; static int (*orig_printk_hook)(int); +static struct k_fifo *avail_queue; +static struct k_fifo *input_queue; + extern void __printk_hook_install(int (*fn)(int)); extern void *__printk_get_hook(void); @@ -236,6 +242,52 @@ static inline bool telnet_send(void) return true; } +static inline void telnet_handle_input(struct net_buf *buf) +{ + struct console_input *input; + uint16_t len, offset, pos; + uint8_t *l_start; + + len = net_nbuf_appdatalen(buf); + if (len > CONSOLE_MAX_LINE_LEN || len < TELNET_MIN_MSG) { + return; + } + + /* Telnet commands are ignored for now + * These are recognized by matching the IAC byte + * (IAC: Intepret As Command) which value is 255 + */ + l_start = net_nbuf_appdata(buf); + if (*l_start == 255) { + return; + } + + if (!avail_queue || !input_queue) { + return; + } + + input = k_fifo_get(avail_queue, K_NO_WAIT); + if (!input) { + return; + } + + offset = net_buf_frags_len(buf) - len; + net_nbuf_read(buf->frags, offset, &pos, len, input->line); + + /* LF/CR will be removed if only the line is not NUL terminated */ + if (input->line[len-1] != '\0') { + if (input->line[len-1] == '\n') { + input->line[len-1] = '\0'; + } + + if (input->line[len-2] == '\r') { + input->line[len-2] = '\0'; + } + } + + k_fifo_put(input_queue, input); +} + static void telnet_recv(struct net_context *client, struct net_buf *buf, int status, @@ -250,6 +302,8 @@ static void telnet_recv(struct net_context *client, return; } + telnet_handle_input(buf); + net_buf_unref(buf); } @@ -343,6 +397,15 @@ error: } } +void telnet_register_input(struct k_fifo *avail, struct k_fifo *lines, + uint8_t (*completion)(char *str, uint8_t len)) +{ + ARG_UNUSED(completion); + + avail_queue = avail; + input_queue = lines; +} + static int telnet_console_init(struct device *arg) { #ifdef CONFIG_NET_IPV4 diff --git a/include/drivers/console/telnet_console.h b/include/drivers/console/telnet_console.h new file mode 100644 index 000000000..fe983dcf4 --- /dev/null +++ b/include/drivers/console/telnet_console.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __TELNET_CONSOLE_H__ +#define __TELNET_CONSOLE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <kernel.h> + +/** @brief Register telnet input processing + * + * Input processing is started when string is received in telnet server. + * Carriage return is translated to NULL making string always NULL + * terminated. Application before calling register function need to + * initialize two fifo queues mentioned below. + * + * @param avail k_fifo queue keeping available input slots + * @param lines k_fifo queue of entered lines which to be processed + * in the application code. + * @param completion callback for tab completion of entered commands + * + * @return N/A + */ +void telnet_register_input(struct k_fifo *avail, struct k_fifo *lines, + uint8_t (*completion)(char *str, uint8_t len)); + +#ifdef __cplusplus +} +#endif + +#endif /* __TELNET_CONSOLE_H__ */ |