#include "bmser_can_j1939_recv.h"
#include "j1939_map_db_obj_cfg.h"
#include "j1939_queue.h"
#include "define_base.h"
#include "j1939_compress.h"
#include "toolkit.h"
#include "bcu_db_addr.h"
#include "bmser_can_j1939_send.h"
#include "xieneng_can_mqtt.h"
#include "xieneng_can_component.h"
#include "bmser_can_j1939_syn_data.h"

#define J1939_BAU_TO_BCU_HANDLE_ID1           CAN_OBJ_ID_1 /*BCU与BAU之间通信的CAN的handle id*/
#define J1939_BAU_TO_BCU_HANDLE_ID2           CAN_OBJ_ID_2 /*BCU与BAU之间通信的CAN的handle id*/

#define J1939_CAN_BAU_MAX_TX_MSG_LEN         20      /*发送消息长度*/
#define J1939_CAN_BAU_MAX_RX_MSG_LEN         1024        /*接收消息长度*/

#define J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM  (J1939_CAN_BAU_MAX_RX_MSG_LEN /2)

#if (J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM < 512)
  #error J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM ERR
#endif

// TODO: 接收多帧通过宏控制，后续改到配置文件
#define BMS_FUNC_ENABLE_INQUIRE_DETAIL_INFO         1
#ifndef BMS_FUNC_ENABLE_INQUIRE_DETAIL_INFO
  #error BMS_FUNC_ENABLE_INQUIRE_DETAIL_INFO not define
#endif

#define BufferCopy J1939_BufferCopy
#define BufferSet J1939_BufferSet 

typedef struct
{
    uint8_t  J1939TxMsgBuffer[J1939_CAN_BAU_MAX_TX_MSG_LEN];/*发送消息buf*/
    uint8_t  J1939RxMsgBuffer[J1939_CAN_BAU_MAX_RX_MSG_LEN]; /*接收消息buf*/
    uint8_t  J1939TxTpDataBuffer[J1939_CAN_BAU_MAX_TX_MSG_LEN];
    uint8_t  J1939RxTpDataBuffer[J1939_TP_RX_SESSION_NUM][J1939_CAN_BAU_MAX_RX_MSG_LEN];
    uint8_t  J1939RxMsgQueueBuffer[J1939_RX_MSG_QUEUE_MAX_NUM][J1939_CAN_BAU_MAX_RX_MSG_LEN];/*接收消息队列*/
    J1939Msg     J1939TxMsg; /*发送消息*/
    J1939Msg     J1939RxMsg; /*接收消息*/
    J1939Context J1939Context;
    uint32_t maxSendFrameNumOneTime;/*每次发生消息帧数量*/
    uint64_t rackInitState;/*每一位代表一个主控，该位置1，表示该主控已经复位*/
    uint64_t isRecvDetailInfoFlag;/*接收详细信息标志位*/
}J1939_MSG_PROCESS_STRU;

J1939_MSG_PROCESS_STRU *g_pJ1939MsgProcessStru[CAN_OBJ_ID_MAX] = {NULL,NULL};
static long long g_recvTime[BMS_CFG_ROCKSNUM_MAX] = {0};
Std_Ret_Type J1939MasterRecvMsg_ReceiveNormalDetailFrameCallback(CanMsg *rxcan,uint8_t pf,uint8_t bcuIdIndex);

/*!
 * @brief       更新BCU初始化状态；
 *
 * @param[in]   ComIf_Handle_Type handle
 * @param[in]   uint16_t dbObj
 * @param[in]   uint16_t dbSubObj
 * @param[in]   uint16_t regValu
 * @param[in]   uint8_t bcuIndex
 * @return      int32_t
 * @retval      None
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-9-6    jyg      Create             \n
 */
Std_Ret_Type J1939MasterRecvMsg_UpdateBcuInitState(uint32_t canIdIndex,uint16_t dbAddr,uint16_t regValue,uint8_t bcuIndex)
{
    if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
    {
        return Std_Ret_ERR;
    }

    if(dbAddr == BMS_RESVER_CFG_PARA_MAIN_INIT_STATE)
    {
        if(regValue != 0)
        {
            /*说明该簇已经复位*/
            g_pJ1939MsgProcessStru[canIdIndex]->rackInitState |= 1<<bcuIndex;
        }
    }
    return Std_Ret_OK;
}

/*!
 * @brief       获取BUC初始化状态；
 *
 * @param[in]   uint32_t canIdIndex
 * @param[in]   uint64_t *bcuInitState
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK:获取成功 Std_Ret_OK:获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-9-6    jyg      Create             \n
 */
Std_Ret_Type J1939MasterRecvMsg_GetBcuInitState(uint32_t canIdIndex,uint64_t *bcuInitState)
{
    if((g_pJ1939MsgProcessStru[canIdIndex] == NULL)||(bcuInitState == NULL))
    {
        return Std_Ret_ERR;
    }

    *bcuInitState = g_pJ1939MsgProcessStru[canIdIndex]->rackInitState;

    return Std_Ret_OK;
}

/*!
 * @brief       重置BUC初始化状态；
 *
 * @param[in]   uint32_t canIdIndex
 * @param[in]   uint8_t bcuIndex
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK:重置成功 Std_Ret_OK:重置失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-9-6    jyg      Create             \n
 */
Std_Ret_Type J1939MasterRecvMsg_SetBcuInitState(uint32_t canIdIndex,uint8_t bcuIndex)
{
    if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
    {
        return Std_Ret_OK;
    }

    g_pJ1939MsgProcessStru[canIdIndex]->rackInitState &= ~(1<<bcuIndex);

    return Std_Ret_OK;
}


