[PATCH 2/2] tty: Add handler for local tty mirroring
Joel Stanley
joel at jms.id.au
Thu Apr 28 17:21:36 AEST 2016
On Thu, Apr 28, 2016 at 2:49 PM, Jeremy Kerr <jk at ozlabs.org> wrote:
> This change adds a simple handler for mirroring data to local tty
> device, like a hardware UART.
>
> This is specified through a new config parameter 'local-tty'.
>
> Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
Reviewed-by: Joel Stanley <joel at jms.id.au>
> ---
> Makefile.am | 1 +
> obmc-console.conf.sample | 3 ++
> tty-handler.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 127 insertions(+)
> create mode 100644 tty-handler.c
>
> diff --git a/Makefile.am b/Makefile.am
> index 5f0a1bb..2df24d8 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -34,6 +34,7 @@ obmc_console_server_SOURCES = \
> config.c \
> log-handler.c \
> socket-handler.c \
> + tty-handler.c \
> console-socket.c
>
> obmc_console_client_SOURCES = \
> diff --git a/obmc-console.conf.sample b/obmc-console.conf.sample
> index a5b8808..d473af2 100644
> --- a/obmc-console.conf.sample
> +++ b/obmc-console.conf.sample
> @@ -4,3 +4,6 @@ device = ttyUSB0
> # For VUART devices, we can specify the LPC address and SIRQ parameters
> lpc-address = 0x3f8
> sirq = 4
> +
> +# To mirror to a local tty device (typically a hardware UART), set local-tty
> +# local-tty = ttyS0
> diff --git a/tty-handler.c b/tty-handler.c
> new file mode 100644
> index 0000000..00ada7a
> --- /dev/null
> +++ b/tty-handler.c
> @@ -0,0 +1,123 @@
> +/**
> + * Copyright © 2016 IBM Corporation
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <assert.h>
> +#include <err.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +
> +#include "console-server.h"
> +
> +struct tty_handler {
> + struct handler handler;
> + struct console *console;
> + struct poller *poller;
> + int fd;
> +};
> +
> +static struct tty_handler *to_tty_handler(struct handler *handler)
> +{
> + return container_of(handler, struct tty_handler, handler);
> +}
> +
> +static enum poller_ret tty_poll(struct handler *handler,
> + int events, void __attribute__((unused)) *data)
> +{
> + struct tty_handler *th = to_tty_handler(handler);
> + uint8_t buf[4096];
> + ssize_t len;
> +
> + if (!(events & POLLIN))
> + return POLLER_OK;
> +
> + len = read(th->fd, buf, sizeof(buf));
> + if (len <= 0) {
> + th->poller = NULL;
> + close(th->fd);
> + return POLLER_REMOVE;
> + }
> +
> + console_data_out(th->console, buf, len);
> +
> + return POLLER_OK;
> +}
> +
> +static int tty_init(struct handler *handler, struct console *console,
> + struct config *config __attribute__((unused)))
> +{
> + struct tty_handler *th = to_tty_handler(handler);
> + const char *tty_name;
> + char *tty_path;
> + int rc, flags;
> +
> + tty_name = config_get_value(config, "local-tty");
> + if (!tty_name)
> + return -1;
> +
> + rc = asprintf(&tty_path, "/dev/%s", tty_name);
> + if (!rc)
> + return -1;
> +
> + th->fd = open(tty_path, O_RDWR);
> + if (th->fd < 0) {
> + warn("Can't open %s; disabling local tty", tty_name);
> + free(tty_path);
> + return -1;
> + }
> +
> + free(tty_path);
> +
> + /* initial tty setup */
> + flags = fcntl(th->fd, F_GETFL, 0);
> + flags |= FNDELAY;
> + fcntl(th->fd, F_SETFL, flags);
> +
> + th->poller = console_register_poller(console, handler, tty_poll,
> + th->fd, POLLIN, NULL);
> + th->console = console;
> +
> + return 0;
> +}
> +
> +static int tty_data(struct handler *handler, uint8_t *buf, size_t len)
> +{
> + struct tty_handler *th = to_tty_handler(handler);
> + return write_buf_to_fd(th->fd, buf, len);
> +}
> +
> +static void tty_fini(struct handler *handler)
> +{
> + struct tty_handler *th = to_tty_handler(handler);
> + if (th->poller)
> + console_unregister_poller(th->console, th->poller);
> + close(th->fd);
> +}
> +
> +static struct tty_handler tty_handler = {
> + .handler = {
> + .name = "tty",
> + .init = tty_init,
> + .data_in = tty_data,
> + .fini = tty_fini,
> + },
> +};
> +
> +console_register_handler(&tty_handler.handler);
> +
> --
> 2.5.0
>
> _______________________________________________
> openbmc mailing list
> openbmc at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/openbmc
More information about the openbmc
mailing list