/*
 * Area.c
 *
 *  Created on: 2025年12月2日
 *      Author: adan
 */
#include "CM_Types.h"
#include "CM_Memory.h"
#include "CM_Socket.h"
#include "CM_UDP.h"
#include "CM_Convert.h"
#include "PFM_Cfg.h"
#include "CM_Sem.h"
#include "CM_MultiThread.h"
#include "CM_MultiThread_Priority.h"
#include "CM_Time.h"
#include "DFM_Time.h"
#include "MSCP_Define.h"
#include "PFM_LOG.h"
#include "Area.h"
#include "DFM_Time.h"
#include "CM_CRC32.h"
#include "Area_2oo2.h"
#include "CFM_Sync.h"
#include "OFM_Base.h"

#define MSCP_MSG_AREA_ARQ_TYPE 0x01  /**< 区域通信请求消息类型 */
#define MSCP_MSG_AREA_RSP_TYPE 0x02  /**< 区域通信响应消息类型 */
#define MSCP_MSG_DEST_ALL 0xFF  /**< 所有设备接收消息类型 */

#define AREA_TIME_MAX  30u

typedef struct
{ 
    CM_UINT8 BoardID;  /**< 板卡ID 插箱id */
    CM_UINT8 Cpuid;  /**< cpu id */
    CM_UINT8 Partner_BoardID;  /**< 对系板卡id */
    CM_UINT8 Partner_Area_A_BoardID;  /**< 对系id */
    CM_UINT8 Partner_Area_B_BoardID;  /**< 对系id */
    STR_Area_IP_Cfg IP_Cfg_Area_A;  /**< IP配置 */
    STR_Area_IP_Cfg IP_Cfg_Area_B;  /**< IP配置 */
}STR_Area_Cfg;

typedef struct
{
    CM_UINT32 *Area_init; /* 初始化函数指针 */
    CM_UINT32 *get_Area_state; /* 获取区域状态函数指针 */
    CM_UINT32 *set_Area_state;  /* 设置区域状态函数指针 */
    STR_Area_Cfg Area_Cfg;  /**< 区域配置 */
    CM_SEM_T m_AreaStart;  /* 区域开始信号量 */
    CM_SEM_T m_AreaStop;  /* 区域停止信号量 */

}STR_Area_Ctl;

STR_Area_State g_Area_State ;

void Area_init();
static void Area_Net_init();
static void Area_Send_Req();
static void Prepare_for_Area_Data();
void Area_Msg_Recv(STR_Area_IP_Cfg *pCtrl,CM_UINT8 *p_buf, CM_UINT16 *p_len, CM_UINT16 BufSize);
void set_Area_Net_Status(CM_UINT8 index, CM_UINT8 state);
void Area_Req_Process(STR_Area_Req *p_Area_Req_tmp);
void clear_Area_ALL_Net_Status();
void Area_Rsp_Process(STR_Area_Req *p_Area_Req_tmp, CM_UINT8 net);
void Area_Data_Exchange();
void Area_Recv_Rsp();
void Area_Data_Pack(CM_UINT8 *p_buf, CM_UINT16 *p_len, CM_UINT16 bufsize);
void net_state_cal();
/**
 * @brief 区域通信请求组包
 *
 * @param p_Area_Req 指向区域通信请求结构体的指针
 * @param p_buf 指向区域通信请求存储的指针
 * @param BufSize 区域通信请求存储缓冲区大小
 * @param p_len 指向区域通信请求长度的指针
 */
void Area_Req_Pack(STR_Area_Req *p_Area_Req, CM_UINT8 *p_buf, CM_UINT16 BufSize, CM_UINT16 *p_len);


STR_Area_State_Ctl g_Area_Status_Ctl[8] = {0};
static STR_Area_Ctl g_Area_Ctl ={0};



static CM_THREAD_FUNC_T Area_Work_Thread(IN CM_Thread_Arg_Struct_T* arg);

void Area_init()
{
    /* 初始化函数指针*/

    g_Area_Ctl.Area_Cfg.BoardID = g_PFM_Cfg.BOARD_ID;/**<  板卡ID 插箱id */
    g_Area_Ctl.Area_Cfg.Cpuid = g_PFM_Cfg.CPU_ID;/**<  cpu id */
    /* 设置区域id*/
    if((MSCP_AREA_A_BOARD_ID_A == g_Area_Ctl.Area_Cfg.BoardID ) || (MSCP_AREA_A_BOARD_ID_B == g_Area_Ctl.Area_Cfg.BoardID ))
    {
    	g_Area_Status_Ctl[g_Area_Ctl.Area_Cfg.BoardID].Area_ID = MSCP_AREA_ID_A;
    	g_Area_4x_Ctl.Area_ID = MSCP_AREA_ID_A;
    }
    else
    {
    	g_Area_Status_Ctl[g_Area_Ctl.Area_Cfg.BoardID].Area_ID = MSCP_AREA_ID_B;
    	g_Area_4x_Ctl.Area_ID = MSCP_AREA_ID_B;
    }

    /* 获取对系、对地板卡id*/
    get_Other_BoardId(g_Area_Ctl.Area_Cfg.BoardID, &g_Area_Ctl.Area_Cfg.Partner_BoardID, &g_Area_Ctl.Area_Cfg.Partner_Area_A_BoardID, &g_Area_Ctl.Area_Cfg.Partner_Area_B_BoardID);
    
    CM_Memset(&g_Area_State, 0 , sizeof(STR_Area_State), sizeof(STR_Area_State));
    /** 初始化区域网络配置 */
    Area_Net_init();
    /** 初始化区域信号量 */
    CM_Sem_Init(&g_Area_Ctl.m_AreaStart);
    CM_Sem_Init(&g_Area_Ctl.m_AreaStop);

    /**创建区域通信线程 */
    CM_Thread_Create(NULL, (CM_THREAD_FUNC_T)Area_Work_Thread, "Area_Work_Thread", 4096*100, CM_TASK_PRIORITY_73, NULL);
}