/*!
 * @brief       解析BCU消息（消息长度 <= 8）；
 *
 * @param[in]   ComIf_Handle_Type handle
 * @param[in]   ComIfData* msg
 * @return      int32_t
 * @retval      None
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-4-19           Create             \n
 * 2023-5-9            增加写响应的后处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_ReceiveNormalFrameCallback(int canIdIndex, CanMsg *rxcan)
{
    uint8_t p_Level = 0,pf = 0u,bcuIdIndex = 0; 
    uint16_t regOffset = 0,regValue = 0;
    int32_t i = 0,j = 0,tableListItemNum = 0;
    EMS_DEV_REG_DATA_S regData = {0};
    J1939_CFG_INFO_STRU *cfgInfo = NULL;
    Std_Ret_Type ret = Std_Ret_OK;
    // uint8_t datatype = 0;
    uint16_t bankId = 0, rackId = 0;
    if(rxcan == NULL)
    {
        return Std_Ret_ERR;
    } 
    p_Level = (uint8_t)((rxcan->CanId >>J1939_CANID_P_POS)&0x07u);
    pf = (uint8_t)((rxcan->CanId >>J1939_CANID_PF_POS)&0xffu);
    bcuIdIndex = (uint8_t)((rxcan->CanId & 0xffu)-J1939_PDU_BCUx_DEF_ADDR);/*簇索引从1开始*/
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIdIndex,&bankId,&rackId);

    if((pf == J1939_SINGLE_CFG_CMD_PF_VALUE)&&(p_Level == J1939_SINGLE_CFG_CMD_P_LEVEL_VALUE))
    {
        cfgInfo = (J1939_CFG_INFO_STRU *)rxcan->Data;
        if(cfgInfo->operationType == J1939_CFG_OPT_TYPE_WRITE_RESPONSE)
        {
            // 写响应
            J1939_WriteRespCallback(rxcan->CanId,(uint8_t*)cfgInfo,J1939_CFG_INFO_MSG_HEAD_LEN);
        }
        else if(cfgInfo->operationType == J1939_CFG_OPT_TYPE_RESPONSE_ERR)
        {
            return Std_Ret_ERR;
        }
        else
        {
            /**/
        }
        p_Level = cfgInfo->priorityLevel;
        pf = cfgInfo->pfNum;        
    }
    else if(p_Level == J1939_SINGLE_DETAIL_INFO_P_LEVEL_VALUE)
    {
        ret = J1939MasterRecvMsg_ReceiveNormalDetailFrameCallback(rxcan,pf,bcuIdIndex);
        return ret;
    }
    else
    {
        /**/
    }
    tableListItemNum = DbObjCfgJ1939_GetDbAddrResponseTableListItemNum();
    for(i = 0;i<tableListItemNum;i++)
    {
        if(p_Level != g_J1939_PF_DbAddrResponseTableList[i].responseOptTypeLevel)
        {
            continue;
        }
        regOffset = 0;
        for(j = 0;j<g_J1939_PF_DbAddrResponseTableList[i].responseOptTypeItemsNum;j++)
        {
            if(pf == g_J1939_PF_DbAddrResponseTableList[i].pfMapDbAddrTable[j].j1939_PF_BaseAddr)
            {
                // unsigned char buf[128] = {0};
                // datainsert_header_t *data_insert = (datainsert_header_t*)buf;
                if(cfgInfo == NULL)
                {
                    regOffset = g_J1939_PF_DbAddrResponseTableList[i].pfMapDbAddrTable[j].j1939_PF_BaseAddrOffset;
                    /*将消息的内容写入到DB中,j1939是小段格式*/
                    regValue = rxcan->Data[regOffset] | (rxcan->Data[regOffset+1]<<8);
                    regValue = (uint16_t)LITTLE_TO_BIG_ENDIAN_16(regValue);
                    regData.bankId = bankId;
                    regData.rackId = rackId;
                    regData.regCount = 1;
                    regData.len = regData.regCount*2;
                    regData.data = (uint8_t*)&regValue;
                    regData.startAddr = g_J1939_PF_DbAddrResponseTableList[i].pfMapDbAddrTable[j].j1939_DbAddr;
                    ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
                    ret |= J1939MasterRecvMsg_UpdateBcuInitState(canIdIndex,regData.startAddr,regValue,bcuIdIndex);
                    // 概要信息暂不发送
                    // datatype = getDataTypeByDbAddr(regData.startAddr);
                    // if(DATA_TYPE_MAX != datatype)
                    // {
                    //     // mqtt_to_TD
                    //     data_insert->datatype = datatype;
                    //     data_insert->dev_id = bcuIdIndex;
                    //     data_insert->dev_type = BMS_DB_DEV_MASTER;
                    //     data_insert->data_count = regData.regCount;
                    //     memcpy(data_insert->data, regData.data, regData.len);
                    //     int p_len = regData.len + sizeof(datainsert_header_t);
                    //     publish_binaryFlow_Data2TD(buf, p_len, bankId, rackId);
                    // }
                    if(rxcan->DLC <= (regOffset+2))
                    {
                        /*已经写DB完毕*/
                        return ret;
                    } 
                }
                else if(cfgInfo->offset == g_J1939_PF_DbAddrResponseTableList[i].pfMapDbAddrTable[j].j1939_PF_BaseAddrOffset)
                {
                    regValue = (uint16_t)LITTLE_TO_BIG_ENDIAN_16(cfgInfo->cfgValue);
                    regData.bankId = bankId;
                    regData.rackId = rackId;
                    regData.regCount = 1;
                    regData.len = regData.regCount*2;
                    regData.data = (uint8_t*)&regValue;
                    regData.startAddr = g_J1939_PF_DbAddrResponseTableList[i].pfMapDbAddrTable[j].j1939_DbAddr;
                    ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
                    ret |= J1939MasterRecvMsg_UpdateBcuInitState(canIdIndex,regData.startAddr,regValue,bcuIdIndex);
                    // datatype = getDataTypeByDbAddr(regData.startAddr);
                    // if(DATA_TYPE_MAX != datatype)
                    // {
                    //     // mqtt_to_TD
                    //     data_insert = (datainsert_header_t*)buf;
                    //     data_insert->datatype = datatype;
                    //     data_insert->dev_id = bcuIdIndex;
                    //     data_insert->dev_type = BMS_DB_DEV_MASTER;
                    //     data_insert->data_count = regData.regCount;
                    //     memcpy(data_insert->data, regData.data, regData.len);
                    //     int p_len = regData.len + sizeof(datainsert_header_t);
                    //     publish_binaryFlow_Data2TD(buf, p_len, bankId, rackId);
                    // }
                    return ret;
                }
                else
                {
                    /**/
                }
            }
        }
    }
    return ret; 
}

/*!
 * @brief       接收CAN数据帧回调函数
 *
 * @param[in]   ComIf_Handle_Type handle
 * @param[in]   ComIfData* msg
 * @return      int32_t
 * @retval      None
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-4-19           Create             \n
 * 2023-5-5            修正总主通信支持2路CAN通信             \n
 * 2023-5-10           增加对簇通信判断及接收数据合法性判断             \n
 * 2023-5-17           增加对广播帧解析\n
 * 2023-9-2            增加对目的地址为0xC1帧解析           \n
 */
Std_Ret_Type J1939RecvMsg_ReceiveCallback(int canIdIndex, CanMsg *rxcan)
{
    J1939Msg  j1939RxMsg = {0};
    uint8_t p_Level = 0u,pf = 0u;
    Std_Ret_Type ret = Std_Ret_OK;

    if((rxcan == NULL)||(g_pJ1939MsgProcessStru[canIdIndex] == NULL))
    {
        return Std_Ret_ERR;
    }

    j1939RxMsg.id.value = rxcan->CanId;

    /*仅处理目的地址为0xC0,0xC1,0xFF的报文*/
    if(((j1939RxMsg.id.Bits.PS != J1939_PDU_BAU_ADDR)&&(j1939RxMsg.id.Bits.PS != J1939_BROADCAST_DST_ADDR)&&(j1939RxMsg.id.Bits.PS != J1939_PDU_LINUX_ADDR)) \
        ||(j1939RxMsg.id.Bits.R != J1939_R_J1939))
    {
        return Std_Ret_ERR;
    }
    /*源地址为0xC0 - 0x80(0xC0,0xC1)不处理*/
    if((j1939RxMsg.id.Bits.SA <= J1939_PDU_BCUx_DEF_ADDR )||(j1939RxMsg.id.Bits.SA >= J1939_PDU_BAU_ADDR))
    {
        return Std_Ret_ERR;
    }
    /*收到合法的j1939报文, 更新接收时间*/
    uint32_t devId = 0xFFFF;
    devId = (uint8_t)((rxcan->CanId & 0xffu)-J1939_PDU_BCUx_DEF_ADDR);
    g_recvTime[devId] = bmser_get_time_stamp_ms();

    /*多帧信息使用J1939，单帧的话直接解析*/
    p_Level = (uint8_t)((rxcan->CanId >>J1939_CANID_P_POS)&0x07u);
    pf = (uint8_t)((rxcan->CanId >>J1939_CANID_PF_POS)&0xffu);
    if(((p_Level == J1939_TP_CM_DEFAULT_PRI)&&(pf == ((J1939_PGN_TP_CM>>8)&0xffu))) \
        ||((p_Level == J1939_TP_DATA_DEFAULT_PRI)&&(pf == ((J1939_PGN_TP_DATA>>8)&0xffu))))
    {
    // 先使用宏，后续改成json配置项
    #if(BMS_FUNC_ENABLE_INQUIRE_DETAIL_INFO == 1)
        J1939CanFrame frame = {0};
        uint8_t i = 0u;
        /*多帧使用J1939协议栈进行解析*/
        frame.id.value = rxcan->CanId;
        frame.data_len = rxcan->DLC;
        /*模式*/
        if(CAN_ID_EXT == (uint8_t)rxcan->IDE)
        {
            frame.mode = 0x01;
        }
        else
        {
            frame.mode = 0x00;
        }
        for(i = 0;i < CAN_FRAME_DATA_MAX_LEN;i++)
        {
            frame.data[i] = rxcan->Data[i];
        }

        pthread_mutex_lock(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_frame_tmp_queue.mutex);
        ret = J1939_PushCanFrameToQueue(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_frame_tmp_queue, &frame);
        pthread_mutex_unlock(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_frame_tmp_queue.mutex);
    #endif
    }
    else
    {
        /*单包直接解析*/
        ret = J1939MasterRecvMsg_ReceiveNormalFrameCallback(canIdIndex, rxcan);
    }

    return ret;
}

