#include "hostMcuDataParse.h"
#include "hostMcuComm.h"


static void stateMachine(void);

/* 状态机函数 */
static uint8_t analysisWait(void);
static uint8_t analysisStartFlagSL(void);
static uint8_t analysisPortSL(void);
static uint8_t analysisLengthSL(void);
static uint8_t analysisEndFlagSL(void);

/**
  * @brief  状态机函数
  * @param 
  * @retval 
  */
void stateMachine(void)
{
    if (state == wait) {
        if (analysisWait() == TRUE) {
            su806UartRxTime = xTaskGetTickCount();
        }
    }

    else if (state == startFlagSL) {
        analysisStartFlagSL();
    }

    else if (state == portSL) {
        analysisPortSL();
    }

    else if (state == lengthSL) {
        analysisLengthSL();
    }

    else if (state == endFlagSL) {
        analysisEndFlagSL();
    }
}

/**
  * @brief  状态 wait
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define waitMaxLen 2
uint8_t analysisWait(void)
{
    if (su806RxBufferIndex >= 2) {
        /* 透传数据帧包头 */
        if (su806RxBuffer[0] == 'S' && su806RxBuffer[1] == 'L') {
            // log_info("startFlagSL\n");
            state = startFlagSL;
            return TRUE;
        }
    }

    if (su806RxBufferIndex < waitMaxLen) {
        return FALSE;
    }

    state = wait;
    su806RxBufferIndex--;
    memcpy(su806RxBuffer, su806RxBuffer + 1, su806RxBufferIndex);

    return FALSE;
}

/**
  * @brief  状态 startFlagSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisStartFlagSL(void)
{
    /* 校验端口号 */
    if (su806RxBuffer[2] < 13) {
        // log_info("portSL\n");
        state = portSL;
        return TRUE;
    }

    // log_error("portSL %d \n", gw485RxBuffer[2]);
    state = wait;
    su806RxBufferIndex--;
    memcpy(su806RxBuffer, su806RxBuffer + 1, su806RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 portSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define PortSLMaxLen 5
uint8_t analysisPortSL(void)
{
    /* 解析数据包的度 */
    if (su806RxBufferIndex >= PortSLMaxLen) {
        uint32_t tempLen = 0;
        tempLen = (su806RxBuffer[3] << 8) | su806RxBuffer[4];

        if (tempLen <= 1024) {
            // log_info("lengthSL\n");
            state = lengthSL;
            frameLength = 6 + tempLen;
            return TRUE;
        }
    }

    if (su806RxBufferIndex < PortSLMaxLen) {
        return FALSE;
    }
    
    // log_error("lengthSL %d \n", (gw485RxBuffer[3] << 8) | gw485RxBuffer[4]);

    state = wait;
    su806RxBufferIndex--;
    memcpy(su806RxBuffer, su806RxBuffer + 1, su806RxBufferIndex);
    return FALSE;
}

/**
  * @brief  状态 lengthSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
#define LengthSLMaxLen frameLength
uint8_t analysisLengthSL(void)
{
    /* 解析帧尾 */
    if (su806RxBufferIndex >= LengthSLMaxLen) {
        if (su806RxBuffer[LengthSLMaxLen - 1] == 0x17) {
            // log_info("endFlagSL\n");
            state = endFlagSL;
            return TRUE;
        }
    }

    if (su806RxBufferIndex < LengthSLMaxLen) {
        return FALSE;
    }
    // log_info("endFlagSL %d\n", gw485RxBuffer[LengthSLMaxLen - 1]);

    state = wait;
    su806RxBufferIndex--;
    memcpy(su806RxBuffer, su806RxBuffer + 1, su806RxBufferIndex);
    return FALSE;
}


/**
  * @brief  状态 endFlagSL
  * @param
  * @retval 0:解析失败
            1:解析成功
  */