void get_Other_BoardId(CM_UINT8 local_Board_Id, CM_UINT8 *partner_Board_Id, CM_UINT8 *partner_Area_A_Board_Id, CM_UINT8 *partner_Area_B_Board_Id)
{
    if(NULL == partner_Board_Id || NULL == partner_Area_A_Board_Id || NULL == partner_Area_B_Board_Id)
    {

    }
    else 
    {
        switch(local_Board_Id)
        {
            case MSCP_AREA_A_BOARD_ID_A:
                *partner_Board_Id = MSCP_AREA_A_BOARD_ID_B;
                *partner_Area_A_Board_Id = MSCP_AREA_B_BOARD_ID_A;
                *partner_Area_B_Board_Id = MSCP_AREA_B_BOARD_ID_B;
                break;
            case MSCP_AREA_A_BOARD_ID_B:
                *partner_Board_Id = MSCP_AREA_A_BOARD_ID_A;
                *partner_Area_A_Board_Id = MSCP_AREA_B_BOARD_ID_A;
                *partner_Area_B_Board_Id =  MSCP_AREA_B_BOARD_ID_B;
                break;
            case MSCP_AREA_B_BOARD_ID_A:
                *partner_Board_Id = MSCP_AREA_B_BOARD_ID_B;
                *partner_Area_A_Board_Id = MSCP_AREA_A_BOARD_ID_A;
                *partner_Area_B_Board_Id = MSCP_AREA_A_BOARD_ID_B;
                break;
            case MSCP_AREA_B_BOARD_ID_B:
                *partner_Board_Id = MSCP_AREA_B_BOARD_ID_A;
                *partner_Area_A_Board_Id = MSCP_AREA_A_BOARD_ID_A;
                *partner_Area_B_Board_Id =  MSCP_AREA_A_BOARD_ID_B;
                break;
            default:
                break;

        }
    
    }
}
/**
 * @brief 初始化区域网络配置
 * 
 */
static void Area_Net_init()
{
    ENUM_CM_RETURN rt = ENUM_CM_TRUE;/**<  返回值 */
    CM_INT32 val = 0;
    CM_BOOL rtCheck = 0;
    Area_2oo2_Init();
    /*- 初始化板卡id等信息*/
    g_Area_Ctl.Area_Cfg.BoardID = g_PFM_Cfg.BOARD_ID;/**<  板卡ID 插箱id */
    g_Area_Ctl.Area_Cfg.Cpuid = g_PFM_Cfg.CPU_ID;/**<  cpu id */

    /** 获取区域网络A配置 */
    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_Area,32);/**<  本地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner, 32, g_PFM_Cfg.Partner_Cfg.IP_Area,32);/**<  对系通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    
    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_A, 32, g_PFM_Cfg.Partner_Area_A_Cfg.IP_Area,32);/**<  对地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_B, 32, g_PFM_Cfg.Partner_Area_B_Cfg.IP_Area,32);/**<  对地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

     g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port = g_PFM_Cfg.Local_Cfg.Port_Area_State;/**<  端口号 */

     rt = Area_LogMQ_Init();
     CM_ASSERT(ENUM_CM_TRUE == rt, 0,0,0);

     AREA_LOG_MSG("nat a cfg %s, %s %s %s \r\n",g_PFM_Cfg.Local_Cfg.IP_Area, g_PFM_Cfg.Partner_Cfg.IP_Area,
    		 g_PFM_Cfg.Partner_Area_A_Cfg.IP_Area, g_PFM_Cfg.Partner_Area_B_Cfg.IP_Area);
    /** 初始化区域网络套接字 */
    /*- 创建socket */
    rt = CM_UDP_Socket_Create(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, CM_FALSE, (CM_UINT32)inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Local), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port, 0u, (CM_UINT8)1);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    val = (CM_INT32)NET_UDP_BUF_MAX;
    (void)setsockopt(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));

    /*初始化消息队列*/
    rt = CM_MQ_Init(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.MsgQ, (CM_UINT16)Area_MSG_NUM_MAX, (CM_UINT16)Area_RAW_MSG_SIZE);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    /*创建udp 接收线程*/
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_UdpRecvThread, "Area_Rx_A", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);


     /** 获取区域网络B配置 */
    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_4x2,32);/**<  本地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner, 32, g_PFM_Cfg.Partner_Cfg.IP_4x2,32);/**<  对系通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    
    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner_Area_A, 32, g_PFM_Cfg.Partner_Area_A_Cfg.IP_4x2,32);/**<  对地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rt = CM_Memcpy(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner_Area_B, 32, g_PFM_Cfg.Partner_Area_B_Cfg.IP_4x2,32);/**<  对地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port = g_PFM_Cfg.Local_Cfg.Port_Area_State;/**<  端口号 */

    AREA_LOG_MSG("nat b cfg %s, %s %s %s \r\n",g_PFM_Cfg.Local_Cfg.IP_4x2, g_PFM_Cfg.Partner_Cfg.IP_4x2,
   		 g_PFM_Cfg.Partner_Area_A_Cfg.IP_4x2, g_PFM_Cfg.Partner_Area_B_Cfg.IP_4x2);

    /** 初始化区域网络套接字 */
    /*- 创建socket */
    rt = CM_UDP_Socket_Create(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, CM_FALSE, (CM_UINT32)inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Local), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port, 0u, (CM_UINT8)1);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    val = (CM_INT32)NET_UDP_BUF_MAX;
    (void)setsockopt(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));

    /*初始化消息队列*/
    rt = CM_MQ_Init(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.MsgQ, (CM_UINT16)Area_MSG_NUM_MAX, (CM_UINT16)Area_RAW_MSG_SIZE);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    /*创建udp 接收线程*/
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_UdpRecvThread, "Area_Rx_B", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);
}

/**
 * @brief 获取区域状态
 *
 * @return ENUM_Area_State 区域状态
 */
ENUM_AREA_STATE Area_Get_State()
{
	return g_Area_4x_Ctl.Local_state;
}

/**
 * @brief 获取区域状态
 *
 * @return ENUM_Area_State 区域状态
 */
ENUM_AREA_STATE Area_Get_Partner_State()
{
	return g_Area_4x_Ctl.Partner_state;
}

void Area_Get_All_State(STR_Area_State *p_all_State)
{
	if(NULL == p_all_State)
	{

	}
	else
	{
		p_all_State->Local_state   =  g_Area_4x_Ctl.Local_state;
		p_all_State->Partner_state =  g_Area_4x_Ctl.Partner_state;
		p_all_State->Partner_Area_A_state =  g_Area_4x_Ctl.Partner_Area_A_state;
		p_all_State->Partner_Area_B_state =  g_Area_4x_Ctl.Partner_Area_B_state;
	}

}

/**
 * @brief 设置区域状态
 *
 * @param State 区域状态
 */
