/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-05-06     lijian       the first version
 */
#include <LTE.h>

#define AT_UART_NAME       "uart3"

LTE_t LTE;

static rt_device_t AT_serial; /* 串口设备句柄 */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */

/* 串口接收消息结构*/
struct rx_msg
{
    rt_device_t dev;
    rt_size_t size;
};

/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;

rt_uint8_t rx_length;
rt_uint8_t check_flag;
rt_err_t result;
static char line_buffer[60];

void set_check_flag(rt_uint8_t flag){
    check_flag = flag;
}

//AT指令发送
void AT_send(const char * cmd)
{
    rt_device_write(AT_serial, 0, cmd, rt_strlen(cmd));
}

/* 接收数据回调函数 */
static rt_err_t uart_callback(rt_device_t dev, rt_size_t size)
{
    struct rx_msg msg;
    rt_err_t result;
    msg.dev = dev;
    msg.size = size;

    //rt_kprintf("in uart_callback\n");

    result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
    if (result == -RT_EFULL)
    {
        /* 消息队列满 */
        rt_kprintf("message queue full！\n");
    }
    return result;
}


//接收数据线程
static void rx_serial_thread_entry(void *parameter)
{
    struct rx_msg msg;
    static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];
    rt_uint8_t line_pos = 0;

    while (1)
    {
        rt_memset(&msg, 0, sizeof(msg));
        /* 从消息队列中读取消息*/
        result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
        if (result > 0)
        {

//            rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
//            rx_buffer[rx_length] = '\0';
//            /* 打印数据 */
//            rt_kprintf("%s\n", rx_buffer);

            rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);

            for (int i = 0; i < rx_length; i++)
            {
                // 如果收到了换行符或回车符，就认为是一行的结束
                if (rx_buffer[i] == '\n' || rx_buffer[i] == '\r')
                {
                    line_buffer[line_pos] = '\0'; // 添加字符串结束符
                    if (line_pos > 0) // 如果这一行至少有一个字符
                    {

                        if (check_flag == 1) //1检测MQTT
                        {
                            //+MQTTSTATU :0 离线   1 已经登陆认证过   2 还没认证，需要发送 MCONNECT
                            char * ch_pos = rt_strstr(line_buffer, "+MQTTSTATU :");
                            // rt_kprintf("ch_pos c: %s\n", ch_pos);
                            if (ch_pos != RT_NULL)
                            {
                                ch_pos = ch_pos + 12;
                                set_MQTT_STATUS((rt_uint8_t) *ch_pos - '0');
                                //break;
                            }
                        }

                        else if (check_flag == 2) //2检测LTE
                        {

                            //判断两个.为有IP，即联网成功
                            char *ch_pos2 = strchr(line_buffer, '.');

                            if (ch_pos2 != NULL) {
                                // 计算点字符的位置
                                rt_uint8_t position = ch_pos2 - line_buffer; // 指针减法得到索引

                                if (line_buffer[position+2] == '.' || line_buffer[position+3] == '.' || line_buffer[position+4] == '.') {
                                    set_LTE_Status(1);
                                }
                            }
                            else
                            {
                                //+CME ERROR:联网失败
                                ch_pos2 = rt_strstr(line_buffer, "+CME ERROR:");
                                if (ch_pos2 != RT_NULL)
                                {
                                    set_LTE_Status(0);
                                }
                            }
                        }

                        if (LTE.log) {
                            rt_kprintf("Received line: %s\n", line_buffer);
                        }

//                        rt_kprintf("Received line: %s , %d\n", line_buffer, line_pos);
                    }
                    line_pos = 0; // 重置行缓冲区位置
                }
                else if (line_pos < sizeof(line_buffer) - 1)
                {
                    // 否则，将字符添加到行缓冲区
                    line_buffer[line_pos++] = rx_buffer[i];
                }
            }

        }
    }
}

//AT串口初始化
rt_uint8_t AT_device_init()
{

//    rt_pin_mode(WAK, PIN_MODE_OUTPUT);
//    // 默认为高电平
//    rt_pin_write(WAK, PIN_HIGH);
//    rt_pin_mode(GPS, PIN_MODE_OUTPUT);
//    // 默认为高电平
//    rt_pin_write(GPS, PIN_LOW);
    rt_pin_mode(RST, PIN_MODE_OUTPUT);
    // 默认为高电平
    rt_pin_write(RST, PIN_HIGH);
    rt_thread_mdelay(200);
    rt_pin_write(RST, PIN_LOW);

    rt_err_t ret = RT_EOK;

    static char msg_pool[256];

    // char str[] = "AT\r\n";

    AT_serial = rt_device_find(AT_UART_NAME);
    if (!AT_serial)
    {
        rt_kprintf("find %s failed!\n", AT_UART_NAME);
        return RT_ERROR;
    }

    config.baud_rate = BAUD_RATE_115200;        //修改波特率为 115200
    config.data_bits = DATA_BITS_8;           //数据位 8
    config.stop_bits = STOP_BITS_1;           //停止位 1
    config.bufsz = 128;                   //修改缓冲区 buff size 为 128
    config.parity = PARITY_NONE;           //无奇偶校验位

    /* 初始化消息队列 */
    rt_mq_init(&rx_mq, "rx_mq", msg_pool, /* 存放消息的缓冲区 */
    sizeof(struct rx_msg), /* 一条消息的最大长度 */
    sizeof(msg_pool), /* 存放消息的缓冲区大小 */
    RT_IPC_FLAG_FIFO); /* 如果有多个线程等待，按照先来先得到的方法分配消息 */

    /* 串口设备控制参数 */
    rt_device_control(AT_serial, RT_DEVICE_CTRL_CONFIG, &config);

    /* 打开串口设备。 DMA 接收及轮询发送模式打开串口设备  RT_DEVICE_FLAG_DMA_RX */
    ret = rt_device_open(AT_serial, RT_DEVICE_FLAG_DMA_RX);
    if (ret != RT_EOK)
    {
        rt_kprintf("open AT_serial fail!\n");
        return RT_ERROR;
    }

    // AT_send("ATE0\r\n");

    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(AT_serial, uart_callback);
    /* 发送字符串 */

    /* 创建 serial 线程 */
    rt_thread_t rx_thread = rt_thread_create("rx_serial", rx_serial_thread_entry, RT_NULL, 1024, 25, 10);
    /* 创建成功则启动线程 */
    if (rx_thread != RT_NULL)
    {
        rt_thread_startup(rx_thread);
    }
    else
    {
        ret = RT_ERROR;
    }

    rt_kprintf("open AT_serial ok!\n");

    return ret;
}