J1939CanDeviceParam g_CanParaInfo[CAN_OBJ_ID_MAX]=
{
    {J1939_BAU_TO_BCU_HANDLE_ID1,0u,J1939_PDU_LINUX_ADDR},
    {J1939_BAU_TO_BCU_HANDLE_ID2,0u,J1939_PDU_LINUX_ADDR},
};

/*!
 * @brief       CAN消息处理初始化（BCU J1939）
 *
 * @param[in]   J1939CanDeviceParam j1939_param
 * @return      void
 * @retval      None
 *
 * @par         modify    log
 * Date        Author     Description              \n
 * 2023-4-11           Create                    \n
 * 2023-5-5            修正支持2路CAN通信配置             \n
 * 2023-5-11           增加压缩初始化             \n
 * 2023-9-2            Linux侧源地址与设备地址改为0xC1      \n
 */
Std_Ret_Type J1939RecvMsg_Init(CAN_INF_CFG_STRU *pCanInitCfg)
{
    Std_Base_Type i = 0,canIdIndex = 0;
    J1939Result ret = J1939_OK;
    if(pCanInitCfg == NULL)
    {
        return J1939_ERR;
    }
    canIdIndex = pCanInitCfg->canObjId;
    g_pJ1939MsgProcessStru[canIdIndex] = (J1939_MSG_PROCESS_STRU *)malloc(sizeof(J1939_MSG_PROCESS_STRU));
    if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
    {
        return Std_Ret_ERR;
    }
    memset(g_pJ1939MsgProcessStru[canIdIndex], 0x00, sizeof(J1939_MSG_PROCESS_STRU));
    /*J1939缓存设置*/
    g_pJ1939MsgProcessStru[canIdIndex]->J1939TxMsg.msg_max_len = J1939_CAN_BAU_MAX_TX_MSG_LEN;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939TxMsg.data = g_pJ1939MsgProcessStru[canIdIndex]->J1939TxMsgBuffer;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg.msg_max_len = J1939_CAN_BAU_MAX_RX_MSG_LEN;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg.data = g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsgBuffer;
    for(i = 0;i < J1939_RX_MSG_QUEUE_MAX_NUM;i++)
    {
        g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_msg_queue.msg[i].msg_max_len = J1939_CAN_BAU_MAX_RX_MSG_LEN;
        g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_msg_queue.msg[i].data = g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsgQueueBuffer[i];
    }
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_msg_max_len = J1939_CAN_BAU_MAX_RX_MSG_LEN;
    for(i = 0;i < J1939_TP_RX_SESSION_NUM;i++)
    {
        g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.tp_rx_session[i].msg.data = g_pJ1939MsgProcessStru[canIdIndex]->J1939RxTpDataBuffer[i];
        g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.tp_rx_session[i].msg.msg_max_len = J1939_CAN_BAU_MAX_RX_MSG_LEN;
    }
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.tp_tx_session.msg.data =  g_pJ1939MsgProcessStru[canIdIndex]->J1939TxTpDataBuffer;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.tp_tx_session.msg.msg_max_len = J1939_CAN_BAU_MAX_TX_MSG_LEN;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.tp_tx_session.msg.source_addr = g_CanParaInfo[canIdIndex].addr;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.device_param.addr = g_CanParaInfo[canIdIndex].addr;
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.device_param.handleid = g_CanParaInfo[canIdIndex].handleid;

    //根据波特率计算每次发送消息帧数量
    g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.device_param.bps = pCanInitCfg->canBitRate;
    g_CanParaInfo[canIdIndex].bps = g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.device_param.bps;
    g_pJ1939MsgProcessStru[canIdIndex]->maxSendFrameNumOneTime = (g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.device_param.bps / 100000u) + 1u;

    /*J1939初始化*/
    ret = J1939_Init(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context, &g_CanParaInfo[canIdIndex]);
    if(ret != J1939_OK)
    {
        return  Std_Ret_ERR;
    }
    // 初始化互斥锁,一般情况只需要关注rx_frame_tmp_queue该队列会有多线程操作，其余的队列只有一个线程操作
    if (pthread_mutex_init(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.rx_frame_tmp_queue.mutex, NULL) != 0)
    {
        return Std_Ret_ERR;
    }
    return ret;
}

/*!
 * @brief       J1939会话轮询(调用频率越快越好)
 *
 * @param[in]   void 
 * @return      void
 * @retval      None
 *
 * @par         modify    log
 * Date        Author     Description       \n
 * 2023-4-12           Create             \n
 * 2023-5-5            修正总主通信支持2路CAN通信             \n
 *
 */
void J1939MasterRecvMsg_TpSession(void)
{
    Std_Base_Type canIdIndex = 0;

    for(canIdIndex = 0;canIdIndex <CAN_OBJ_ID_MAX ;canIdIndex++)
    {
        if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
        {
            continue ;
        }

    	J1939_TpSession(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context);
    }
}

typedef Std_Ret_Type (*J1939MsgAnalysisFunc)(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);

Std_Ret_Type J1939MasterRecvMsg_BatVolAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_PackTotalVolAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_BalanceCtrlAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_BalanceStateAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_BatTempAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_BalanceTempAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_PolarityTempAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_TempRaiseAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_SocAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_SohAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
Std_Ret_Type J1939MasterRecvMsg_InnerResAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex);
void J1939MasterRecvMsg_UpdateRecvRackDetailState(uint8_t bcuIndex);

typedef struct
{
    uint8_t pf;
    J1939MsgAnalysisFunc j1939MsgAnalysisFunc;   
}J1939_DETAIL_INFO_ANALYSIS_STRU;