void Area_Set_State(ENUM_AREA_STATE State)
{
	g_Area_4x_Ctl.Local_state = State;
}


/**
 * @brief 区域开始
 * 
 */
void Area_Start()
{
    /** 区域开始信号量 */
    CM_Sem_Post(g_Area_Ctl.m_AreaStart);
    AREA_LOG_MSG("*** Area thread star \n");
}
/**
 * @brief 等待区域开始
 * 
 */
void Area_Wait_Start()
{
    /** 区域开始信号量 */
    CM_Sem_Wait(g_Area_Ctl.m_AreaStart);
}

/**
 * @brief 区域停止
 * 
 */
void Area_Stop()
{
    /** 区域停止信号量 */
    CM_Sem_Post(g_Area_Ctl.m_AreaStop);
}
/**
 * @brief 等待区域停止
 * 
 */
void Area_Wait_Stop()
{
    /** 区域停止信号量 */
    CM_Sem_Wait(g_Area_Ctl.m_AreaStop);
}

/**
 * @brief 创建区域工作线程
 * 
 * @return CM_UINT32 
 */
static CM_THREAD_FUNC_T Area_Work_Thread(IN CM_Thread_Arg_Struct_T* arg)
{
   // STR_Area_Ctl *p_Area_Ctl = (STR_Area_Ctl *)arg;
    /**todo 设置线程cpu亲和力 */
    CM_UINT32 cpu_mask = 0;
    /*- 本线程锁定在 A53 core 1 */
    cpu_mask = (0x04u);
    set_thread_affinity(cpu_mask);
	/**  清空 队列 */
	CM_MQ_Clear(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.MsgQ);
	CM_MQ_Clear(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.MsgQ);
	CM_INT64 tick = 0;
    while(1)
    {
        /** 区域开始信号量 */
        Area_Wait_Start();
        /**< 延时等待100ms */
        CM_Sleep(200);
        tick = CM_GetTick();
        AREA_LOG_MSG("#### area start  time = %lld####\r\n",tick / 1000000);
        /**<  2oo2 交互区域状态 和主备系同步标识 以及AB 网状态*/
        Prepare_for_Area_Data();
        AREA_LOG_MSG("#### Prepare_for_Area_Data  ####\r\n");
        /*清除上周期网络状态*/
        clear_Area_ALL_Net_Status();

        /**< 发送区域通信请求 */
        Area_Send_Req();
        AREA_LOG_MSG("#### Area_Send_Req  %llu ####\r\n",CM_GetTick()/1000000);
        /*读队列处理数据  读取20ms 超时后退出*/

         /**< 接收区域通信应答 */
        Area_Recv_Rsp();
        AREA_LOG_MSG("#### Area_Recv_Rsp  ####\r\n");
        /**2oo2 交互接收数据 更新网络状态*/
        Area_Data_Exchange();
        /*主备地表决*/
        Area_vote(&g_Area_Status_Ctl[0], g_Area_Ctl.Area_Cfg.BoardID);
        AREA_LOG_MSG("#### area end state %d usetime = %lld####\r\n", g_Area_4x_Ctl.Local_state, (CM_GetTick() - tick) / 1000000);
        /** 区域停止信号量 */
        Area_Stop();
    }

    return 0;
}


void updata_Local_State()
{
	CM_UINT32 Local_BoardId = 0;
    CM_UINT32 Partner_BoardId = 0;
    CM_UINT32 Area_A_BoardID = 0;
    CM_UINT32 Area_B_BoardID = 0;
    Local_BoardId =  g_Area_Ctl.Area_Cfg.BoardID;

    get_Other_BoardId(Local_BoardId, &Partner_BoardId, &Area_A_BoardID, &Area_B_BoardID);
    AREA_LOG_MSG("board %d %d %d %d \r\n", Local_BoardId, Partner_BoardId, Area_A_BoardID, Area_B_BoardID);
    AREA_LOG_MSG("g_Area_Status_Ctl state  %d %d %d %d \r\n", g_Area_Status_Ctl[Local_BoardId].Area_Req.Localstate, g_Area_Status_Ctl[Partner_BoardId].Area_Req.Localstate,
    		g_Area_Status_Ctl[Area_A_BoardID].Area_Req.Localstate, g_Area_Status_Ctl[Area_B_BoardID].Area_Req.Localstate);
	g_Area_4x_Ctl.Partner_state = g_Area_Status_Ctl[Partner_BoardId].Area_Req.Localstate;
	g_Area_4x_Ctl.Partner_Area_A_state = g_Area_Status_Ctl[Area_A_BoardID].Area_Req.Localstate;
	g_Area_4x_Ctl.Partner_Area_B_state = g_Area_Status_Ctl[Area_B_BoardID].Area_Req.Localstate;

	/*更新网络健康度*/
	net_state_cal();

}


