#include "wmhcomm.h"
#include "wmhcommdata.h"
#include "mwwmhcomm.h"
#include "TYW_stdint.h"
#include "string.h"
#include "Task.h"
#include "CAN_Communication_Matrix.h"
const WMH_COMM_INIT_FRAME_T WMHCommRecvInitList[EM_WMH_COMM_RECV_MSG_TOTAL] = {
    {0x80u, 1000u, COMM_DATA_UNION_WI_BOX_LENGTH_0X80, 5000u, 1u, WMHCommDataWiBox_0x80.Bytes, WMHCommFrameCallBack_WiBox_0x80, WMHCommFrameTimeoutFunc_WiBox80, WMHCommFrameCheckSumFunc},
};

const WMH_COMM_INIT_FRAME_T WMHCommSendInitList[EM_WMH_COMM_SEND_MSG_TOTAL] = {
    {0x90u, 1000u, COMM_DATA_UNION_WI_BOX_LENGTH_0X90, 10000u, 1u, WMHCommDataWiBox_0x90.Bytes, WMHCommFrameCallBack_Icm, WMHCommFrameTimeoutFunc_WiBox_90, WMHCommFrameCheckSumFunc},
    {0x91u, 1000u, COMM_DATA_UNION_WI_BOX_LENGTH_0X91, 10000u, 1u, WMHCommDataWiBox_0x91.Bytes, WMHCommFrameCallBack_Icm, WMHCommFrameTimeoutFunc_WiBox_91, WMHCommFrameCheckSumFunc},
    {0x92u, 1000u, COMM_DATA_UNION_WI_BOX_LENGTH_0X92, 10000u, 1u, WMHCommDataWiBox_0x92.Bytes, WMHCommFrameCallBack_Icm, WMHCommFrameTimeoutFunc_WiBox_92, WMHCommFrameCheckSumFunc},
};

uint32_t WMHCommRecvMessageTimeout[EM_WMH_COMM_RECV_MSG_TOTAL] = {0};
uint32_t WMHCommSendMessageTimeout[EM_WMH_COMM_SEND_MSG_TOTAL] = {0};

uint32_t WMHCommAnalysisPos = 0;
void WMHCommInit(void)
{
    uint8_t i = 0;
    for (i = 0; i < EM_WMH_COMM_RECV_MSG_TOTAL; i++) {
        (void)memset(WMHCommRecvInitList[i].SignalList, 0, WMHCommRecvInitList[i].DLC);
        WMHCommRecvMessageTimeout[i] = WMHCommRecvInitList[i].TimeoutMax;
    }
    for (i = 0; i < EM_WMH_COMM_SEND_MSG_TOTAL; i++) {
        (void)memset(WMHCommSendInitList[i].SignalList, 0, WMHCommSendInitList[i].DLC);
        WMHCommSendMessageTimeout[i] = WMHCommSendInitList[i].TimeoutMax;
    }
    WMHCommAnalysisPos = 0;
}

void WMHCommFramePackedTransmit(EM_WMH_COMM_SEND_MSG_T MsgIdx)
{
    uint8_t data[64] = {0};
    uint8_t length = 0;
    if ((MsgIdx < EM_WMH_COMM_SEND_MSG_TOTAL) && (MsgIdx > 0)){
        if ((WMHCommSendInitList[MsgIdx].DLC + 4) <= 64) {
            if (WMHCommSendInitList[MsgIdx].FrameCallBackFunc != NULL_P) {
                WMHCommSendInitList[MsgIdx].FrameCallBackFunc();
            }
            data[0] = WMHCommSendInitList[MsgIdx].ID;//id
            data[1] = WMH_COMM_PROTOCOL_VERSION;//主协议版本号
            data[2] = WMHCommSendInitList[MsgIdx].DLC + 1u;//数据长度
            (void)memcpy(&data[3], WMHCommSendInitList[MsgIdx].SignalList, WMHCommSendInitList[MsgIdx].DLC);
            data[3 + WMHCommSendInitList[MsgIdx].DLC] = WMHCommSendInitList[MsgIdx].FrameGetCheckSum(WMHCommSendInitList[MsgIdx].ID, WMHCommSendInitList[MsgIdx].DLC, data[1], WMHCommSendInitList[MsgIdx].SignalList);
            length = WMHCommSendInitList[MsgIdx].DLC + 4u;
            mwWMHCommTransmitBytes(data, length);
            WMHCommSendMessageTimeout[MsgIdx] = WMHCommSendInitList[MsgIdx].TimeoutMax;
        }
    }
    else if(MsgIdx == 0)
    {
        if ((WMHCommSendInitList[MsgIdx].DLC + 4) <= 64) {
            if (WMHCommSendInitList[MsgIdx].FrameCallBackFunc != NULL_P) {
                WMHCommSendInitList[MsgIdx].FrameCallBackFunc();
            }
            data[0] = WMHCommSendInitList[MsgIdx].ID;//id
            data[1] = WMH_COMM_PROTOCOL_VERSION;//主协议版本号
            data[2] = WMHCommSendInitList[MsgIdx].DLC + 1u;//数据长度
            (void)memcpy(&data[3], WMHCommSendInitList[MsgIdx].SignalList, WMHCommSendInitList[MsgIdx].DLC);
            data[3 + WMHCommSendInitList[MsgIdx].DLC] = WMHCommSendInitList[MsgIdx].FrameGetCheckSum(WMHCommSendInitList[MsgIdx].ID, WMHCommSendInitList[MsgIdx].DLC, data[1], WMHCommSendInitList[MsgIdx].SignalList);
            length = WMHCommSendInitList[MsgIdx].DLC + 4u;
            mwWMHCommTransmitBytes_90(data, length);
            WMHCommSendMessageTimeout[MsgIdx] = WMHCommSendInitList[MsgIdx].TimeoutMax;
        }
    }
}

