/*
 * Copyright (C) MOXA Inc. All rights reserved.
 * Authors:
 *     2024  Wilson YS Huang  <wilsonys.huang@moxa.com>
 * This software is distributed under the terms of the MOXA SOFTWARE NOTICE.
 * See the file LICENSE for details.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include <logger.h>

static int32_t set_tty(int32_t fd)
{
    struct termios termio = {0};
    int32_t        rc     = -1;

    errno = 0;
    rc    = tcgetattr(fd, &termio);
    if (rc < 0) {
        log_error("Get tty attr failed: %s", strerror(errno));
        return rc;
    }

    termio.c_iflag = IGNBRK;
    termio.c_oflag = 0;
    termio.c_lflag = 0;
    termio.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
    termio.c_cflag &= ~CRTSCTS;
    termio.c_iflag &= ~(IXON | IXOFF | IXANY);

    termio.c_cc[VMIN]  = 1;
    termio.c_cc[VTIME] = 5;
    termio.c_cflag &= ~(PARENB | PARODD);
    termio.c_cflag &= ~CSTOPB;

    errno = 0;
    rc    = tcsetattr(fd, TCSANOW, &termio);
    if (rc < 0) {
        log_error("Set tty attr failed: %s", strerror(errno));
        return rc;
    }

    errno = 0;
    rc    = tcflush(fd, TCIOFLUSH);
    if (rc < 0) {
        log_error("Flush tty failed: %s", strerror(errno));
        return rc;
    }

    return rc;
}

int32_t open_tty(const char *tty_name)
{
    int32_t fd = 0;

    errno = 0;
    fd    = open(tty_name, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd < 0) {
        log_error("Open tty failed: %s", strerror(errno));
        return -1;
    }

    if (set_tty(fd) < 0) {
        log_error("Set tty failed");
        close(fd);
        return -1;
    }

    return fd;
}