void net_state_cal()
{
	CM_UINT16 index = 0;

	for(index = 1; index <= MSCP_AREA_DEVICE_MAX; index ++)
	{
		g_Area_Status_Ctl[index].Net_Health = 0;
		if(MSCP_AREA_NET_FILD == g_Area_Status_Ctl[index].Local_Net_A_state)
		{
			g_Area_Status_Ctl[index].Local_Net_A_state_ErrCnt ++;
		}
		else
		{
			g_Area_Status_Ctl[index].Local_Net_A_state_ErrCnt = 0;
			g_Area_Status_Ctl[index].Net_Health++;
		}

		if(MSCP_AREA_NET_FILD == g_Area_Status_Ctl[index].Local_Net_B_state)
		{
			g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt ++;
		}
		else
		{
			g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt = 0;
			g_Area_Status_Ctl[index].Net_Health++;
		}

		if(MSCP_AREA_NET_FILD == g_Area_Status_Ctl[index].Peer_Net_A_state)
		{
			g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt ++;
		}
		else
		{
			g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt = 0;
			g_Area_Status_Ctl[index].Net_Health++;
		}

		if(MSCP_AREA_NET_FILD == g_Area_Status_Ctl[index].Peer_Net_B_state)
		{
			g_Area_Status_Ctl[index].Peer_Net_B_state_ErrCnt ++;
		}
		else
		{
			g_Area_Status_Ctl[index].Peer_Net_B_state_ErrCnt = 0;
			g_Area_Status_Ctl[index].Net_Health++;
		}
		/*
		 * 判断4线是否同时中断，通过判断未收到数据计数判断
		 * 任意3个数据相等或者4个数据相等，则认为通信是ok的，
		 * 否则认为非同时通信中断。此处无容忍，一周期断则认为是断
		 * 公式如下：
		 *  if ((A == B && B == C) ||
			(A == B && B == D) ||
			(A == C && C == D) ||
			(B == C && C == D))
		 * */
		 if ((g_Area_Status_Ctl[index].Local_Net_A_state_ErrCnt == g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt
		   && g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt == g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt)

		   ||(g_Area_Status_Ctl[index].Local_Net_A_state_ErrCnt == g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt
		   && g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt == g_Area_Status_Ctl[index].Peer_Net_B_state_ErrCnt)

		   ||(g_Area_Status_Ctl[index].Local_Net_A_state_ErrCnt == g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt
		   && g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt == g_Area_Status_Ctl[index].Peer_Net_B_state_ErrCnt)

		   ||(g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt == g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt
		   && g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt == g_Area_Status_Ctl[index].Peer_Net_B_state_ErrCnt))
		 {
			 g_Area_Status_Ctl[index].Net_ERR_FLAG = MSCP_AREA_NET_SYNC_ERR_FLAG;
		 }
		 else
		 {
			 g_Area_Status_Ctl[index].Net_ERR_FLAG = MSCP_AREA_NET_ASYNC_ERR_FLAG;
		 }

		 AREA_LOG_MSG("board index %d  health %d recverr lo_A %d Lo_B %d peer_a %d peer_B %d\r\n",index,g_Area_Status_Ctl[index].Net_Health,
				 g_Area_Status_Ctl[index].Local_Net_A_state_ErrCnt, g_Area_Status_Ctl[index].Local_Net_B_state_ErrCnt
				 ,g_Area_Status_Ctl[index].Peer_Net_A_state_ErrCnt, g_Area_Status_Ctl[index].Peer_Net_B_state_ErrCnt);

	}
}

void Area_Data_Exchange()
{

    CM_UINT8 sendbuf[MSCP_MSG_BUF_MAX] = {0};
    CM_UINT8 recvbuf[MSCP_MSG_BUF_MAX] = {0};
    CM_UINT16 send_len = 0;
    CM_UINT16 recvLen = 0;
	CM_UINT16 index = 0;
	CM_UINT16 idx = 0;
	STR_Area_Req Area_Req_tmp = {0};
    /*数据打包*/
    Area_Data_Pack(&sendbuf[0], &send_len, MSCP_MSG_BUF_MAX);
	   /**2oo2 交互 */

	recvLen = Area_2oo2_Currency_NoSplit(&sendbuf[0], send_len, &recvbuf[0], MSCP_MSG_BUF_MAX);
	if(recvLen > 0)
	{
		/** 解析2oo2 数据 */
		idx = 0;
		for(index = 1; index <= MSCP_AREA_DEVICE_MAX; index ++)
		{
			g_Area_Status_Ctl[index].Peer_Net_A_state = recvbuf[idx];
			idx += 1;
			g_Area_Status_Ctl[index].Peer_Net_B_state = recvbuf[idx];
			idx += 1;

			CM_Memcpy(&Area_Req_tmp, sizeof(STR_Area_Req), &recvbuf[idx],sizeof(STR_Area_Req));
			AREA_LOG_MSG("Peer_Net_A_state %d  %d \r\n",g_Area_Status_Ctl[index].Peer_Net_A_state,g_Area_Status_Ctl[index].Peer_Net_B_state);

			AREA_LOG_MSG("2oo2 state arq %d local arq %d state %d %d index %d \r\n",Area_Req_tmp.arqCount, g_Area_Status_Ctl[index].Area_Req.Localstate,g_Area_Status_Ctl[index].Area_Req.arqCount, Area_Req_tmp.Localstate, index);

			if(Area_Req_tmp.arqCount > g_Area_Status_Ctl[index].Area_Req.arqCount)
			{
				 g_Area_Status_Ctl[index].Area_Req = Area_Req_tmp;
			}
			else
			{

			}
			idx += sizeof(STR_Area_Req);
		}
	}
	/*更新状态 */
    updata_Local_State();

}

/*
 * 区域状态数据打包*/
void Area_Data_Pack(CM_UINT8 *p_buf, CM_UINT16 *p_len, CM_UINT16 bufsize)
{
	CM_UINT16 index = 0;
	CM_UINT16 idx = 0;
	if((NULL == p_buf) && (NULL == p_len))
	{

	}
	else
	{
		for(index = 1; index <= MSCP_AREA_DEVICE_MAX; index ++)
		{
			p_buf[idx] = g_Area_Status_Ctl[index].Local_Net_A_state;
			idx++;
			p_buf[idx] = g_Area_Status_Ctl[index].Local_Net_B_state;
			idx++;
			CM_Memcpy(&p_buf[idx] ,bufsize - idx , &g_Area_Status_Ctl[index].Area_Req ,sizeof(STR_Area_Req));

//			MSCP_LOG_MSG("!!![0x%x] [0x%x] [0x%x] [0x%x] [0x%x] [0x%x] [0x%x] [0x%x]\r\n", sizeof(STR_Area_Req), g_Area_Status_Ctl[index].Area_Req.Localstate,
//					g_Area_Status_Ctl[index].Area_Req.msgType, g_Area_Status_Ctl[index].Area_Req.arqCount,
//					g_Area_Status_Ctl[index].Area_Req.srcId, g_Area_Status_Ctl[index].Area_Req.destId,
//					g_Area_Status_Ctl[index].Area_Req.Localstate,g_Area_Status_Ctl[index].Area_Req.crc1);


			idx+= sizeof(STR_Area_Req);
		}
		*p_len = idx;
	}


}


/**
 * @brief 准备区域数据
 * 
 */