void WMHCommFrameUnpacked(uint8_t *data, uint32_t length)
{
    uint32_t i = EM_WMH_COMM_RECV_MSG_WI_BOX_0x80;
    if (length > 0) {
            if (data[0] == WMHCommRecvInitList[i].ID) {
                if ((data[2] == (WMHCommRecvInitList[i].DLC + 1)) && (length == (WMHCommRecvInitList[i].DLC + 4))) {
                    if (data[length - 1] == WMHCommRecvInitList[i].FrameGetCheckSum(data[0], WMHCommRecvInitList[i].DLC, data[1], &data[3])) {
                        (void)memcpy(WMHCommRecvInitList[i].SignalList, &data[3], WMHCommRecvInitList[i].DLC);
                        if (WMHCommRecvInitList[i].FrameCallBackFunc != NULL_P) {
                            WMHCommRecvInitList[i].FrameCallBackFunc();
                        }
                        WMHCommRecvMessageTimeout[i] = WMHCommRecvInitList[i].TimeoutMax;
                        Can_Msg_Tx_Overwrite(&CAN_CH4_CanMsgTxOp,0u,1u,1000u);
                    }
                }
 
            }
    }
}

void WMHCommTimeoutService(uint32_t TimerDelta)
{
    uint8_t i = 0;
    for (i = 0; i < EM_WMH_COMM_RECV_MSG_TOTAL; i++) {
        if (WMHCommRecvMessageTimeout[i] > TimerDelta) {
            WMHCommRecvMessageTimeout[i] -= TimerDelta;
        } else {
            if (WMHCommRecvMessageTimeout[i] > 0) {
                if (WMHCommRecvInitList[i].FrameTimeoutFunc != NULL_P) {
                    WMHCommRecvInitList[i].FrameTimeoutFunc();
                }
            }
            WMHCommRecvMessageTimeout[i] = 0;
        }
    }
    for (i = 0; i < EM_WMH_COMM_SEND_MSG_TOTAL; i++) {
        if (WMHCommSendMessageTimeout[i] > TimerDelta) {
            WMHCommSendMessageTimeout[i] -= TimerDelta;
        } else {
            if (WMHCommSendMessageTimeout[i] > 0) {
                if (WMHCommSendInitList[i].FrameTimeoutFunc != NULL_P) {
                    WMHCommSendInitList[i].FrameTimeoutFunc();
                }
            }
            WMHCommSendMessageTimeout[i] = 0;
        }
    }
}

uint32_t WMHCommServiceCnts = 0;
void WMHCommService(uint32_t TimerDelta)
{
    uint8_t data[64] = {0};
    uint32_t length = 0;
    uint32_t tmpPos = 0;
    uint8_t *tmpAddr = NULL_P;
    uint8_t i = 0;

    WMHCommTimeoutService(TimerDelta);
    WMHCommServiceCnts += TimerDelta;
    if (WMHCommServiceCnts >= 50) {
        WMHCommServiceCnts = 0;
        //mwWMHCommTransmitBytes(tmpBuffer, length);
        tmpAddr = mwWMHCommGetRecvData(&length, &tmpPos);
        if (tmpAddr != NULL_P) {
            i = 0;
            while (WMHCommAnalysisPos != tmpPos) {
                data[i++] = (tmpAddr[WMHCommAnalysisPos++]);
                WMHCommAnalysisPos = WMHCommAnalysisPos % length;
            }
            // if (SYS_OPR_STAT_IGN_ON)
            //  {
                WMHCommFrameUnpacked(data, i);
            // }
        }
    }
}

uint8_t WMHCommFrameGetRecvTimeoutSt(uint8_t n)
{
    uint8_t ret = 0;
    if (n < EM_WMH_COMM_RECV_MSG_TOTAL) {
        ret = (uint8_t)(WMHCommRecvMessageTimeout[n] == 0);
    }
    return ret;
}