const J1939_DETAIL_INFO_ANALYSIS_STRU g_pJ1939MsgAnalysisStru[] = {
    {BMS_J1939_P_LEVEL6_CELL_VOLTAGE_INFO_BASIC_ADDR,                    J1939MasterRecvMsg_BatVolAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_VOLTAGE_COMPRE_INFO_BASIC_ADDR,             J1939MasterRecvMsg_BatVolAnalysis},
    {BMS_J1939_P_LEVEL6_PACK_TOTAL_VOLTAGE_BASIC_ADDR,                   J1939MasterRecvMsg_PackTotalVolAnalysis},
    {BMS_J1939_P_LEVEL6_PACK_TOTAL_VOLTAGE_COMPRE_BASIC_ADDR,            J1939MasterRecvMsg_PackTotalVolAnalysis},
    {BMS_J1939_P_LEVEL6_BALANCE_CTRL_BASIC_ADDR,                         J1939MasterRecvMsg_BalanceCtrlAnalysis},
    {BMS_J1939_P_LEVEL6_BALANCE_CTRL_COMPRE_BASIC_ADDR,                  J1939MasterRecvMsg_BalanceCtrlAnalysis},
    {BMS_J1939_P_LEVEL6_BALANCE_STATE_BASIC_ADDR,                        J1939MasterRecvMsg_BalanceStateAnalysis},
    {BMS_J1939_P_LEVEL6_BALANCE_STATE_COMPRE_BASIC_ADDR,                 J1939MasterRecvMsg_BalanceStateAnalysis},
    {BMS_J1939_P_LEVEL6_BATT_TEMP_INFO_BASIC_ADDR,                       J1939MasterRecvMsg_BatTempAnalysis},
    {BMS_J1939_P_LEVEL6_BATT_TEMP_INFO_COMPRE_BASIC_ADDR,                J1939MasterRecvMsg_BatTempAnalysis},
    {BMS_J1939_P_LEVEL6_CARD_TEMP_INFO_BASIC_ADDR,                       J1939MasterRecvMsg_BalanceTempAnalysis},
    {BMS_J1939_P_LEVEL6_CARD_TEMP_INFO_COMPRE_BASIC_ADDR,                J1939MasterRecvMsg_BalanceTempAnalysis},
    {BMS_J1939_P_LEVEL6_CARD_ACTIVE_TEMP_INFO_BASIC_ADDR,                J1939MasterRecvMsg_BalanceTempAnalysis},
    {BMS_J1939_P_LEVEL6_POLE_TEMP_INFO_BASIC_ADDR,                       J1939MasterRecvMsg_PolarityTempAnalysis},
    {BMS_J1939_P_LEVEL6_POLE_TEMP_INFO_COMPRE_BASIC_ADDR,                J1939MasterRecvMsg_PolarityTempAnalysis},
    {BMS_J1939_P_LEVEL6_CATHODE_POLE_TEMP_INFO_BASIC_ADDR,               J1939MasterRecvMsg_PolarityTempAnalysis},
    {BMS_J1939_P_LEVEL6_TEMP_RISE_INFO_BASIC_ADDR,                       J1939MasterRecvMsg_TempRaiseAnalysis},
    {BMS_J1939_P_LEVEL6_TEMP_RISE_INFO_COMPRE_BASIC_ADDR,                J1939MasterRecvMsg_TempRaiseAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_SOC_INFO_BASIC_ADDR,                        J1939MasterRecvMsg_SocAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_SOC_INFO_COMPRE_BASIC_ADDR,                 J1939MasterRecvMsg_SocAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_SOH_INFO_BASIC_ADDR,                        J1939MasterRecvMsg_SohAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_SOH_INFO_COMPRE_BASIC_ADDR,                 J1939MasterRecvMsg_SohAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_INTERNAL_RESISTANCE_INFO_BASIC_ADDR,        J1939MasterRecvMsg_InnerResAnalysis},
    {BMS_J1939_P_LEVEL6_CELL_INTERNAL_RESISTANCE_INFO_COMPRE_BASIC_ADDR, J1939MasterRecvMsg_InnerResAnalysis}
};

#define J1939_DETAIL_INFO_TYPE_NUM SIZE_OF_ARRAY(g_pJ1939MsgAnalysisStru)

/*!
 * @brief       解析单包BCU详细消息（消息长度 <= 8）；
 *
 * @param[in]   ComIfData* msg
 * @param[in]   uint8_t pf
 * @param[in]  uint8_t bcuIdIndex
 * @return      Std_Ret_Type
 * @retval      0：解析OK，非0：解析失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-8-24    jyg      Create             \n
 */
Std_Ret_Type J1939MasterRecvMsg_ReceiveNormalDetailFrameCallback(CanMsg *rxcan,uint8_t pf,uint8_t bcuIdIndex)
{
    Std_Ret_Type i = 0,ret = Std_Ret_OK;
    J1939Msg  j1939RxMsg = {0};

    if(rxcan == NULL)
    {
        return Std_Ret_ERR;
    } 
    for(i = 0u;i < J1939_DETAIL_INFO_TYPE_NUM ;i++)
    {
        if(pf == g_pJ1939MsgAnalysisStru[i].pf)
        {
            if(g_pJ1939MsgAnalysisStru[i].j1939MsgAnalysisFunc != NULL)
            {
                j1939RxMsg.id.value = rxcan->CanId;
                j1939RxMsg.pgn = (uint32_t)pf<<8;
                j1939RxMsg.msg_len = rxcan->DLC;
                j1939RxMsg.data = rxcan->Data;
                ret = g_pJ1939MsgAnalysisStru[i].j1939MsgAnalysisFunc(&j1939RxMsg,bcuIdIndex);
            }
            break;
        }
    }
    return ret;
}

/*!
 * @brief      更新详细接收状态
 *
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      void
 * @retval      none
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-09-13     jyg      Create             \n
 */
void J1939MasterRecvMsg_UpdateRecvRackDetailState(uint8_t bcuIndex)
{
    uint32_t  i = 0;
    for(i = 0; i< CAN_OBJ_ID_MAX;i++)
    {
        if(g_pJ1939MsgProcessStru[i] != NULL)
        {
            g_pJ1939MsgProcessStru[i]->isRecvDetailInfoFlag |= (1<< bcuIndex); 
        }
    }
}

/*!
 * @brief      解析后的单体电压信息写入DB中/发送至TD
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
  * 2023-04-19            Create             \n
  * 2023-05-11            增加消息解压缩功能             \n
  * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_BatVolAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0;
    uint16_t batVol[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM + SYNCHRO_BUTT] = {0};
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint16_t bankId = 0,rackId = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    if(pf == BMS_J1939_P_LEVEL6_CELL_VOLTAGE_COMPRE_INFO_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&batVol[0],&tmpMsgLen);
        msg->msg_len = tmpMsgLen;
        // 接收详细信息标志
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        // 在同步信息处理流程中写入单体电压DB
        SynSampleDataMaster_Callback(batVol, msg->msg_len, bcuIndex, bankId, rackId);

    }
    else if(pf == BMS_J1939_P_LEVEL6_CELL_VOLTAGE_INFO_BASIC_ADDR)
    {
        /*将单体电压写入DB中*/
        uint32_t Offset = 0;
        Offset = (msg->data[1]<<8) | msg->data[0];
        // 每帧3个数据
        msg->msg_len /= 2;
        msg->msg_len -= 1;
        if(Offset >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_BATTERY_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(batVol,&msg->data[2],(msg->msg_len*2));
        EMS_DEV_REG_DATA_S regData = {0};
        regData.bankId = bankId;
        regData.rackId = rackId;
        regData.regCount = (unsigned short)msg->msg_len;
        regData.len = regData.regCount*2;
        convertArrayToLittleEndian(&batVol[0], regData.regCount);
        regData.data = (uint8_t*)&batVol[0];
        regData.startAddr = BMS_VOLTAGE_SUBOBJ_ID_1 + Offset;
        BmserProtocolExt_UpdateRegisterDb(&regData);
    }

    if(pf == BMS_J1939_P_LEVEL6_CELL_VOLTAGE_COMPRE_INFO_BASIC_ADDR)
    {
        // mqtt_to_TD(忽略同步信息); 单帧需要修改方案，暂仅支持多帧
        unsigned char vol_buf[BUF_LEN] = {0};
        datainsert_header_t *data_insert = (datainsert_header_t*)vol_buf;
        data_insert->datatype = DATA_TYPE_CELL_VOL;
        data_insert->dev_id = bcuIndex;
        data_insert->dev_type = BMS_DB_DEV_MASTER;
        data_insert->data_count = MAX_BATTERY_NUM_IN_ONE_CLUSTER + SYNCHRO_BUTT;
        batVol[msg->msg_len - 1] = 0;       //CRC置0
        memcpy(data_insert->data, (uint8_t*)&batVol[0], (MAX_BATTERY_NUM_IN_ONE_CLUSTER + SYNCHRO_BUTT)*2);
        int p_len = (MAX_BATTERY_NUM_IN_ONE_CLUSTER + SYNCHRO_BUTT)*2 + sizeof(datainsert_header_t);
        publish_binaryFlow_Data2TD(vol_buf, p_len, bankId, rackId);
    }

    return ret;
}

