#include "Barcode_Scanner.h"
#include "api_RS485.h"
#include "string.h"
#include "init.h"
#include "Display_Info.h"
#include "R485_Communication_Matrix.h"
#define UART_RX_MAX_DEPTH (1024)    // 4K

typedef struct
{
    uint32_t read_pos;
    uint32_t write_pos;
    uint8_t  Rx_Buffer [ UART_RX_MAX_DEPTH ];
} UARTRxBuf_t;

static UARTRxBuf_t      UARTRxBuf;
static UARTRxBuf_t      UARTRxBuf1;
static uint8_t  mDataBufPtr[1024]   = {0};
static uint32_t mDataBufLen   = 0;
static uint8_t  mDataBufPtr1[1024]   = {0};
static uint32_t mDataBufLen1   = 0;
uint8_t  BarCode[256] = {0};
uint8_t  BarCode1[256] = {0};
uint32_t readNum = 0;
uint32_t readNum1 = 0;

static uint32_t Protocol_UartRead(uint8_t *pData, uint32_t len);//485
static uint32_t Protocol_UartRead1(uint8_t *pData, uint32_t len);//扫码枪
static uint32_t Protocol_UartRead2(uint8_t *pData, uint32_t len);//esp32
uint8_t nowdata[4];
uint8_t lastdata[4];
uint8_t checkresult;
uint8_t sendmsg[8];
uint8_t timenum = 0;
uint8_t firstflag = 0;
uint8_t RS485_data[64];
uint8_t checknumwrong = 3;
uint8_t zhenduanflag = Data_Mode_Dot;
uint8_t clearOdoFlag = 0;
uint8_t connectbleFlag = 0;
uint8_t Auto_ONOFF = 0;
uint32_t key_value;
uint8_t key_array[4];
uint8_t seed_value[4];
uint8_t zhenduansendStep = 0;
uint8_t line_stdio = 2;
uint8_t powerstdio = 0;
uint8_t get_num_buf[34];
uint8_t mimaread[35];
uint8_t comparestart;
uint8_t blename[5];
uint8_t btmac[6];
uint8_t firstpowerflag = 0;
uint16_t lightnumber = 0;
uint8_t writeflag = 0;
void get_key(void)
{
    key_array[0] = seed_value[0] | seed_value[3];
    key_array[1] = (seed_value[1] >> 1) | (seed_value[2] << 1);
    key_array[2] = (seed_value[2] >> 2) | (seed_value[1] << 2);
    key_array[3] = (seed_value[3] >> 3) | (seed_value[0] << 3);
    key_value = ((uint32_t)key_array[0] << 24U);
    key_value = key_value | ((uint32_t)key_array[1] << 16U);
    key_value = key_value | ((uint32_t)key_array[2] << 8U);
    key_value = key_value | (uint32_t)key_array[3];
}
uint8_t recvflag111 = 0;
uint8_t xierucishu = 0;
uint8_t waittimer;
uint8_t saomafinish;
void datacheck(void)
{
    uint16_t checksum = 0;
    uint8_t arraynum = 0;
    if(zhenduanflag == Data_Mode_Dot)
    {
        if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
        {
            for(int i = 0;i<255;i++)
            {
                if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
                {
                    arraynum = i;
                }
            }
            if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
            {
                for(int i = 0;i < (arraynum - 4);i++)
                {
                    RS485_data[i] = BarCode[5+i];       //存数据
                }
                switch (BarCode[2])     //ID
                {
                    case 0xB4:
                    memcpy(R485_IDB4h.Msg,RS485_data,RS485_RX_ID0XB4_DATA_LEN);
                    checksum = Yadi_CAL_Data_Sum(&BarCode[2], 64 + 2);
                    if(checksum != BarCode[68])
                    {
                        ;
                    }
                    case 0x81:      //81接收mac地址
                    {
                        if((BarCode[72] == 0x4A) && (BarCode[71] == 0x4B))
                        {
                            btmac[0] = RS485_data[0];
                            btmac[1] = RS485_data[1];
                            btmac[2] = RS485_data[2];
                            btmac[3] = RS485_data[3];
                            btmac[4] = RS485_data[4];
                            btmac[5] = RS485_data[5];
                            blename[0] = RS485_data[6];
                            blename[1] = RS485_data[7];
                            blename[2] = RS485_data[8];
                            blename[3] = RS485_data[9];
                            blename[4] = 0xff;
                            lightnumber = (RS485_data[11]<<8)+RS485_data[10];
                            writeflag = RS485_data[12];
                        }
                        
                        // General_Number_Disp(blename, 3, 165); 
                    }
                    break;
                    case 0x4F:      //接收诊断信息
                    {
                        switch (BarCode[6])
                        {
                        case 0:
                            LineGetSta.power1 = (BarCode[7]<<8 |BarCode[8]);
                            if(LineGetSta.power1 < 24)
                            {
                                powerstdio = 1;
                            }
                        break;
                        case 1:
                                LineGetSta.ble1 = BarCode[7];
                                if(LineGetSta.ble1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        case 2:
                                LineGetSta.turnleft1 = BarCode[7];
                                if(LineGetSta.turnleft1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        case 3:
                                LineGetSta.turnright1 = BarCode[7];
                                if(LineGetSta.turnright1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        case 4:
                                LineGetSta.ABSlight1 = BarCode[7];
                                if(LineGetSta.ABSlight1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        case 5:
                                LineGetSta.lowlight1 = BarCode[7];
                                if(LineGetSta.lowlight1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        case 6:
                                LineGetSta.highlight1 = BarCode[7];
                                if(LineGetSta.highlight1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        case 7:
                                LineGetSta.weizhilight1 = BarCode[7];
                                if(LineGetSta.weizhilight1 == 1)
                                {
                                    line_stdio = 1;
                                }
                            break;
                        default:
                            break;
                        }
                        break;
                    }
                default:
                    break;
                }
                memset(RS485_data,0,64);
                memset(BarCode,0,sizeof(BarCode));
                RS485_TX_finish = 0;
            }
            else
            {
                // RS485_send_num--;
                RS485_TX_finish = 0;
            }
        }
        else
        {
            // RS485_TX_finish = 0;
        }
    }
    else if(zhenduanflag == Data_Mode_Write)
    {
        if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
        {
            for(int i = 0;i<255;i++)
            {
                if(BarCode[3] == 0x40)
                {
                    if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B && i > 0x40-3)
                    {
                        arraynum = i;
                    }
                }
                else
                {
                    if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
                    {
                        arraynum = i;
                    }
                }
                
            }
            // g_Stage = 1;
            if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
            {
                if(BarCode[2] == 0x81)
                {
                    writeflag = BarCode[17];
                    RS485_TX_finish = 0;
                }
                switch (zhenduansendStep)
                {
                case 0:
                    if(BarCode[2] == 0x14)
                    {
                        if(BarCode[5] == 0x50 && BarCode[6] == 0x3)
                        {
                            zhenduansendStep++;
                            RS485_TX_finish = 0;
                        }
                    }
                    break;
                case 1:
                    if(BarCode[2] == 0x14)
                    {
                        if(BarCode[5] == 0x67 && BarCode[6] == 0x1)
                        {
                            seed_value[0] = BarCode[7];
                            seed_value[1] = BarCode[8];
                            seed_value[2] = BarCode[9];
                            seed_value[3] = BarCode[10];
                            get_key();
                            zhenduansendStep++;
                            RS485_TX_finish = 0;
                        }
                    }
                    break;
                case 2:
                    if(BarCode[2] == 0x14)
                    {
                        if(BarCode[5] == 0x67 && BarCode[6] == 0x2)
                        {
                            zhenduansendStep++;
                            RS485_TX_finish = 0;
                        }
                        else if(BarCode[5] != 0x67)
                        {
                            zhenduansendStep = 0;
                            RS485_TX_finish = 0;
                        }
                        else
                        {
                            ;
                        }
                    }
                    break;
                case 3:
                    if(BarCode[2] == 0x14)
                    {
                        if((BarCode[5] == 0x6E) && (BarCode[6] == 0x50) && (BarCode[7] == 0))
                        {
                            zhenduansendStep++;
                            RS485_TX_finish = 0;
                            saomafinish = 1;
                            waittimer = 0;
                        }
                        if(BarCode[5] == 0x7F && BarCode[6] == 0x2E && BarCode[7] == 0x78 )
                        {
                            if(waittimer >= 2)
                            {
                                zhenduansendStep = 0;
                                waittimer = 0;
                                RS485_TX_finish = 0;
                            }
                            else
                            {
                                waittimer++;
                            }
                        }
                        if(BarCode[5] == 0x7F && BarCode[6] == 0x2E && BarCode[7] == 0x31 )
                        {
                            RS485_TX_finish = 0;
                        }
                    }
                    else
                    {
                        // RS485_TX_finish = 0;
                    }
                    break;
                case 5:
                    if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
                    {
                        if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
                        {
                            if(BarCode[5] == 0x62 && BarCode[6] == 0x50 && BarCode[7] == 0)
                            {
                                memcpy(mimaread,BarCode+8,34 );
                                saomafinish = 2;
                            }
                        }
                    }
                default:
                    break;
                }
                memset(RS485_data,0,64);
            }
            else
            {
                // RS485_TX_finish = 0x0;
            }
        }
    }
    else if(zhenduanflag == Data_Mode_Read)
    {
        // if(BarCode[0] == 0x59 && BarCode[1] == 0x44)
        // {
        //         for(int i = 0;i<255;i++)
        //         {
        //             if(BarCode[i] == 0x4A && BarCode[i - 1] == 0x4B)
        //             {
        //                 arraynum = i;
        //             }
        //         }
        //         if(((BarCode[arraynum]) == 0x4A) && ((BarCode[arraynum-1]) == 0x4B))
        //         {
        //            if(BarCode[4] == 0x62 && BarCode[5] == 0x50 && BarCode[6] == 0)
        //            {
        //                 memcpy(get_num_buf,BarCode+7,34 );
        //                 comparestart = 1;
        //                 zhenduanflag = 3;
                        
        //            }
                    
        //         }
        // }
    }
}
uint8_t cmpresult = 3;
void BarCodeDataGet(void)
{

    if((mDataBufPtr1[0] == 0x59) && (mDataBufPtr1[1] == 0x59)&&(mDataBufPtr1[39] != 0x0))
    {
        memcpy(barcode_Msg,&mDataBufPtr1[6],34);
        memcpy(barcode_Msg1,&mDataBufPtr1[6],34);
    }
    else
    {
        // memcpy(barcode_Msg1,&mDataBufPtr1[6],34);
        memset(barcode_Msg,0,34);
        // General_Number_Disp(writefail, 3, 250);
    }
}
uint8_t GetDataCompare(void)
{
    
    for(int i = 0;i<34;i++)
    {
        if(get_num_buf[i] == barcode_Msg1[i] )
        {
            cmpresult = 0;
            // u8compareresult = 0;
        }
        else
        {
            cmpresult = 1;
            return cmpresult;
            // u8compareresult = 1;
        }
        
    }
    return cmpresult;
    
}
void UART_Put(uint32_t Value)
{
    uint32_t nextPos = 0u;
    
    nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf.read_pos )
    {
        //队列已满，无法插入队列
        // UARTRxBuf.write_pos  = 0;
        // RS485_TX_finish = 0;
    }
    else
    {
        UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Value;
        UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
    }
    // RS485_TX_finish = 0;
    // RS485_TX_finish = 0;
    // RS485_send_time = 0;
    RS485_send_time = 0;
    return;
}
void UART_Put1(uint32_t Value)
{
    uint32_t nextPos = 0u;
    
    nextPos = (UARTRxBuf1.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf1.read_pos )
    {
        //队列已满，无法插入队列
        // UARTRxBuf.write_pos  = 0;
        // RS485_TX_finish = 0;
    }
    else
    {
        UARTRxBuf1.Rx_Buffer [ UARTRxBuf1.write_pos ] = Value;
        UARTRxBuf1.write_pos                         = (UARTRxBuf1.write_pos + 1) % UART_RX_MAX_DEPTH;
    }
    // RS485_TX_finish = 0;
    // RS485_TX_finish = 0;
    if(firstpowerflag != 2)
    {
        firstpowerflag = 1;
    }
    return;
}

void UART_Put2(uint32_t Value)
{
    uint32_t nextPos = 0u;
    
    nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

    if ( nextPos == UARTRxBuf.read_pos )
    {
        //队列已满，无法插入队列
        // UARTRxBuf.write_pos  = 0;
        // RS485_TX_finish = 0;
    }
    else
    {
        // UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Value;
        // UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
    }
    // RS485_send_time = 0;
    return;
}

void Recv_Byte(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;
    int k = 0;
    readNum = Protocol_UartRead(mDataBufPtr + mDataBufLen, 1025 - mDataBufLen);
    uint8_t testflag = 0;
    if ( readNum > 0 )
    {
        mDataBufLen += readNum;

        while(mDataBufLen)
        {
            for(i = 0; i < mDataBufLen; i++)
            {
                if(mDataBufPtr[i - 1] == 0x59  && mDataBufPtr[i] == 0x44)
                {
                    k = i - 1;
                }
                
                if((mDataBufPtr[k] == 0x59 && mDataBufPtr[k+1] == 0x44) && (mDataBufPtr[i] == 0x4A ) && (mDataBufPtr[i - 1] == 0x4B) && (i > mDataBufPtr[k + 3] - 3))
                {
                    if( i < 1)
                    {
                        break;
                    }
                    memset(BarCode, 0, sizeof(BarCode));
                    for(j = 0; j < i+1; j++)
                    {
                        BarCode[j] = mDataBufPtr[j];
                    }
                    testflag = 0;
                    break;
                }
                else
                {
                    testflag = 1;
                }
            }
            if(testflag)
            {
                testflag = 0;
                break;
            }
            // 解析协议
            len = i+1;
            if ( (len > 0) && (len < mDataBufLen) )
            {
                // 将未解析的数据移到头部
                // Move unparsed data to the head
                
                memcpy(mDataBufPtr, mDataBufPtr + len, mDataBufLen - len);
                
                // memcpy(nowdata,mDataBufPtr + len,len);
                // datacheck();
            }
            mDataBufLen -= len;
            datacheck();
        }
        
    }
    
    return;
}

static uint32_t Protocol_UartRead(uint8_t *pData, uint32_t len)
{
    uint32_t i       = 0;
    uint32_t DataLen = 0u;
    uint32_t ReadLen = 0u;

    if ( UARTRxBuf.write_pos == UARTRxBuf.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf.write_pos > UARTRxBuf.read_pos )
    {
        DataLen = UARTRxBuf.write_pos - UARTRxBuf.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf.read_pos - UARTRxBuf.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf.Rx_Buffer [ UARTRxBuf.read_pos ];
        UARTRxBuf.read_pos = (UARTRxBuf.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return i;
}
void Recv_Byte1(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;
    readNum1 = Protocol_UartRead1(mDataBufPtr1 + mDataBufLen1, 1024 - mDataBufLen1);
    // if (readNum1 > 0)
    // {
    // BarCodeDataGet();
    // }
    if (readNum1 > 0)
    {
        mDataBufLen1 += readNum1;

        while(mDataBufLen1)
        {
            memset(BarCode1, 0, sizeof(BarCode1));
            for(i = 0; i < mDataBufLen1; i++)
            {
                    // if((mDataBufPtr1[i] == 0x0 ) && (mDataBufPtr1[i - 1] == 0x0))
                    // {
                        // if( i < 1)
                        // {
                        //     break;
                        // }
                        // memset(BarCode1, 0, sizeof(BarCode1));
                        
                        for(j = 0; j < mDataBufLen1; j++)
                        {
                            BarCode1[j] = mDataBufPtr1[j];
                        }
                        
                    
                    // }
                
                
            }

            // 解析协议
            len = mDataBufLen1;
            if ( (len > 0) && (len < mDataBufLen1) )
            {
                // 将未解析的数据移到头部
                // Move unparsed data to the head
                
                memcpy(mDataBufPtr1, mDataBufPtr1 + len, mDataBufLen1 - len);
                
                // memcpy(nowdata,mDataBufPtr + len,len);
                // datacheck();
            }
            
            mDataBufLen1 -= len;
            
        }
        BarCodeDataGet();
    }
    
    
}

static uint32_t Protocol_UartRead1(uint8_t *pData, uint32_t len)
{
    uint32_t i       = 0;
    uint32_t DataLen = 0u;
    uint32_t ReadLen = 0u;

    if ( UARTRxBuf1.write_pos == UARTRxBuf1.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf1.write_pos > UARTRxBuf1.read_pos )
    {
        DataLen = UARTRxBuf1.write_pos - UARTRxBuf1.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf1.read_pos - UARTRxBuf1.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf1.Rx_Buffer [ UARTRxBuf1.read_pos ];
        UARTRxBuf1.read_pos = (UARTRxBuf1.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return i;
}


void Recv_Byte2(void)
{
    int      i = 0;
    int      j = 0;
    uint32_t      len;
    readNum1 = Protocol_UartRead2(mDataBufPtr1 + mDataBufLen1, 1024 - mDataBufLen1);
    // if (readNum1 > 0)
    // {
    // BarCodeDataGet();
    // }
    if (readNum1 > 0)
    {
        mDataBufLen1 += readNum1;

        while(mDataBufLen1)
        {
            memset(BarCode1, 0, sizeof(BarCode1));
            for(i = 0; i < mDataBufLen1; i++)
            {
                    // if((mDataBufPtr1[i] == 0x0 ) && (mDataBufPtr1[i - 1] == 0x0))
                    // {
                        // if( i < 1)
                        // {
                        //     break;
                        // }
                        // memset(BarCode1, 0, sizeof(BarCode1));
                        
                        for(j = 0; j < mDataBufLen1; j++)
                        {
                            BarCode1[j] = mDataBufPtr1[j];
                        }
                        
                    
                    // }
                
                
            }

            // 解析协议
            len = mDataBufLen1;
            if ( (len > 0) && (len < mDataBufLen1) )
            {
                // 将未解析的数据移到头部
                // Move unparsed data to the head
                
                memcpy(mDataBufPtr1, mDataBufPtr1 + len, mDataBufLen1 - len);
                
                // memcpy(nowdata,mDataBufPtr + len,len);
                // datacheck();
            }
            
            mDataBufLen1 -= len;
            
        }
        BarCodeDataGet();
    }
    
    
}

static uint32_t Protocol_UartRead2(uint8_t *pData, uint32_t len)
{
    uint32_t i       = 0;
    uint32_t DataLen = 0u;
    uint32_t ReadLen = 0u;

    if ( UARTRxBuf1.write_pos == UARTRxBuf1.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf1.write_pos > UARTRxBuf1.read_pos )
    {
        DataLen = UARTRxBuf1.write_pos - UARTRxBuf1.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf1.read_pos - UARTRxBuf1.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf1.Rx_Buffer [ UARTRxBuf1.read_pos ];
        UARTRxBuf1.read_pos = (UARTRxBuf1.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return i;
}