static void Prepare_for_Area_Data()
{
    CM_UINT16 index = 0;
    CM_UINT8 idx = 0;
    CM_UINT16 index_tmp = 0;
    CM_UINT8 cpuid = 0;
    CM_UINT32 crc = 0;
    CM_UINT32 recvLen = 0;
    CM_UINT8 sendbuf[MSCP_MSG_BUF_MAX] = {0};
    CM_UINT8 recvbuf[MSCP_MSG_BUF_MAX] = {0};
    cpuid = g_Area_Ctl.Area_Cfg.Cpuid;
    index = g_Area_Ctl.Area_Cfg.BoardID;

    /*清空所有全局变量的状态，*/
	for(index_tmp = 1; index_tmp <= MSCP_AREA_DEVICE_MAX; index_tmp ++)
	{
		CM_Memset(&g_Area_Status_Ctl[index_tmp].Area_Req, 0, sizeof(STR_Area_Req),sizeof(STR_Area_Req));
		g_Area_Status_Ctl[index_tmp].Area_Req.Localstate = ENUM_AREA_SHUTDOWN;
	}

	g_Area_Status_Ctl[index].Area_Req.Localstate = g_Area_4x_Ctl.Local_state;
    g_Area_4x_Ctl.sync_finish_flag = CFM_GetSyncHealth();
    /*同步失败标志*//*todo 此标志位为输出比较失败标志，已经完成2oo2交互，此处可以不交互，如果双cpu不一致，需要交互此标志位*/
    g_Area_4x_Ctl.Sync_Fail_Flag = CFM_GetSyncFailFlag();

    sendbuf[idx] =  g_Area_4x_Ctl.Local_state;
    idx += 1;
    sendbuf[idx] =  g_Area_4x_Ctl.sync_finish_flag;
    idx += 1;
    sendbuf[idx] =  g_Area_Status_Ctl[index].Local_Net_A_state;
    idx += 1;
    sendbuf[idx] =  g_Area_Status_Ctl[index].Local_Net_B_state;
    idx += 1;
   

    /**2oo2 交互 */
    AREA_LOG_MSG("#### first 2oo2  ####\r\n");
    recvLen = Area_2oo2_Currency_NoSplit(&sendbuf[0], idx , &recvbuf[0], MSCP_MSG_BUF_MAX);
    if(recvLen > 0)
    {
        /** 解析2oo2 数据 */
        idx = 0;
        g_Area_Status_Ctl[index].Area_Req.Localstate = g_Area_4x_Ctl.Local_state & recvbuf[idx];
        idx += 1;
        g_Area_Status_Ctl[index].Area_Req.sync_finish_flag = g_Area_4x_Ctl.sync_finish_flag & recvbuf[idx];
        idx += 1;
        g_Area_Status_Ctl[index].Peer_Net_A_state = recvbuf[idx];
        idx += 1;
        g_Area_Status_Ctl[index].Peer_Net_B_state = recvbuf[idx];
        idx += 1;
    }

    idx = 0;

    sendbuf[idx] =  g_Area_Status_Ctl[index].Area_Req.Localstate;
    idx += 1;
    CM_LongToChar(g_Area_Status_Ctl[index].Area_Req.sync_finish_flag, &sendbuf[idx]);
    idx += 4;
    if(1 == cpuid)
    {
        crc = CM_Crc32_1(&sendbuf[0], idx);
        g_Area_Status_Ctl[index].Area_Req.crc1 = crc;

    }
    else 
    {
        crc = CM_Crc32_2(&sendbuf[0], idx);
        g_Area_Status_Ctl[index].Area_Req.crc2 = crc;
    }
    AREA_LOG_MSG("Prepare_for_Area_Data crc 0x%x\r\n", crc);
    CM_LongToChar(crc, &sendbuf[idx]);
    idx += 4;
        /**2oo2 交互 */
    recvLen = Area_2oo2_Currency_NoSplit(&sendbuf[0], idx + 4, &recvbuf[0], MSCP_MSG_BUF_MAX);
    if(recvLen > 0)
    {
        /** 解析2oo2 数据 */
        idx = 5;
        AREA_LOG_MSG("Prepare_for_Area_Data peer_crc 0x%x\r\n", CM_LongFromChar(&recvbuf[idx]));
        if(1 == cpuid)
        {
            g_Area_Status_Ctl[index].Area_Req.crc2 = CM_LongFromChar(&recvbuf[idx]);
        }
        else 
        {
            g_Area_Status_Ctl[index].Area_Req.crc1 = CM_LongFromChar(&recvbuf[idx]);
        }
        
    }

}

/**
 * @brief 区域通信请求
 * 
 */

static void Area_Send_Req()
{
    CM_UINT16 index = 0;
    CM_UINT16 send_len = 0;
    
    index = g_Area_Ctl.Area_Cfg.BoardID;

    g_Area_Status_Ctl[index].Area_Req.len = sizeof(STR_Area_Req);
    g_Area_Status_Ctl[index].Area_Req.msgType = MSCP_MSG_AREA_ARQ_TYPE;
    g_Area_Status_Ctl[index].Area_Req.arqCount = DFM_GetBirthCount();
    g_Area_Status_Ctl[index].Area_Req.srcId = (g_Area_Ctl.Area_Cfg.BoardID); /*(g_Area_Ctl.Area_Cfg.BoardID << 16) + (g_Area_Ctl.Area_Cfg.Cpuid);*/
    g_Area_Status_Ctl[index].Area_Req.destId = MSCP_MSG_DEST_ALL;
    g_Area_Status_Ctl[index].Area_Req.Localstate = g_Area_4x_Ctl.Local_state;
    g_Area_Status_Ctl[index].Area_Req.sync_finish_flag = g_Area_4x_Ctl.sync_finish_flag;
//    g_Area_Status_Ctl[index].Area_Req.crc1 = 0;
//    g_Area_Status_Ctl[index].Area_Req.crc2 = 0;
    CM_Memset(&g_Area_Status_Ctl[index].Area_Req.reserver[0], 0, 8,sizeof(g_Area_Status_Ctl[index].Area_Req.reserver));
    g_Area_Status_Ctl[index].Area_Req.crc = 0;

    AREA_LOG_MSG("Send_Req LOCAL dtate %d sn %d \r\n",g_Area_Status_Ctl[index].Area_Req.Localstate, g_Area_Status_Ctl[index].Area_Req.arqCount);
    /** 区域通信请求组包 */
    CM_Memset(&g_Area_Status_Ctl[index].send_buf[0], 0, MSCP_MSG_BUF_MAX, MSCP_MSG_BUF_MAX);
    Area_Req_Pack(&g_Area_Status_Ctl[index].Area_Req, &g_Area_Status_Ctl[index].send_buf[0], MSCP_MSG_BUF_MAX, &send_len);

	/** 发送区域通信请求 */
	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);
	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port);

	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_A), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);
	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner_Area_A), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port);

	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_B), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);
	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner_Area_B), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port);

	AREA_LOG_MSG("Send_Req dest ip %s port %d \r\n",g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_A, g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);


}