/*!
 * @brief      解析后的电池包总压信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
  * 2023-05-11            增加消息解压缩功能             \n
  * 2023-07-21            修正解压缩时传入压缩内容的长度及解压后存放数组大小             \n
  * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_PackTotalVolAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0;
    uint16_t batVol[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0};
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint32_t Offset = 0;
    uint16_t bankId = 0,rackId = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    if(pf == BMS_J1939_P_LEVEL6_PACK_TOTAL_VOLTAGE_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Offset = 0;
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&batVol[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,MAX_PACK_NUM_IN_ONE_CLUSTER);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2;
        msg->msg_len -= 1;
        if(Offset >= MAX_PACK_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_PACK_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_PACK_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(batVol,&msg->data[2],(msg->msg_len*2));
    }
    regData.bankId = bankId;
    regData.rackId = rackId;
    regData.regCount = (unsigned short)msg->msg_len;
    regData.len = regData.regCount*2;
    convertArrayToLittleEndian(&batVol[0], regData.regCount);
    regData.data = (uint8_t*)&batVol[0];
    regData.startAddr = BMS_PACK_VOL_SUBOBJ_ID_1 + Offset;
    ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
    return ret;

}

/*!
 * @brief      解析后的均衡控制信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
  * 2023-05-11            增加消息解压缩功能             \n
  * 2023-07-21            修正解压后存放数组大小             \n
  * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_BalanceCtrlAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0u;   
    int32_t tmpMsgLen = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    // EMS_DEV_REG_DATA_S regData = {0};
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    if(pf == BMS_J1939_P_LEVEL6_BALANCE_CTRL_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&msg->data[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,MAX_BATTERY_NUM_IN_ONE_CLUSTER);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
    #if 0
        ret |= BMSDB_WriteObj(BMS_DB_GET_MASTER_OBJ_ID_BY_DEVID_AND_BASEOBJ(bcuIndex + BMS_DB_DEV_MASTER,
                    BMS_MAINCTRL_OBJ_ID_VOLTAGE),BMS_VOLTAGE_SUBOBJ_ID_1, msg->msg_len, &msg->data); 
    #endif
    }
    return ret;

}

/*!
 * @brief      解析后的均衡状态信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
  * 2023-05-11            增加消息解压缩功能             \n
  * 2023-07-21            修正解压后存放数组大小             \n
  * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_BalanceStateAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0;
    uint16_t balanceState[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0};
    int32_t tmpMsgLen = 0;
    uint32_t Offset = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    uint16_t bankId = 0,rackId = 0;
    EMS_DEV_REG_DATA_S regData = {0};
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    if(pf == BMS_J1939_P_LEVEL6_BALANCE_STATE_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Offset = 0;
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&balanceState[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,MAX_BATTERY_NUM_IN_ONE_CLUSTER);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*将均衡状态信息写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2;
        msg->msg_len -= 1;
        if(Offset >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_BATTERY_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(balanceState,&msg->data[2],(msg->msg_len*2));
    }
    regData.bankId = bankId;
    regData.rackId = rackId;
    regData.regCount = (unsigned short)msg->msg_len;
    regData.len = regData.regCount*2;
    convertArrayToLittleEndian(&balanceState[0], regData.regCount);
    regData.data = (uint8_t*)&balanceState[0];
    regData.startAddr = BMS_BAT_BALANCE_STATUS_SUBOBJ_ID_1 + Offset;
    ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
    return ret;

}

/*!
 * @brief      解析后的电池温度信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
  * 2023-05-11            增加消息解压缩功能             \n
  * 2023-07-21            修正解压后存放数组大小             \n
  * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_BatTempAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0u;
    uint16_t batTemp[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0u};
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint32_t Offset = 0;
    uint16_t bankId = 0,rackId = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    if(pf == BMS_J1939_P_LEVEL6_BATT_TEMP_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Offset = 0;
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&batTemp[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*将电池温度写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2;
        msg->msg_len -= 1;
        if(Offset >= MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(batTemp,&msg->data[2],(msg->msg_len*2));
    }
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    regData.bankId = bankId;
    regData.rackId = rackId;
    regData.regCount = (unsigned short)msg->msg_len;
    regData.len = regData.regCount*2;
    convertArrayToLittleEndian(&batTemp[0], regData.regCount);
    regData.data = (uint8_t*)&batTemp[0];
    regData.startAddr = BMS_BAT_TEMP_SUBOBJ_ID_1 + Offset;
    ret |= BmserProtocolExt_UpdateRegisterDb(&regData);

    if (pf == BMS_J1939_P_LEVEL6_BATT_TEMP_INFO_COMPRE_BASIC_ADDR)
    {
        // mqtt_to_TD, 暂仅支持多帧
        unsigned char temp_buf[BUF_LEN] = {0};
        datainsert_header_t *data_insert = (datainsert_header_t*)temp_buf;
        data_insert->datatype = DATA_TYPE_CELL_TEMP;
        data_insert->dev_id = bcuIndex;
        data_insert->dev_type = BMS_DB_DEV_MASTER;
        data_insert->data_count = MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER;
        memcpy(data_insert->data, (uint8_t*)&batTemp[0], MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER*2);
        int p_len = MAX_BAT_TEMPERATURE_NUM_IN_ONE_CLUSTER*2 + sizeof(datainsert_header_t);
        publish_binaryFlow_Data2TD(temp_buf, p_len, bankId, rackId);
    }

    return ret;
}

/*!
 * @brief      解析后的均衡温度信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
 * 2023-05-11            增加消息解压缩功能             \n
 * 2023-05-17            修正主动被动均衡温度数量赋值位置             \n
 * 2023-07-21            修正解压缩时传入压缩内容的长度及解压后存放数组大小             \n
 * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_BalanceTempAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0;
    uint32_t passiveTempNum = 0,activeTempNum = 0,dbPassiveTempNum = 0,dbActiveTempNum = 0;
    uint16_t balanceTemp[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM+2] = {0};
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint32_t passiveTempOffset = 0, activeTempOffset = 0;
    uint16_t bankId = 0,rackId = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    if(pf == BMS_J1939_P_LEVEL6_CARD_TEMP_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&balanceTemp[0],&tmpMsgLen);
        passiveTempNum = (uint32_t)((msg->data[0] >> 8)&0xffu);
        activeTempNum = (uint32_t)(msg->data[0]&0xffu); 
        dbPassiveTempNum = MIN(passiveTempNum,(uint32_t)PASSIVE_TEMP_NUM_IN_ONE_CLUSTER);
        memcpy(&balanceTemp[0],&balanceTemp[1],(dbPassiveTempNum*2));
        passiveTempOffset = 0;
        if(activeTempNum != 0)
        {
            dbActiveTempNum = MIN(activeTempNum,(uint32_t)ACTIVE_TEMP_NUM_IN_ONE_CLUSTER);
            memcpy(&balanceTemp[dbPassiveTempNum],&balanceTemp[1+passiveTempNum],(dbActiveTempNum*2));
            activeTempOffset = 0;
        }
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else if(pf == BMS_J1939_P_LEVEL6_CARD_TEMP_INFO_BASIC_ADDR)
    {
        /*非压缩, 将板间被动均衡温度写入DB中*/
        dbActiveTempNum = 0;
        passiveTempOffset = (msg->data[1]<<8) | msg->data[0];
        dbPassiveTempNum = (msg->msg_len/2 - 1);
        if(passiveTempOffset >= PASSIVE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbPassiveTempNum = 0;/*不再进行写入*/
            return Std_Ret_ERR;
        }
        else if((passiveTempOffset + dbPassiveTempNum) >= PASSIVE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbPassiveTempNum = PASSIVE_TEMP_NUM_IN_ONE_CLUSTER - passiveTempOffset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        passiveTempNum = dbPassiveTempNum;
        memcpy(&balanceTemp[0],&msg->data[2],(dbPassiveTempNum*2));
    }
    else if(pf == BMS_J1939_P_LEVEL6_CARD_ACTIVE_TEMP_INFO_BASIC_ADDR)
    {
        /*非压缩, 将板间主动均衡温度写入DB中*/
        dbPassiveTempNum = 0;
        activeTempOffset = (msg->data[1]<<8) | msg->data[0];
        dbActiveTempNum = (msg->msg_len/2 - 1);
        if(activeTempOffset >= ACTIVE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbActiveTempNum = 0;/*不再进行写入*/
            return Std_Ret_ERR;
        }
        else if((activeTempOffset + dbPassiveTempNum) >= ACTIVE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbActiveTempNum = ACTIVE_TEMP_NUM_IN_ONE_CLUSTER - activeTempOffset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        activeTempNum = dbActiveTempNum;
        memcpy(&balanceTemp[0],&msg->data[2],(dbActiveTempNum*2));
    }  

    regData.bankId = bankId;
    regData.rackId = rackId;
    convertArrayToLittleEndian(&balanceTemp[0], (dbPassiveTempNum + dbActiveTempNum));
    //被动
    if(passiveTempNum != 0)
    {
        regData.regCount = dbPassiveTempNum;
        regData.len = regData.regCount*2;
        regData.data = (uint8_t*)&balanceTemp[0];
        regData.startAddr = BMS_PASSIVE_TEMP_SUBOBJ_ID_1 + passiveTempOffset;
        ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
    }
    //主动
    if(activeTempNum != 0)
    {
        regData.regCount = dbActiveTempNum;
        regData.len = regData.regCount*2;
        regData.data = (uint8_t*)&balanceTemp[dbPassiveTempNum];
        regData.startAddr = BMS_ACTIVE_TEMP_SUBOBJ_ID_1 + activeTempOffset;
        ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
     }
    return ret;
}