uint8_t analysisEndFlagSL(void)
{
    uint32_t tempLen = 0;
    tempLen = (su806RxBuffer[3] << 8) | su806RxBuffer[4];

    if (su806RxBuffer[2] == HostMcu) {
        hostFrameDataAnalyze(su806RxBuffer, su806RxBufferIndex);
        su806RxBufferIndex = 0;
        state = wait;
        return 1;
    }

    //系统内存不足,丢去当前包
    if (xPortGetFreeHeapSize() < tempLen + 1024) {
        goto err;
    }
    uint8_t *Buff;

    /* 对于从mcu处理的数据,原封不动的发送到从mcu上 */
    if (su806RxBuffer[2] == J1
            || su806RxBuffer[2] == J3
            || su806RxBuffer[2] == J5
            || su806RxBuffer[2] == J7
            || su806RxBuffer[2] == J8
            || su806RxBuffer[2] == J9
            || su806RxBuffer[2] == SlaveMcu) {

        Buff = (uint8_t *)pvPortMalloc(tempLen + hostQueueUartSendInfoSize + 6);
        hostQueueUartSendInfo *sendBuff = (hostQueueUartSendInfo *)Buff;
        sendBuff->length = tempLen + 6;
        sendBuff->data = Buff + hostQueueUartSendInfoSize;
        memcpy((char *)sendBuff->data, (char *)su806RxBuffer, tempLen + 6);

        if (uxQueueSpacesAvailable(hostMcu_uart_Queue)) {
            xQueueSend(hostMcu_uart_Queue, &Buff, 10);
        }
        /* 队列中无空间,释放内存,退出 */
        else {
            vPortFree(Buff);
        }
    }

    Buff = (uint8_t *)pvPortMalloc(tempLen + hostQueueUartSendInfoSize);
    hostQueueUartSendInfo *sendBuff = (hostQueueUartSendInfo *)Buff;
    sendBuff->length = tempLen;
    sendBuff->data = Buff + hostQueueUartSendInfoSize;
    memcpy((char *)sendBuff->data, (char *)&su806RxBuffer[5], tempLen);


    /* 通过不同的端口将数据发送到不同的地方 */
    if (su806RxBuffer[2] == J0) {
        if (uxQueueSpacesAvailable(J0_485_Queue)) {
            xQueueSend(J0_485_Queue, &Buff, 10);
        }
        /* 队列中无空间,释放内存,退出 */
        else {
            vPortFree(Buff);
        }
    }
    else if (su806RxBuffer[2] == J2) {
        if (uxQueueSpacesAvailable(J2_485_Queue)) {
            xQueueSend(J2_485_Queue, &Buff, 10);
        }
        /* 队列中无空间,释放内存,退出 */
        else {
            vPortFree(Buff);
        }
    }    
    else if (su806RxBuffer[2] == J4) {
        if (uxQueueSpacesAvailable(J4_485_Queue)) {
            xQueueSend(J4_485_Queue, &Buff, 10);
        }
        /* 队列中无空间,释放内存,退出 */
        else {
            vPortFree(Buff);
        }
    }    
    else if (su806RxBuffer[2] == J6) {
        if (uxQueueSpacesAvailable(J6_485_Queue)) {
            xQueueSend(J6_485_Queue, &Buff, 10);
        }
        /* 队列中无空间,释放内存,退出 */
        else {
            vPortFree(Buff);
        }
    }
    else if (su806RxBuffer[2] == Lora) {
        if (uxQueueSpacesAvailable(lora_uart_Queue)) {
            xQueueSend(lora_uart_Queue, &Buff, 10);
        }
        /* 队列中无空间,释放内存,退出 */
        else {
            vPortFree(Buff);
        }
    }

err:
    //清零buff
    state = wait;
    su806RxBufferIndex = 0;
    return 1;
}


/**
  * @brief  解析智能模块发送来的数据
  * @param  device 用于接收智能模块发送来的数据的串口设备
  * @retval
  */
void hostMcuUartDataAnalysis(device_handle device)
{
    /* 每次函数最多执行10ms */
    static uint32_t tickstart = 0U;
    tickstart = xTaskGetTickCount();

    /* 2S未解析出来一帧数据,将数据清零 */
    if (getTickDiff(su806UartRxTime) >= tick_2S) {
        su806UartRxTime = xTaskGetTickCount();
        su806RxBufferIndex = 0;
        state = wait;
    }

    while (uart_dev_char_present(device) == 1 && ((xTaskGetTickCount() - tickstart) < 5)) {
        su806RxBuffer[su806RxBufferIndex++] = uart_dev_in_char(device);
        stateMachine();
    }

    if (uart_dev_char_present(device) != 1 && state != wait) {        
        stateMachine();
    }
}