/**
 * @brief 区域通信请求组包
 * 
 * @param p_Area_Req 指向区域通信请求结构体的指针
 * @param p_buf 指向区域通信请求存储的指针
 * @param BufSize 区域通信请求存储缓冲区大小
 * @param p_len 指向区域通信请求长度的指针
 */
void Area_Req_Pack(STR_Area_Req *p_Area_Req, CM_UINT8 *p_buf, CM_UINT16 BufSize, CM_UINT16 *p_len)
{
    CM_UINT32 idx = 0;/** buf 数组索引 */
    if((NULL == p_buf) && (BufSize < sizeof(STR_Area_Req)) && (NULL == p_len))
    {
        CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    }
    else 
    {

        /** 区域通信请求组包 */

    	/* 2字节长度 + 1个字节消息类型 + 8字节序列号  + 4字节源ID + 4字节目的ID + 1字节本机状态 + 4字节同步状态 + 4字节CRC1 + 4字节CRC2 + 8字节预留 + 4字节CRC*/
        idx = 0;
        CM_ShortToChar(p_Area_Req->len,&p_buf[idx]);
        idx += sizeof(CM_UINT16);

        p_buf[idx] = p_Area_Req->msgType;
        idx += sizeof(CM_UINT8);

        CM_LongToChar(p_Area_Req->arqCount,&p_buf[idx]);
        idx += sizeof(CM_UINT32);

        CM_LongToChar(p_Area_Req->srcId,&p_buf[idx]);       
        idx += sizeof(CM_UINT32);

        CM_LongToChar(p_Area_Req->destId,&p_buf[idx]);  
        idx += sizeof(CM_UINT32);

        p_buf[idx] = p_Area_Req->Localstate;
        idx += sizeof(CM_UINT8);

        CM_LongToChar(p_Area_Req->sync_finish_flag,&p_buf[idx]);
        idx += sizeof(CM_UINT32);

        CM_LongToChar(p_Area_Req->crc1,&p_buf[idx]);
        idx += sizeof(CM_UINT32);

        CM_LongToChar(p_Area_Req->crc2,&p_buf[idx]);
        idx += sizeof(CM_UINT32);

        CM_Memcpy(&p_buf[idx], sizeof(p_Area_Req->reserver), &p_Area_Req->reserver[0], sizeof(p_Area_Req->reserver));
        idx += sizeof(p_Area_Req->reserver);       

        p_Area_Req->crc = CM_Crc32((CM_UINT8 *)p_buf, idx);
        CM_LongToChar(p_Area_Req->crc,&p_buf[idx]);     
        idx += sizeof(CM_UINT32);   

        *p_len = idx;
        

    }

}

CM_UINT8 Area_Req_Unpack(STR_Area_Req *p_Area_Req, CM_UINT8 *p_buf, CM_UINT16 len)
{
    CM_UINT32 idx = 0;/** buf 数组索引 */
    CM_UINT32 crc = 0;
    CM_UINT32 buf_crc = 0;
    CM_UINT32 buf_len = 0;
    CM_UINT8  msg_Type = 0;
//    CM_UINT32  srcId = 0;
    CM_UINT32 crc1 = 0;
    CM_UINT32 crc2 = 0;
    CM_UINT8 rt = 0;
    if((NULL == p_buf) )
    {
         rt = 0;
        CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);  
    }
    else 
    {
        /** 区域通信请求解包 */
        idx = 0;
        /** 区域通信请求长度 */
        buf_len = CM_ShortFromChar(&p_buf[idx]);
        idx += sizeof(CM_UINT16);
        /** 区域通信请求校验和计算 */
        crc = CM_Crc32((CM_UINT8 *)p_buf, buf_len - 4);
        /** 区域通信请求校验和提取*/
        buf_crc = CM_LongFromChar(&p_buf[buf_len - 4]);
        /** 区域通信请求校验和校验 */
        if(crc != buf_crc)
        {
            CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
            rt = 0;
        }
        else 
        {

            p_Area_Req->len = buf_len;

            /** 获取区域通信请求消息类型 */
            msg_Type = p_buf[idx];
            idx += sizeof(CM_UINT8);
            p_Area_Req->msgType = msg_Type;

            /** 获取区域通信请求arqCount */
            p_Area_Req->arqCount = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);

            /** 获取区域通信请求srcId */
            p_Area_Req->srcId = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);
            /** 获取区域通信请求destId */       
            p_Area_Req->destId = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);
            /*校验双crc*/
            crc1 = CM_Crc32_1(&p_buf[idx],5);
            crc2 = CM_Crc32_2(&p_buf[idx],5);
            /** 获取区域通信请求Localstate */
            p_Area_Req->Localstate = p_buf[idx];
            idx += sizeof(CM_UINT8);
            /** 获取区域通信请求sync_finish_flag */
            p_Area_Req->sync_finish_flag = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);
            /** 获取区域通信请求crc1 */
            p_Area_Req->crc1 = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);
            /** 获取区域通信请求crc2 */ 
            p_Area_Req->crc2 = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);

            /** 获取区域通信请求reserver */
            CM_Memcpy(&p_Area_Req->reserver[0], sizeof(p_Area_Req->reserver), &p_buf[idx], sizeof(p_Area_Req->reserver));
            idx += sizeof(p_Area_Req->reserver);    
            p_Area_Req->crc = CM_LongFromChar(&p_buf[idx]);
            idx += sizeof(CM_UINT32);   

            if(MSCP_MSG_AREA_RSP_TYPE == msg_Type)
            {
                if((crc1 == p_Area_Req->crc1) && (crc2 == p_Area_Req->crc2))
                {
                	AREA_LOG_MSG("Area_Req_Unpack ok \r\n");
                	rt = 1;
                }
                else
                {
                	rt = 0;
                	AREA_LOG_MSG("Area_Req_Unpack double crc err srcid %d local_crc [0x%x][0x%x] crc [0x%x][0x%x]\r\n",p_Area_Req->srcId, crc1, crc2, p_Area_Req->crc1,p_Area_Req->crc2);
                	CM_Memset(p_Area_Req, 0 , sizeof(STR_Area_Req), sizeof(STR_Area_Req));
                }
            }
            else
            {
            	rt = 1;
            }




        }
        
    }
       return rt;

}