/*!
 * @brief      解析后的正负极柱信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
 * 2023-05-11            增加消息解压缩功能             \n
 * 2023-05-17            修正主动被动均衡温度数量赋值位置             \n
 * 2023-07-21            修正解压缩时传入压缩内容的长度及解压后存放数组大小及存入DB的起始位置             \n
 * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_PolarityTempAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0;
    uint32_t anodeTempNum = 0,cathodeTempNum = 0,dbAnodeTempNum = 0,dbCathodeTempNum = 0;
    uint16_t polarityTemp[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM+2] = {0};
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint32_t anodeTempOffset = 0, cathodeTempOffset = 0;
    uint16_t bankId = 0,rackId = 0;
    int p_len = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    if(pf == BMS_J1939_P_LEVEL6_POLE_TEMP_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        anodeTempNum = 0;
        cathodeTempOffset = 0;
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t*)&polarityTemp[0],&tmpMsgLen);
        anodeTempNum = ((polarityTemp[0]>>8)&0xff);
        dbAnodeTempNum = MIN(anodeTempNum,(uint32_t)ANODE_TEMP_NUM_IN_ONE_CLUSTER);

        cathodeTempNum = (polarityTemp[0]&0xff);
        dbCathodeTempNum = MIN(cathodeTempNum,(uint32_t)CATHODE_TEMP_NUM_IN_ONE_CLUSTER);
        memcpy(&polarityTemp[0],&polarityTemp[1],(dbAnodeTempNum*2));
        memcpy(&polarityTemp[dbAnodeTempNum],&polarityTemp[1+anodeTempNum],(dbCathodeTempNum*2));
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else if(pf == BMS_J1939_P_LEVEL6_POLE_TEMP_INFO_BASIC_ADDR)
    {
        /*非压缩, 将正极柱温度写入DB中*/
        cathodeTempNum = 0;
        anodeTempOffset = (msg->data[1]<<8) | msg->data[0];
        dbAnodeTempNum = (msg->msg_len/2 - 1);
        if(anodeTempOffset >= ANODE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbAnodeTempNum = 0;/*不再进行写入*/
            return Std_Ret_ERR;
        }
        else if((anodeTempOffset + dbAnodeTempNum) >= ANODE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbAnodeTempNum = ANODE_TEMP_NUM_IN_ONE_CLUSTER - anodeTempOffset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        anodeTempNum = dbAnodeTempNum;
        memcpy(&polarityTemp[0],&msg->data[2],(dbAnodeTempNum*2));
    }
    else if(pf == BMS_J1939_P_LEVEL6_CATHODE_POLE_TEMP_INFO_BASIC_ADDR)
    {
        /*非压缩, 将负极柱温度写入DB中*/
        anodeTempNum = 0;
        cathodeTempOffset = (msg->data[1]<<8) | msg->data[0];
        dbCathodeTempNum = (msg->msg_len/2 - 1);
        if(cathodeTempOffset >= CATHODE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbCathodeTempNum = 0;/*不再进行写入*/
            return Std_Ret_ERR;
        }
        else if((cathodeTempOffset + dbCathodeTempNum) >= CATHODE_TEMP_NUM_IN_ONE_CLUSTER)
        {
            dbCathodeTempNum = CATHODE_TEMP_NUM_IN_ONE_CLUSTER - cathodeTempOffset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        cathodeTempNum = dbCathodeTempNum;
        memcpy(&polarityTemp[0],&msg->data[2],(dbCathodeTempNum*2));
    }
    else
    {
        /**/
    }

    regData.bankId = bankId;
    regData.rackId = rackId;
    convertArrayToLittleEndian(&polarityTemp[0], (dbAnodeTempNum + dbCathodeTempNum));
    if(anodeTempNum != 0)
    {
        regData.regCount = dbAnodeTempNum;
        regData.len = regData.regCount*2;
        regData.data = (uint8_t*)&polarityTemp[0];
        regData.startAddr = BMS_ANODE_TEMP_SUBOBJ_ID_1 + anodeTempOffset;
        ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
    }
    if(cathodeTempNum != 0)
    {
        regData.regCount = dbCathodeTempNum;
        regData.len = regData.regCount*2;
        regData.data = (uint8_t*)&polarityTemp[anodeTempNum];
        regData.startAddr = BMS_CATHODE_TEMP_SUBOBJ_ID_1 + cathodeTempOffset;
        ret |= BmserProtocolExt_UpdateRegisterDb(&regData);
    }

    if(pf == BMS_J1939_P_LEVEL6_POLE_TEMP_INFO_COMPRE_BASIC_ADDR)
    {
        // mqtt_to_TD
        unsigned char anodeTemp_buf[BUF_LEN] = {0};
        datainsert_header_t *data_insert = (datainsert_header_t*)anodeTemp_buf;
        data_insert->datatype = DATA_TYPE_ANODE_TEMP;
        data_insert->dev_id = bcuIndex;
        data_insert->dev_type = BMS_DB_DEV_MASTER;
        data_insert->data_count = ANODE_TEMP_NUM_IN_ONE_CLUSTER;
        memcpy(data_insert->data, (uint8_t*)&polarityTemp[0], ANODE_TEMP_NUM_IN_ONE_CLUSTER*2);
        p_len = ANODE_TEMP_NUM_IN_ONE_CLUSTER*2 + sizeof(datainsert_header_t);
        publish_binaryFlow_Data2TD(anodeTemp_buf, p_len, bankId, rackId);

        // mqtt_to_TD
        unsigned char cathodeTemp_buf[BUF_LEN] = {0};
        data_insert = (datainsert_header_t*)cathodeTemp_buf;
        data_insert->datatype = DATA_TYPE_CATHODE_TEMP;
        data_insert->dev_id = bcuIndex;
        data_insert->dev_type = BMS_DB_DEV_MASTER;
        data_insert->data_count = CATHODE_TEMP_NUM_IN_ONE_CLUSTER;
        memcpy(data_insert->data, (uint8_t*)&polarityTemp[anodeTempNum], CATHODE_TEMP_NUM_IN_ONE_CLUSTER*2);
        p_len = CATHODE_TEMP_NUM_IN_ONE_CLUSTER*2 + sizeof(datainsert_header_t);
        publish_binaryFlow_Data2TD(cathodeTemp_buf, p_len, bankId, rackId);
    }
    return ret;
}