//LTE初始化
rt_uint8_t LTE_init()
{
    AT_send("AT\r\n");
    AT_send("ATE0\r\n");
    rt_thread_mdelay(1000);
//    AT_send("AT+CGMI\r\n"); //模块厂商信息
//    rt_thread_mdelay(500);
//
//    AT_send("AT+CPIN?\r\n"); //查询卡是否插好
//    rt_thread_mdelay(500);
//
//    AT_send("AT+CSQ\r\n");  //信号质量
//    rt_thread_mdelay(500);
//
//    AT_send("AT+CREG?\r\n"); //网络注册状态
//    rt_thread_mdelay(500);
//
//    AT_send("AT+CGATT?\r\n"); //附着GPRS
//    rt_thread_mdelay(500);

    AT_send("AT+CSTT=\"\",\"\",\"\"\r\n"); //自动APN
    rt_thread_mdelay(500);

//    AT_send("AT+CSTT?\r\n");
//    rt_thread_mdelay(500);

    AT_send("AT+CIICR\r\n");    //激活移动场景
    rt_thread_mdelay(500);

    AT_send("AT+CIFSR\r\n"); //查询IP
    rt_thread_mdelay(500);

//    AT_send("ATI\r\n");
//    rt_thread_mdelay(500);

    //AT_send("ATD15612696324;\r\n");

    return RT_EOK;
}

//获取LTE状态
rt_uint8_t get_LTE_status_flag()
{
    set_check_flag(2);
    rt_uint8_t i = 0;
    AT_send("AT+CIFSR\r\n");
    while (!get_LTE_Status())
    {
        rt_thread_mdelay(200);
        if (i > 3)
        {
            break;
        }
        i++;
    }

    if (LTE.log) {
        rt_kprintf("LTE status:%d\n" , get_LTE_Status());
    }


    return get_LTE_Status();
}

void set_LTE_log(rt_uint8_t log){
    LTE.log = log;
}

//LTE重新初始化
void LTE_Re_Init()
{
    rt_pin_write(RST, PIN_HIGH);
    rt_thread_mdelay(500);
    rt_pin_write(RST, PIN_LOW);

    AT_send("AT+CSTT=\"\",\"\",\"\"\r\n"); //自动APN
    rt_thread_mdelay(500);

//    AT_send("AT+CSTT?\r\n");
//    rt_thread_mdelay(500);

    AT_send("AT+CIICR\r\n");    //激活移动场景
    rt_thread_mdelay(500);

    AT_send("AT+CIFSR\r\n"); //查询IP
}

//检测MQTT与LTE联网状态
void check_LTE_MQTT(){
    if (LTE.toggle)
      {
          if (get_LTE_status_flag() != 1)
          {
              LTE.LTE_re++;
          }
          else
          {
              LTE.LTE_re = 0;
          }

          if (LTE.LTE_re == 3)
          {

              LTE_Re_Init();
          }


          LTE.toggle = 0;
      }
      else
      {

          if (get_MQTT_Status_flag() != 1)
          {
              LTE.MQTT_re++;
          }
          else
          {
              LTE.MQTT_re = 0;
          }

          if (LTE.LTE_re == 0 && LTE.MQTT_re == 3)
          {
              MQTT_RE_init();
          }

          LTE.toggle = 1;
      }

}

/**
 * @brief 设置/获取LTE使用键值
 * @param rt_uint8_t key 要设置的Key值
 * @return rt_uint8_t 返回当前的Key值
 */
void set_LTE_Key(rt_uint8_t key)
{
    LTE.Key = key;
}

rt_uint8_t get_LTE_Key()
{
    return LTE.Key;
}

/**
 * @brief 设置/获取LTE状态键值
 * @param rt_uint8_t key 要设置的Key值
 * @return rt_uint8_t 返回当前的Key值
 */
void set_LTE_Status(rt_uint8_t Status_t)
{
    LTE.Status = Status_t;
}

rt_uint8_t get_LTE_Status()
{
    return LTE.Status;
}

rt_uint8_t get_LTE_re()
{
    return LTE.LTE_re;
}

rt_uint8_t get_L_MQTT_re()
{
    return LTE.MQTT_re;
}