/**
 * @brief 区域通信应答
 * 
 */
 void Area_Recv_Rsp()
 {
    CM_UINT8 *p_buf = NULL;
    CM_UINT16 index = 0;
    CM_UINT16 recv_len = MSCP_MSG_BUF_MAX;
    CM_UINT8 i = 0;
    CM_UINT8 rt = 0;

    STR_Area_IP_Cfg *p_cfg[2] = {0};          /**临时变量 */
    STR_Area_Req Area_Req_tmp = {0}; /** 临时变量 */


    CM_UINT64 end_Time = 0;
    end_Time = CM_GetTick()/CM_MILLION + AREA_TIME_MAX;

    p_cfg[MSCP_AREA_NET_A] = &g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A;
    p_cfg[MSCP_AREA_NET_B] = &g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B;

    index = g_Area_Ctl.Area_Cfg.BoardID;
    CM_Memset(&g_Area_Status_Ctl[index].recv_buf[0], 0, MSCP_MSG_BUF_MAX, MSCP_MSG_BUF_MAX);
    p_buf = g_Area_Status_Ctl[index].recv_buf;
    if((NULL == p_buf) && (NULL == p_cfg))
    {

    }
    else
    {
    	AREA_LOG_MSG("st time %d ms \r\n",(CM_GetTick()/CM_MILLION));
    	while(end_Time > (CM_GetTick()/CM_MILLION))
    	{
    		CM_Sleep(2);
            for(i = 0; i < 2; i++)
            {
                do {
                	recv_len = MSCP_MSG_BUF_MAX;

                        /** udp 数据接收*/
                    Area_Msg_Recv(p_cfg[i], p_buf, &recv_len, MSCP_MSG_BUF_MAX);
                    if(recv_len > 0)
                    {
                    	CM_Memset(&Area_Req_tmp, 0,sizeof(Area_Req_tmp), sizeof(Area_Req_tmp));
                    	 rt = 0;

                    	/*设置本机通信状态*/
                    	set_Area_Net_Status(i, MSCP_AREA_NET_OK);

                        rt = Area_Req_Unpack(&Area_Req_tmp, p_buf, recv_len);
                        if(rt == 1)
                        {
                            if(Area_Req_tmp.msgType == MSCP_MSG_AREA_ARQ_TYPE)
                            {
                            	AREA_LOG_MSG("recv data ok i = %d ARQ\r\n",i );
                                /** 区域通信应答处理 */
                                Area_Req_Process(&Area_Req_tmp);
                            }
                            else if(Area_Req_tmp.msgType == MSCP_MSG_AREA_RSP_TYPE)
                            {
                            	AREA_LOG_MSG("recv data ok i = %d RSP\r\n",i );
                                /** 区域通信应答处理 */
                                Area_Rsp_Process(&Area_Req_tmp, i);
                            }
                            else
                            {

                            }
                        }
                    }
                    else
                    {
                        /** 无操作 */
                    }


                }while (recv_len > 0);

            }
    	}

    	AREA_LOG_MSG("end time %d ms %d ms\r\n",(CM_GetTick()/CM_MILLION), (CM_GetTick()/CM_MILLION) - end_Time);
    }
     

 }

/** @brief 区域通信请求处理
 * @param p_Area_Req_tmp 区域通信请求结构体指针
*/
void Area_Req_Process(STR_Area_Req *p_Area_Req_tmp)
{
    CM_UINT32 index = 0;
    CM_UINT32 srcid = 0;
    CM_UINT16 send_len = 0;
    CM_UINT8 *p_buf = NULL;
    CM_UINT16 recv_len = 0;
    /**获取板卡id作为管理结构体下标 */
    index = g_Area_Ctl.Area_Cfg.BoardID;
    srcid = p_Area_Req_tmp->srcId;
    p_buf = g_Area_Status_Ctl[index].send_buf;

	CM_UINT32 Partner_BoardId = 0;
	CM_UINT32 Area_A_BoardID = 0;
	CM_UINT32 Area_B_BoardID = 0;

    get_Other_BoardId(index, &Partner_BoardId, &Area_A_BoardID, &Area_B_BoardID);

    if((NULL == p_Area_Req_tmp) && (NULL == p_buf))
    {
        
    }
    else 
    {

        p_Area_Req_tmp->destId = srcid;
        p_Area_Req_tmp->srcId = g_Area_Status_Ctl[index].Area_Req.srcId;
        p_Area_Req_tmp->msgType = MSCP_MSG_AREA_RSP_TYPE;
        p_Area_Req_tmp->Localstate = g_Area_Status_Ctl[index].Area_Req.Localstate;
        p_Area_Req_tmp->sync_finish_flag = g_Area_Status_Ctl[index].Area_Req.sync_finish_flag;
        /** 区域通信应答crc1 */
        p_Area_Req_tmp->crc1 = g_Area_Status_Ctl[index].Area_Req.crc1;
        /** 区域通信应答crc2 */
        p_Area_Req_tmp->crc2 = g_Area_Status_Ctl[index].Area_Req.crc2;

        AREA_LOG_MSG("srcid %d sn %d crc [0x%x] [0x%x]\r\n",srcid,p_Area_Req_tmp->arqCount,g_Area_Status_Ctl[index].Area_Req.crc1, g_Area_Status_Ctl[index].Area_Req.crc2);
        /** 打包数据 */
        CM_Memset(p_buf, 0, MSCP_MSG_BUF_MAX, MSCP_MSG_BUF_MAX);
        Area_Req_Pack(p_Area_Req_tmp, p_buf, MSCP_MSG_BUF_MAX, &send_len);

        if(srcid == Partner_BoardId)
        {
            CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);
            CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port);
        }
        else if(srcid == Area_A_BoardID)
        {
            CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_A), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);
            CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner_Area_A), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port);


        }
        else if(srcid == Area_B_BoardID)
        {
        	CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.IP_Partner_Area_B), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.port);
            CM_UDP_Send_Msg(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.Socket, (CM_UINT8 *)&g_Area_Status_Ctl[index].send_buf[0], send_len, inet_addr(g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.IP_Partner_Area_B), g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.port);
        }



    }

}

/** 区域通信应答处理
 */