/*!
 * @brief      解析后的电池温度升高信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19             Create             \n
 * 2023-05-11             增加消息解压缩功能             \n
 * 2023-07-21             修正解压缩时传入压缩内容的长度及解压后存放数组大小             \n
 * 2023-09-13             修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_TempRaiseAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    Std_Ret_Type ret = Std_Ret_OK;
#if(MAX_BAT_TEMP_RISE_NUM_IN_ONE_CLUSTER != 0)
    uint8_t pf = 0u;
    uint16_t  batTempRise[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0u};
    uint32_t Offset = 0;
    EMS_DEV_REG_DATA_S regData = {0};
    uint16_t bankId = 0,rackId = 0;
    int32_t tmpMsgLen = 0;

    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    if(pf == BMS_J1939_P_LEVEL6_TEMP_RISE_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Offset = 0;
        Compress_DeCode(&msg->data[0],(int32_t)(msg->msg_len - 1),(int16_t *)&batTempRise[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,MAX_BAT_TEMP_RISE_NUM_IN_ONE_CLUSTER);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*将电池温升写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2u;
        msg->msg_len -= 1u;
        if(Offset >= MAX_BAT_TEMP_RISE_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_BAT_TEMP_RISE_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_BAT_TEMP_RISE_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(batTempRise,&msg->data[2],(msg->msg_len*2));
    }
    // regData.bankId = bankId;
    // regData.rackId = rackId;
    // regData.regCount = msg->msg_len;
    // regData.len = regData.regCount*2;
    // convertArrayToLittleEndian(&batTempRise[0], regData.regCount);
    // regData.data = &batTempRise[0];
    // regData.startAddr = BMS_BAT_TEMP_RISE_SUBOBJ_ID_1 + Offset;
    // BmserProtocolExt_UpdateRegisterDb(&regData); 
#endif
    return ret;

}

/*!
 * @brief      解析后的SOC信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
 * 2023-05-11            增加消息解压缩功能             \n
 * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_SocAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    Std_Ret_Type ret = Std_Ret_OK;
    uint8_t pf = 0u;
    uint16_t soc[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0u}; 
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint32_t Offset = 0;
    uint16_t bankId = 0,rackId = 0;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    if(pf == BMS_J1939_P_LEVEL6_CELL_SOC_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Offset = 0;
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&soc[0],&tmpMsgLen);
        msg->msg_len = MIN(MAX_BATTERY_NUM_IN_ONE_CLUSTER,tmpMsgLen);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*将单体电压写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2u;
        msg->msg_len -= 1u;
        if(Offset >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_BATTERY_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(soc,&msg->data[2],(msg->msg_len*2));
    }
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    regData.bankId = bankId;
    regData.rackId = rackId;
    regData.regCount = msg->msg_len;
    regData.len = regData.regCount*2;
    convertArrayToLittleEndian(&soc[0], regData.regCount);
    regData.data = (uint8_t*)&soc[0];
    regData.startAddr = BMS_SOC_SUBOBJ_ID_1 + Offset;
    BmserProtocolExt_UpdateRegisterDb(&regData);
    return ret;

}

/*!
 * @brief      解析后的SOH信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
 * 2023-05-11            增加消息解压缩功能             \n
 * 2023-07-21            修正解压缩时传入压缩内容的长度及解压后存放数组大小             \n
 * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_SohAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    uint8_t pf = 0u;
    uint16_t soh[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0};
    EMS_DEV_REG_DATA_S regData = {0};
    uint16_t bankId = 0,rackId = 0;
    int32_t tmpMsgLen = 0;
    uint32_t Offset = 0;
    Std_Ret_Type ret = Std_Ret_OK;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    if(pf == BMS_J1939_P_LEVEL6_CELL_SOH_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Offset = 0;
        Compress_DeCode(&msg->data[0],(msg->msg_len - 1),(int16_t *)&soh[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,MAX_BATTERY_NUM_IN_ONE_CLUSTER);
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*将单体SOH写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2u;
        msg->msg_len -= 1u;
        if(Offset >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= MAX_BATTERY_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = MAX_BATTERY_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(soh,&msg->data[2],(msg->msg_len*2));
    }
    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    regData.bankId = bankId;
    regData.rackId = rackId;
    regData.regCount = msg->msg_len;
    regData.len = regData.regCount*2;
    convertArrayToLittleEndian(&soh[0], regData.regCount);
    regData.data = (uint8_t*)&soh[0];
    regData.startAddr = BMS_SOH_SUBOBJ_ID_1 + Offset;
    BmserProtocolExt_UpdateRegisterDb(&regData); 
    return ret;
}

/*!
 * @brief      解析后的电池内阻信息写入DB中
 *
 * @param[in]  J1939Msg* J1939_PAGED msg 接收消息信息
 * @param[in]  uint8_t bcuIndex 接收BCU消息的设备ID索引，从0开始
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-19            Create             \n
 * 2023-05-11            增加消息解压缩功能             \n
 * 2023-05-17            修正内阻的压缩的PF值             \n
 * 2023-07-21            修正解压缩时传入压缩内容的长度及解压后存放数组大小             \n
 * 2023-09-13            修正详细非压缩处理            \n
 */
