/* tty3.c - send Close to reset MCU link state, then test handshake */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>

static uint8_t calc_cs(const uint8_t* d, int len) {
    int s = 0; for (int i = 0; i < len; i++) s += d[i]; return (~s) & 0xFF;
}

static void send_frame(int fd, uint8_t ft, uint8_t seq) {
    uint8_t f[7] = {0xFF,0xAA,0x00,0x07,seq,ft,0x00};
    f[6] = calc_cs(f+2, 4);
    write(fd, f, 7); tcdrain(fd);
}

int main() {
    int fd = open("/dev/ttyS7", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd < 0) return 1;
    fcntl(fd, F_SETFL, 0);
    struct termios t; tcgetattr(fd, &t);
    cfsetospeed(&t, B460800); cfsetispeed(&t, B460800);
    t.c_cflag |= CLOCAL|CREAD; t.c_cflag &= ~(PARENB|CSTOPB|CSIZE); t.c_cflag |= CS8;
    t.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG); t.c_oflag &= ~OPOST;
    t.c_iflag &= ~(IXON|IXOFF|IXANY|ICRNL); tcsetattr(fd, TCSANOW, &t);

    /* Step 1: Send Close to reset link */
    send_frame(fd, 0x04, 0x01);
    usleep(200000);
    printf("[CLOSE] Sent\n");

    /* Step 2: Listen for MCU broadcasts */
    uint8_t buf[4096]; int pos = 0;
    uint64_t t0; struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    t0 = ts.tv_sec*1000ULL+ts.tv_nsec/1000000ULL;
    while ((ts.tv_sec*1000ULL+ts.tv_nsec/1000000ULL)-t0 < 2000) {
        fd_set rfds; FD_ZERO(&rfds); FD_SET(fd, &rfds);
        struct timeval tv = {0, 200000};
        if (select(fd+1, &rfds, NULL, NULL, &tv) > 0) {
            int n = read(fd, buf+pos, sizeof(buf)-pos);
            if (n > 0) { pos += n; printf("[RX] "); for (int j = 0; j < n; j++) printf("%02X ", buf[j]); printf("\n"); }
        }
        clock_gettime(CLOCK_MONOTONIC, &ts);
    }
    printf("[DONE] %d bytes received\n", pos);
    close(fd);
    return pos > 0 ? 0 : 1;
}