void Area_Rsp_Process(STR_Area_Req *p_Area_Req_tmp, CM_UINT8 net)
{
    CM_UINT32 index = 0;
    CM_UINT32 srcid = 0;
    CM_UINT32 local_SN = 0;
    if(NULL == p_Area_Req_tmp)
    {
       
    }
    else 
    {
        /**获取板卡id作为管理结构体下标 */
        index = g_Area_Ctl.Area_Cfg.BoardID;
        srcid = p_Area_Req_tmp->srcId;
        /** 获取本机序列号*/
        local_SN = g_Area_Status_Ctl[index].Area_Req.arqCount;
        /** 如果时间同步失败 则接收3周期的旧数据，如果时间同步成功，必须是自己的数据 */
        if (MSCP_AREA_TIME_SYNC_OK != CFM_GetTimeSyncFlag())
		{
        	 /** 校验应答是否为自己发出的 且目标id为自己*/
            if(((local_SN - 3)< p_Area_Req_tmp->arqCount) && (p_Area_Req_tmp->destId == index))
            {

                /** 保存接收状态 */
                CM_Memcpy(&g_Area_Status_Ctl[srcid].Area_Req, sizeof(STR_Area_Req), p_Area_Req_tmp, sizeof(STR_Area_Req));
                AREA_LOG_MSG("recv state = %d sn %d srcid %d \r\n",p_Area_Req_tmp->Localstate, p_Area_Req_tmp->arqCount, srcid);
                if(MSCP_AREA_NET_A == net)
                {
                	g_Area_Status_Ctl[srcid].Local_Net_A_state = MSCP_AREA_NET_OK;
                }
                else
                {
                	g_Area_Status_Ctl[srcid].Local_Net_B_state = MSCP_AREA_NET_OK;
                }
            }
            else
            {
            	AREA_LOG_MSG("no sync time  local_SN %d ,sn %d id %d %d\r\n",local_SN,p_Area_Req_tmp->arqCount,p_Area_Req_tmp->destId,index);
                /** 不是自己发出的应答，忽略 */
            }
		}
        else
        {
        	/* 根据接收到的数据  设置接收数据状态*/
            if(MSCP_AREA_NET_A == net)
            {
            	g_Area_Status_Ctl[srcid].Local_Net_A_state = MSCP_AREA_NET_OK;
            }
            else
            {
            	g_Area_Status_Ctl[srcid].Local_Net_B_state = MSCP_AREA_NET_OK;
            }

            if((local_SN == p_Area_Req_tmp->arqCount) && (p_Area_Req_tmp->destId == index))
            {
                AREA_LOG_MSG("recv time %llu local_SN %d ,sn %d id %d %d\r\n",CM_GetTick()/1000000,local_SN,p_Area_Req_tmp->arqCount,p_Area_Req_tmp->destId, srcid);

                /** 保存接收状态 */
                CM_Memcpy(&g_Area_Status_Ctl[srcid].Area_Req, sizeof(STR_Area_Req), p_Area_Req_tmp, sizeof(STR_Area_Req));
                AREA_LOG_MSG("RSP recv state = %d sn %d srcid %d \r\n",p_Area_Req_tmp->Localstate, p_Area_Req_tmp->arqCount, srcid);

            }
            else
            {
            	AREA_LOG_MSG("sync time local_SN %d ,sn %d id %d %d\r\n",local_SN,p_Area_Req_tmp->arqCount,p_Area_Req_tmp->destId,srcid);
                /** 不是自己发出的应答，忽略 */
            }
        }

    }

}

/** @brief 设置区域通信网络状态
 * @param index 区域通信网络索引
 * @param state 区域通信网络状态
*/

void set_Area_Net_Status(CM_UINT8 net, CM_UINT8 state)
{
    /**获取板卡id作为管理结构体下标 */
	CM_UINT32 index = 0;
    index = g_Area_Ctl.Area_Cfg.BoardID;

    if(MSCP_AREA_NET_A == net)
    {
    	g_Area_Status_Ctl[index].Local_Net_A_state = state;
    }
    else if(MSCP_AREA_NET_B == net)
    {
    	g_Area_Status_Ctl[index].Local_Net_B_state = state;
    }
    else
    {
        CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    }
}

void clear_Area_Net_Status()
{
    CM_UINT32 index= 0;
    /**获取板卡id作为管理结构体下标 */
    index = g_Area_Ctl.Area_Cfg.BoardID;

    g_Area_Status_Ctl[index].Local_Net_A_state = MSCP_AREA_NET_FILD;
    g_Area_Status_Ctl[index].Local_Net_B_state = MSCP_AREA_NET_FILD;

}

void clear_Area_ALL_Net_Status()
{
    CM_UINT32 index= 0;
   for(index = 1; index <= MSCP_AREA_DEVICE_MAX; index++)
   {
	    g_Area_Status_Ctl[index].Local_Net_A_state = MSCP_AREA_NET_FILD;
	    g_Area_Status_Ctl[index].Local_Net_B_state = MSCP_AREA_NET_FILD;
   }
}



/** @brief 是否存在区域备地
 * @return CM_BOOL 是否存在区域备地
*/
CM_BOOL Area_Slave_Is_Exist()
{
	CM_BOOL rt = CM_FALSE;
	if((ENUM_AREA_SLAVE == g_Area_4x_Ctl.Local_state) || (ENUM_AREA_SLAVE == g_Area_4x_Ctl.Partner_state)
			|| (ENUM_AREA_SLAVE == g_Area_4x_Ctl.Partner_Area_A_state) || (ENUM_AREA_SLAVE == g_Area_4x_Ctl.Partner_Area_B_state))
	{
		rt = CM_TRUE;
	}
	else
	{

	}
	return rt;
}


/**
 * @brief 区域通信消息接收
 *
 */
 void Area_Msg_Recv(STR_Area_IP_Cfg *pCtrl,CM_UINT8 *p_buf, CM_UINT16 *p_len, CM_UINT16 BufSize)
 {
	ENUM_CM_RETURN rt  = ENUM_CM_FALSE;
    if((NULL == p_buf) || (NULL == p_len))
    {
        CM_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    }
    else
    {
        rt = CM_MQ_Read(&pCtrl->MsgQ, p_buf, p_len);
        if(ENUM_CM_FALSE == rt )
        {
        	*p_len = 0;
        }
    }
 }

void Area_Clear_MQ()
{
	CM_MQ_Clear(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_B.MsgQ);
	CM_MQ_Clear(&g_Area_Ctl.Area_Cfg.IP_Cfg_Area_A.MsgQ);
}

CM_UINT32 Area_GetArea_A_ID(void)
{
	return g_Area_Ctl.Area_Cfg.Partner_Area_A_BoardID;
}
CM_UINT32 Area_GetArea_B_ID(void)
{
	return g_Area_Ctl.Area_Cfg.Partner_Area_B_BoardID;
}


