Commit 35124ca4 authored by Adam Wujek's avatar Adam Wujek 💬

lib: implement netconsole (via uart_read_byte)

Mirror serial console to netconsole.
To use netconsole executre the following command on a host connected to wrpc:
nc -u <IP> 55

Send of a command is triggered by a newline.
To see output in the netconsole any command (even empty line) has to be sent
first.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent cea444a3
...@@ -379,6 +379,13 @@ config CMD_LEAPSEC ...@@ -379,6 +379,13 @@ config CMD_LEAPSEC
This enables leapsec command, which can be used to adjust leap seconds This enables leapsec command, which can be used to adjust leap seconds
value. value.
config NETCONSOLE
depends on WR_NODE && IP && !NET_VERBOSE
boolean "Include netconsole via UDP"
default y
help
Include netconsole to be run via UDP
# #
# This is a set of configuration options that should not be changed by # This is a set of configuration options that should not be changed by
# normal users. If the "developer" menu is used, the binary is tainted. # normal users. If the "developer" menu is used, the binary is tainted.
......
...@@ -18,6 +18,16 @@ ...@@ -18,6 +18,16 @@
( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \ ( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \
(CPU_CLOCK >> 8)) / (CPU_CLOCK >> 7) ) (CPU_CLOCK >> 8)) / (CPU_CLOCK >> 7) )
#ifdef CONFIG_NETCONSOLE
#define HAS_NETCONSOLE 1
int netconsole_read_byte(void);
int netconsole_write_string(const char *);
#else
#define HAS_NETCONSOLE 0
static int netconsole_read_byte(void) {return -1;}
static int netconsole_write_string(const char *s) {return -1;}
#endif
static inline uint32_t suart_calc_baud( int baudrate ) static inline uint32_t suart_calc_baud( int baudrate )
{ {
uint64_t n = (((uint64_t) (baudrate)) << 12 ) + (CPU_CLOCK >> 8); uint64_t n = (((uint64_t) (baudrate)) << 12 ) + (CPU_CLOCK >> 8);
...@@ -48,6 +58,9 @@ void suart_write_byte(struct simple_uart_device *dev, int b) ...@@ -48,6 +58,9 @@ void suart_write_byte(struct simple_uart_device *dev, int b)
int suart_write_string(struct simple_uart_device *dev, const char *s) int suart_write_string(struct simple_uart_device *dev, const char *s)
{ {
const char *t = s; const char *t = s;
if (HAS_NETCONSOLE)
netconsole_write_string(s);
while (*s) while (*s)
suart_write_byte(dev, *(s++)); suart_write_byte(dev, *(s++));
return s - t; return s - t;
...@@ -72,6 +85,12 @@ int suart_poll(struct simple_uart_device *dev) ...@@ -72,6 +85,12 @@ int suart_poll(struct simple_uart_device *dev)
int suart_read_byte(struct simple_uart_device *dev) int suart_read_byte(struct simple_uart_device *dev)
{ {
int ret;
/* check if there is anything from netconsole first */
if (HAS_NETCONSOLE && (ret = netconsole_read_byte()) >= 0)
return ret;
if (!suart_poll(dev)) if (!suart_poll(dev))
return -1; return -1;
......
/*
* This work is part of the White Rabbit project
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __NETCONSOLE_H__
#define __NETCONSOLE_H__
void netconsole_init(void);
int netconsole_poll(void);
int netconsole_read_byte(void);
int netconsole_write_string(const char *s);
#endif /* __NETCONSOLE_H__ */
...@@ -13,6 +13,7 @@ obj-$(CONFIG_SYSLOG) += lib/syslog.o ...@@ -13,6 +13,7 @@ obj-$(CONFIG_SYSLOG) += lib/syslog.o
obj-$(CONFIG_LATENCY_PROBE) += lib/latency.o obj-$(CONFIG_LATENCY_PROBE) += lib/latency.o
obj-$(CONFIG_SNMP) += lib/snmp.o obj-$(CONFIG_SNMP) += lib/snmp.o
obj-$(CONFIG_LLDP) += lib/lldp.o obj-$(CONFIG_LLDP) += lib/lldp.o
obj-$(CONFIG_NETCONSOLE) += lib/netconsole.o
# below requires $(AUTOCONF_PPSI) to be present before build # below requires $(AUTOCONF_PPSI) to be present before build
REQUIRE_AUTOCONF_PPSI += \ REQUIRE_AUTOCONF_PPSI += \
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2018 CERN (www.cern.ch)
* Author: Adam Wujek <adam.wujek@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
//#include <wrpc.h>
#include <string.h>
#include "ipv4.h"
#include "ptpd_netif.h"
#include "shell.h"
#include "netconsole.h"
static uint8_t __netconsole_queue[128];
static struct wrpc_socket __static_netconsole_socket = {
.queue.buff = __netconsole_queue,
.queue.size = sizeof(__netconsole_queue),
};
static struct wrpc_socket *netconsole_socket;
static unsigned char *cmd_rx_p = NULL;
/* net headers + cmd len */
static uint8_t tx_buf[UDP_END + SH_MAX_LINE_LEN + 1];
static uint8_t rx_buf[UDP_END + SH_MAX_LINE_LEN + 1];
struct wr_sockaddr netconsole_sock_addr;
static int netconsole_has_peer = 0;
struct wr_udp_addr netconsole_udp_addr;
void netconsole_init(void)
{
netconsole_socket = ptpd_netif_create_socket(
&__static_netconsole_socket, NULL,
PTPD_SOCK_UDP, 55);
/* TODO: find a better port number */
}
int netconsole_read_byte(void)
{
if (cmd_rx_p && *cmd_rx_p != 0)
return *(cmd_rx_p++);
return -1;
}
int netconsole_write_string(const char *s)
{
int len;
if (!netconsole_has_peer)
return 0;
/* Prevent recursive calls when net verbose configured.
* NOTE: Even with the following if, NET_IS_VERBOSE does not work
* with netconsole */
if (NET_IS_VERBOSE)
netconsole_has_peer = 0;
strncpy((char *) &tx_buf[UDP_END], s, SH_MAX_LINE_LEN);
len = min(strlen(s), SH_MAX_LINE_LEN);
len += UDP_END;
fill_udp((uint8_t *)tx_buf, len, &netconsole_udp_addr);
ptpd_netif_sendto(netconsole_socket,
&netconsole_sock_addr, tx_buf, len, 0);
if (NET_IS_VERBOSE)
netconsole_has_peer = 1;
return 0;
}
int netconsole_poll(void)
{
int len;
if (ip_status == IP_TRAINING)
return 0; /* can't do netconsole w/o an address... */
if ((len = ptpd_netif_recvfrom(netconsole_socket,
&netconsole_sock_addr, rx_buf,
sizeof(rx_buf), NULL)
) > 0) {
if (check_dest_ip(rx_buf)) {
/* wrong destination IP */
return 0;
}
rx_buf[len] = 0;
/* copy source and destination address */
memcpy(&netconsole_udp_addr.daddr, rx_buf + IP_SOURCE, 4);
memcpy(&netconsole_udp_addr.saddr, rx_buf + IP_DEST, 4);
memcpy(&netconsole_udp_addr.dport, rx_buf + UDP_SPORT, 2);
memcpy(&netconsole_udp_addr.sport, rx_buf + UDP_DPORT, 2);
cmd_rx_p = &rx_buf[UDP_END];
netconsole_has_peer = 1;
return 1;
}
return 0;
}
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <dev/rxts_calibrator.h> #include <dev/rxts_calibrator.h>
#include <dev/flash.h> #include <dev/flash.h>
#include <dev/gpio.h> #include <dev/gpio.h>
#include <netconsole.h>
#include <wrc_ptp.h> #include <wrc_ptp.h>
#include <system_checks.h> #include <system_checks.h>
...@@ -320,6 +321,11 @@ static void create_tasks(void) ...@@ -320,6 +321,11 @@ static void create_tasks(void)
#ifdef CONFIG_WR_DIAG #ifdef CONFIG_WR_DIAG
wrc_task_create( "diags", NULL, wrc_wr_diags ); wrc_task_create( "diags", NULL, wrc_wr_diags );
#endif #endif
#ifdef CONFIG_NETCONSOLE
t = wrc_task_create( "netconsole", netconsole_init, netconsole_poll );
wrc_task_set_enable( t, is_link_up );
#endif
} }
int main(void) __attribute__ ((weak)); int main(void) __attribute__ ((weak));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment