summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Bursztyka <tomasz.bursztyka@linux.intel.com>2017-01-24 14:59:11 +0100
committerJukka Rissanen <jukka.rissanen@linux.intel.com>2017-01-27 12:35:53 +0200
commit1d9402b3e334255e9ede0b323b4de3cd37fef82d (patch)
treea37379749774086e5d577c23d4f901d528d181f2
parent587335c6cfb05e5c5104051e21d98f1ffcbfdafe (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.c63
-rw-r--r--include/drivers/console/telnet_console.h37
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__ */