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

#define SERIAL_PORT "/dev/ttyUSB1"  
#define BAUDRATE B115200            

// 初始化串口
int init_serial(int fd) {
    struct termios tty;
    memset(&tty, 0, sizeof(tty));

    if (tcgetattr(fd, &tty) != 0) {
        perror("tcgetattr");
        return -1;
    }

    // 设置波特率
    cfsetospeed(&tty, BAUDRATE);
    cfsetispeed(&tty, BAUDRATE);

    // 8N1模式（8数据位，无校验，1停止位）
    tty.c_cflag &= ~PARENB;
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;

    // 禁用流控
    tty.c_cflag &= ~CRTSCTS;
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);

    // 原始模式（禁用规范输入和回显）
    tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    tty.c_oflag &= ~OPOST;

    // 超时设置：5S超时，最少读取1字节
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 5;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        perror("tcsetattr");
        return -1;
    }

    return 0;
}

// 发送AT指令并读取响应
int send_at_command(int fd, const char *cmd, char *resp, size_t resp_len) {
    char buf[256];
    ssize_t n;

    // 清空缓冲区
    tcflush(fd, TCIOFLUSH);

    // 发送指令
    printf("Sending: %s\n", cmd);
    write(fd, cmd, strlen(cmd));
    write(fd, "\r\n", 2);

    // 读取结果
    memset(resp, 0, resp_len);
    n = read(fd, resp, resp_len - 1);
    if (n < 0) {
        perror("read");
        return -1;
    }

    printf("Response: %s\n", resp);
    return 0;
}

char *get_modem_signal()
{
    int fd;
    static char signal[512];
    memset(signal, 0, sizeof(signal));
    // 打开串口设备
    fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    } 
    if (init_serial(fd) != 0) {
        close(fd);
        exit(EXIT_FAILURE);

    }
    if (send_at_command(fd, "AT+CSQ", signal, sizeof(signal)) == 0) {
        printf("Signal Strength: %s\n", signal);

    }
    return signal;
}

char *get_modem_iccid()
{
    int fd;
    static char iccid[512];
    memset(iccid, 0, sizeof(iccid));
    fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    } 
    if (init_serial(fd) != 0) {
        close(fd);
        exit(EXIT_FAILURE);

    }
    if (send_at_command(fd, "AT+QCCID", iccid, sizeof(iccid)) == 0) {
        printf("ICCID: %s\n", iccid);

    }
    return iccid;
}

char *get_modem_imei()
{
    int fd;
    static char imei[512];
    memset(imei, 0, sizeof(imei));
    fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    } 
    if (init_serial(fd) != 0) {
        close(fd);
    }
        if (send_at_command(fd, "AT+GSN", imei, sizeof(imei)) == 0) {
        printf("imei: %s\n", imei);

    }
    return imei;
}
