/*
 * usart_biz.c
 *
 *  Created on: 2026-02-26
 *      Author: wangfq
 *  Updated:   2026-07-02 — 使用 loop_uart_proto 帧解析器替代 timeout heuristic
 */

#include "config.h"
#include "cmcng.h"
#include "loop_uart_proto.h"
#include <string.h>
#include "dbn_ble_srv.h"

void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));


void uart_init(void){
    GPIO_InitTypeDef  GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure  = {0};

    // usart1 : peripheral / DEBUG


    //usart2 :loop mcu
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // Tx
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   // Rx
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate            = 192000;  // Loop MCU 实际波特率
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Tx | USART_Mode_Rx;

    USART_Init(USART2, &USART_InitStructure);
    // USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel                   = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    USART_Cmd(USART2, ENABLE);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 初始化帧解析器
    lup_frame_reset();

}



/*********************************************************************
 * @fn      USART1_IRQHandler
 *
 * @brief   This function handles USART1 global interrupt request.
 *
 * @return  none
 */
void USART1_IRQHandler(void)
{

}


/*********************************************************************
 * @fn      USART2_IRQHandler
 *
 * @brief   USART2 RX — 使用 lup_feed_byte() 帧解析器
 *          当解析出完整帧时，复制到 g_pkg_uart_2.pkg 并设置 flag
 *
 * @return  none
 */
void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        uint8_t _dat = USART_ReceiveData(USART2);

        // 喂给帧解析器
        if (lup_feed_byte(_dat)) {
            // 帧接收完成，复制到 g_pkg_uart_2
            const uint8_t *frame = lup_frame_data();
            uint16_t frame_len = lup_frame_len();
            if (frame_len <= BUFF_STACK_SIZE) {
                memcpy(g_pkg_uart_2.pkg, frame, frame_len);
                g_pkg_uart_2.offset = frame_len;
                g_pkg_uart_2.flag   = 1;
                g_pkg_uart_2.tick   = 0;
            }
            lup_frame_reset();
        } else if (g_lup_parser.state != LUP_FRAME_STATE_IDLE) {
            // 正在接收帧中，tick 归零
            g_pkg_uart_2.tick = 0;
        }
    }
}


void UART2_SendString(uint8_t *buf, uint16_t len)
{
    uint16_t _len = len;
    while(_len){
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
        USART_SendData(USART2, *buf++);
        _len--;
    }
    while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}

void UART1_SendString(uint8_t *buf, uint16_t len)
{
    uint16_t _len = len;
    while(_len){
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
        USART_SendData(USART1, *buf++);
        _len--;
    }
}


/*
 * uart_srv — 主循环中调用，处理已接收完整的 UART2 帧
 *
 * 处理流程:
 *  1. 0x7F + 0xC0/0x0C → 传感器数据上报
 *     - 若无 BLE 连接 → 标记 `_report_flag`，在 TCP JSON 中处理
 *     - 若有 BLE 连接且 acs_enable → 转 0x8F 前缀发给 BLE
 *  2. 0x7F + 其他 CMD → 响应帧，交给 lup_process_frame() 匹配挂起命令
 *  3. 非 0x7F → 调试打印（可能是字符串等）
 */
void uart_srv(void)
{
    uint8_t i;
    uint8_t _report_flag = 0;

    // 检查命令超时
    lup_cmd_check_timeout();

    if(g_pkg_uart_2.flag){

        if(g_flag_counter_ota.flag == 0){
            if(g_pkg_uart_2.pkg[0] == 0x7F){
                uint8_t cmd = g_pkg_uart_2.pkg[3];

                // --- 所有 0x7F 帧先经过 lup_process_frame 校验 ---
                // 0xC0: 校验后通过回调直接推送 TCP JSON
                // 其他: 校验后匹配挂起命令
                lup_process_frame(g_pkg_uart_2.pkg, g_pkg_uart_2.offset);

                // --- 传感器上报 (0xC0) 分流 ---
                // 回调已处理 TCP 推送，此处仅处理 BLE 转发
                if(cmd == LUP_CMD_SENSOR_REPORT)
                {
                    if(g_dbn_ble_state_acs_enable.flag != 0){
                        // BLE ACS 已连接 → 改 Magic 为 0x8F 发给 BLE
                        g_pkg_uart_2.pkg[0] = 0x8F;
                        _report_flag = 1;  // 保留给 BLE
                    }
                    // else: 回调已推送 TCP，直接清理
                }

                // 调试打印
                for(i = 0; i < g_pkg_uart_2.offset; i++){
                    PRINT(" %02X", g_pkg_uart_2.pkg[i]);
                }
                PRINT("\n");

                if(_report_flag){
                    // 传感器帧保留在 pkg 中供上层 (tcp_json_srv) 处理
                    // 不 InitPkgUart — 由 tcp_json_push_sensor 消费后清理
                }
            }
            else {
                // 非 0x7F 魔法字节
                PRINT("Rcv_len:%d,dat: %s\n", g_pkg_uart_2.offset, g_pkg_uart_2.pkg);
            }
        }
        else{
            // OTA 模式 — 忽略 Loop MCU 数据
        }


        if(g_flag_bt_state){
            g_flag_notify_temp = set_response_tran_to_notify(g_pkg_uart_2.pkg, g_pkg_uart_2.offset, &g_notify_buftemp);
        }
        else{
            g_dbn_ble_state_acs_enable.flag = 0;
        }

        // 只有非 _report_flag 时才立即清空
        // _report_flag 的帧由 tcp_json_push_sensor 消费后清理
        if (!_report_flag) {
            InitPkgUart(&g_pkg_uart_2);
        }
    }
}