Std_Ret_Type J1939MasterRecvMsg_InnerResAnalysis(J1939Msg* J1939_PAGED msg,uint8_t bcuIndex)
{
    Std_Ret_Type ret = Std_Ret_OK;
    uint8_t pf = 0u;
    uint16_t batInnerRes[J1939_CAN_BAU_MAX_RX_DOUBLE_BYTE_NUM] = {0u};
    EMS_DEV_REG_DATA_S regData = {0};
    int32_t tmpMsgLen = 0;
    uint32_t Offset = 0;
    uint16_t bankId = 0,rackId = 0;
    if(msg == NULL || msg->msg_len <= 0)
    {
        return Std_Ret_ERR;
    }
    pf = (uint8_t)((msg->pgn >> 8) & 0xffu);
    if(pf == BMS_J1939_P_LEVEL6_CELL_INTERNAL_RESISTANCE_INFO_COMPRE_BASIC_ADDR)
    {
        /*需要对消息进行解压缩*/
        Compress_DeCode(&msg->data[0], (msg->msg_len - 1), (int16_t*)&batInnerRes[0],&tmpMsgLen);
        msg->msg_len = MIN(tmpMsgLen,(RESISTANCE_NUM_IN_ONE_CLUSTER));
        J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
    }
    else
    {
        /*将电池内阻写入DB中*/
        Offset = (msg->data[1]<<8) | msg->data[0];
        msg->msg_len /= 2u;
        msg->msg_len -= 1u;
        if(Offset >= RESISTANCE_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = 0;
            return Std_Ret_ERR;
        }
        else if((Offset + msg->msg_len) >= RESISTANCE_NUM_IN_ONE_CLUSTER)
        {
            msg->msg_len = RESISTANCE_NUM_IN_ONE_CLUSTER - Offset;
            J1939MasterRecvMsg_UpdateRecvRackDetailState(bcuIndex);
        }
        else
        {
            /**/
        }
        memcpy(batInnerRes,&msg->data[2],(msg->msg_len*2));
    }

    bmser_dev_calcBankIdAndRackIdByDevId(bcuIndex,&bankId,&rackId);
    regData.bankId = bankId;
    regData.rackId = rackId;
    regData.regCount = (unsigned short)msg->msg_len;
    regData.len = regData.regCount*2;
    convertArrayToLittleEndian(&batInnerRes[0], regData.regCount);
    regData.data = (uint8_t*)&batInnerRes[0];
    regData.startAddr = BMS_RESISTANCE_SUBOBJ_ID_1 + Offset;
    BmserProtocolExt_UpdateRegisterDb(&regData);
    return ret;

}

/*!
 * @brief      定时读取主控中的接收的J1939信息(调用频率越快越好,多包功能)
 *
 * @param[in]   void
 * @return      Std_Ret_Type
 * @retval      Std_Ret_OK：获取成功，Std_Ret_ERR：获取失败
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-04-18           Create             \n
 * 2023-5-5             修正总主通信支持2路CAN通信             \n
 */
Std_Ret_Type J1939MasterRecvMsg_TpMsgReceive(void)
{
    uint32_t i = 0u; 
    uint8_t pf = 0u,bcuIdIndex = 0u;
    Std_Base_Type canIdIndex = 0;
    Std_Ret_Type ret = Std_Ret_OK;

    for(canIdIndex = 0;canIdIndex < CAN_OBJ_ID_MAX;canIdIndex++)
    {
        if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
        {
            continue;
        }
        if(J1939_RxMsg(&g_pJ1939MsgProcessStru[canIdIndex]->J1939Context, &g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg) == J1939_OK)
        {
            /*对j1939协议的合法性判断*/
            if((g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg.id.Bits.R) != J1939_R_J1939)
            {
                return Std_Ret_ERR;
            }
            /*判断下消息来源的合法性*/
            if((g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg.id.Bits.PS - J1939_PDU_BAU_ADDR) != 1)
            {
                /*不是本设备地址*/
                return Std_Ret_ERR;
            }
            bcuIdIndex = g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg.id.Bits.SA - J1939_PDU_BCUx_DEF_ADDR;
            pf = (uint8_t)((g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg.pgn >> 8) & 0xffu);
            for(i = 0u;i < J1939_DETAIL_INFO_TYPE_NUM ;i++)
            {
                if(pf == g_pJ1939MsgAnalysisStru[i].pf)
                {
                    if(g_pJ1939MsgAnalysisStru[i].j1939MsgAnalysisFunc != NULL)
                    {
                        ret = g_pJ1939MsgAnalysisStru[i].j1939MsgAnalysisFunc(&g_pJ1939MsgProcessStru[canIdIndex]->J1939RxMsg,bcuIdIndex);
                    }
                    break;
                }
            }  
        }
        else
        {
            // XXX: 这里不能直接return error，会造成第二路can无法更新共享内存
            continue;
        }
    }

    return ret;
}

/*!
 * @brief       定时读取主控中的接收的J1939信息与J1939定时会话轮询(调用频率越快越好)
 *
 * @param[in]   void
 * @return      void
 * @retval      None
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-4-28           Create             \n
 *
 */
void J1939RecvMsg_TpSession_Runnable (void)
{
    int32_t i = 0,tmpMaxSendFrameNum = 1,canIdIndex = 0;
    
    for(canIdIndex = 0;canIdIndex < CAN_OBJ_ID_MAX;canIdIndex++)
    {
        if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
        {
            continue;
        }
        if(tmpMaxSendFrameNum < (int16_t)g_pJ1939MsgProcessStru[canIdIndex]->maxSendFrameNumOneTime)
        {
            tmpMaxSendFrameNum = (int16_t)g_pJ1939MsgProcessStru[canIdIndex]->maxSendFrameNumOneTime;
        }
    }
    for(i = 0;i < tmpMaxSendFrameNum;i++)
    {
        J1939MasterRecvMsg_TpSession();
        J1939MasterRecvMsg_TpMsgReceive();
    }
}

/*!
 * @brief       获取多帧传输时数据发送状态
 *
 * @param[in]   int32_t canIdIndex
 * @return      TpStatus
 * @retval      TpStatus
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-8-16    jyg      Create             \n
 *
 */
TpStatus J1939MasterRecvMsg_GetTpRecvState(int32_t canIdIndex)
{ 
    if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
    {
        return kTp_IDLE;
    }
    return g_pJ1939MsgProcessStru[canIdIndex]->J1939Context.tp_rx_session[0].status;
}

/*!
 * @brief       获取接收详细信息的标志
 *
 * @param[in]   int32_t canIdIndex
 * @return      Std_Bool_Enum
 * @retval      uint64_t bit0~Bit63 每一位代表一簇，该位置1，则说明该簇接收完毕
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-9-5    jyg      Create             \n
 *
 */
uint64_t J1939MasterRecvMsg_GetRecvDetailInfoFlag(int32_t canIdIndex)
{ 
    if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
    {
        return Std_False;
    }
    return g_pJ1939MsgProcessStru[canIdIndex]->isRecvDetailInfoFlag;
}


/*!
 * @brief       清除接收详细信息的标志
 *
 * @param[in]   int32_t canIdIndex
 * @return      Std_Ret_Type
 * @retval      Std_Ret_ERR:重置失败 Std_Ret_OK:重置成功
 *
 * @par         modify    log
 * Date        Author     Description             \n
 * 2023-9-5    jyg      Create             \n
 *
 */
Std_Ret_Type J1939MasterRecvMsg_ResetRecvDetailInfoFlag(int32_t canIdIndex)
{ 
    if(g_pJ1939MsgProcessStru[canIdIndex] == NULL)
    {
        return Std_Ret_ERR;
    }
    g_pJ1939MsgProcessStru[canIdIndex]->isRecvDetailInfoFlag = 0;
    
    return Std_Ret_OK;
}

long long J1939Get_recvTime(int32_t devid)
{
    return g_recvTime[devid];
}