#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 "MSCP_APP_Interface.h"
#include "CM_MQ.h"
#include "stdarg.h"
#include "Arb.h"
#include "Arb_Net.h"
#include "Area_2oo2.h"

/*===========↓↓↓↓↓宏定义↓↓↓↓↓=============*/
#define ARB_MSG_NUM_MAX     20      /*仲裁应答接收队列最大数量*/
#define ARB_RAW_MSG_SIZE   1400     /*仲裁应答接收数据包最大长度*/

/*区域单播通信配置指针*/
#define AREA_UNI_COMM_CFG_PTR           (&g_area_with_arb_cfg.COMM_CFG.COMM_CFG_AREA)
/*仲裁通信配置指针*/
#define ARB_COMM_CFG_PTR            (&g_area_with_arb_cfg.COMM_CFG.COMM_CFG_ARB)
/*区域组播通信配置指针*/
#define AREA_MULTI_COMM_CFG_PTR     (&g_area_with_arb_cfg.COMM_CFG.COMM_CFG_AREA_MULTICAST)
/*===========↑↑↑↑↑宏定义↑↑↑↑↑=============*/


/*===========↓↓↓↓↓全局变量声明&定义↓↓↓↓↓=============*/

/*===========↑↑↑↑↑全局变量声明&定义↑↑↑↑↑=============*/


/*===========↓↓↓↓↓静态函数声明↓↓↓↓↓=============*/

/**
 * @brief 仲裁接收线程
 * @param STRU_ARB_IP_CFG_T-仲裁相关通信配置
 */
static CM_THREAD_FUNC_T t_Area_Arb_UdpRecvThread(IN STRU_ARB_COMM_CFG_T *arg);
/**
 * @brief 区域间组播接收线程
 * @param 
 */
static CM_THREAD_FUNC_T t_Area_Multi_UdpRecvThread(IN STRU_AREA_MULTICAST_COMM_T *arg);
/**
 * @brief 区域间但播接收线程
 */
static CM_THREAD_FUNC_T t_Area_Uni_UdpRecvThread(IN STR_Area_IP_Cfg* arg);
/**
 * @brief 从配置中读取仲裁模式下使用的IP
 */
static void s_Area_Arb_IP_Init(void);

/*===========↑↑↑↑↑静态函数声明↑↑↑↑↑=============*/


/*===========↓↓↓↓↓函数定义↓↓↓↓↓↓=============*/
/**
 * @brief 仲裁模式下的网络初始化
 */
void Area_Arb_Net_Init(void)
{
    CM_UINT32 val = 0u;
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    CM_BOOL rtCheck = CM_FALSE;
    /**2取初始化 */
    Area_2oo2_Init();
    /*获取IP配置*/
    s_Area_Arb_IP_Init();
    /** 初始化区域网络通信 */
    rt = CM_UDP_Socket_Create(&(AREA_UNI_COMM_CFG_PTR->Socket), CM_FALSE, (CM_UINT32)inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Local), AREA_UNI_COMM_CFG_PTR->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(AREA_UNI_COMM_CFG_PTR->Socket, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));


    rt = CM_MQ_Init(&(AREA_UNI_COMM_CFG_PTR->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);

    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_Uni_UdpRecvThread, "Area_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)AREA_UNI_COMM_CFG_PTR);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);

    /*初始化仲裁通信*/
    rt = CM_UDP_Socket_Create(&(ARB_COMM_CFG_PTR->Socket), CM_FALSE, (CM_UINT32)inet_addr(ARB_COMM_CFG_PTR->IP_Local), ARB_COMM_CFG_PTR->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(ARB_COMM_CFG_PTR->Socket, SOL_SOCKET, SO_RCVBUF, (void*)(&val), (unsigned int)sizeof(val));


    rt = CM_MQ_Init(&(ARB_COMM_CFG_PTR->MsgQ), (CM_UINT16)ARB_MSG_NUM_MAX, (CM_UINT16)ARB_RAW_MSG_SIZE);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_Arb_UdpRecvThread, "Arb_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)ARB_COMM_CFG_PTR);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);

    /** 初始化区域组播网络通信 */
    rt = CM_UDP_Socket_Create(&(AREA_MULTI_COMM_CFG_PTR->Socket_Send), CM_FALSE, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Local), AREA_MULTI_COMM_CFG_PTR->Port_Send, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Multicast),ENUM_MULTICAST_SEND);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rt = CM_UDP_Socket_Create(&AREA_MULTI_COMM_CFG_PTR->Socket_Recv, CM_FALSE, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Local), AREA_MULTI_COMM_CFG_PTR->Port_Recv, (CM_UINT32)inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Multicast),ENUM_MULTICAST_RCV);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);
    
    rt = CM_MQ_Init(&(AREA_MULTI_COMM_CFG_PTR->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);
    
    rtCheck = CM_Thread_Create((CM_THREAD_T*)NULL, (CM_THREAD_FUNC_T)t_Area_Multi_UdpRecvThread, "Area_Rx", 0, CM_TASK_PRIORITY_73, (CM_Thread_Arg_Struct_T*)AREA_MULTI_COMM_CFG_PTR);
	CM_NM_ASSERT(CM_TRUE == rtCheck, NET_MODE,DARK_FAULT_CODE_FUN_ORDER_1, TSCP_DARK_ASSERT_24);

}

/**
* @brief 第三方仲裁请求发送
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_Arb_Req_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 入参指针防空 */
    if(NULL != pBuf)
    {
		/*- 向第三方仲裁发送 */
    	rt = CM_UDP_Send_Msg(ARB_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(ARB_COMM_CFG_PTR->IP_Arb),ARB_COMM_CFG_PTR->port);
    }
    else
    {
    	/*空指针返回失败*/
    }
    /*- 返回发送结果 */
    return rt;
}
/**
* @brief 第三方仲裁请求发送接收
* @param pBuf 接收报文指针 取值范围：非空
* @param BufLen 接收报文缓冲区大小 取值范围：0~0xFFFFFFFF
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_Arb_Ack_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize)
{
	/*- 变量初始化 */
	CM_UINT16 len = (CM_UINT16)((BufSize > 65535u) ? 65535u : BufSize);
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 指针防空*/
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&(ARB_COMM_CFG_PTR->MsgQ), pBuf, &len);
	/*- 是否获取成功 */
	if (ENUM_CM_TRUE == rt)
	{
		/*- 输出接收数据 */
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
	/*- 返回接收长度 */
	return (CM_INT32)len;
}

/**
* @brief 区域状态请求单播发送
* @param dstID 发送的目的ID
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_State_Send(IN CM_UINT8 dstID, IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 入参指针防空 */
    if(NULL != pBuf)
    {
		/*- 向目的ID发送 */
        if(dstID == AREA_BASIC_CFG_PTR->Partner_BoardID)
        {
            rt = CM_UDP_Send_Msg(AREA_UNI_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Partner),AREA_UNI_COMM_CFG_PTR->port);
        }
        else if(dstID == AREA_BASIC_CFG_PTR->Partner_Area_A_BoardID)
        {
            rt = CM_UDP_Send_Msg(AREA_UNI_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Partner_Area_A),AREA_UNI_COMM_CFG_PTR->port);
        }
        else if(dstID == AREA_BASIC_CFG_PTR->Partner_Area_B_BoardID)
        {
            rt = CM_UDP_Send_Msg(AREA_UNI_COMM_CFG_PTR->Socket, pBuf, BufLen, inet_addr(AREA_UNI_COMM_CFG_PTR->IP_Partner_Area_B),AREA_UNI_COMM_CFG_PTR->port);
        }
    	else
        {
            /**ID查询失败 */
            rt = ENUM_CM_FALSE;
        }
        
    }
    else
    {
    	/*空指针返回失败*/
    }
    /*- 返回发送结果 */
    return rt;
}

/**
* @brief 区域状态请求单播接收（仲裁模式使用）
* @param pBuf 接收报文指针 取值范围：非空
* @param BufLen 接收报文缓冲区大小 取值范围：0~0xFFFFFFFF
* @param timeRcv 接收时的时间戳，单位ms
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_State_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* timeRcv)
{
	/*- 变量初始化 */
	CM_UINT8 buf[Area_RAW_MSG_SIZE] = {0};
	CM_UINT16 len = (CM_UINT16)sizeof(buf);
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 指针防空*/
	if((NULL == pBuf) || (0u == BufSize))
	{
		return 0;
	}
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&(AREA_UNI_COMM_CFG_PTR->MsgQ), buf, &len);
	/*- 是否获取成功 */
	if ((ENUM_CM_TRUE == rt) && (len > 4u) && ((CM_UINT32)(len - 4u) <= BufSize))
	{
		/*- 输出接收数据 */
        if(NULL != timeRcv)
        {
            *timeRcv = CM_LongFromChar(buf);
        }
        CM_Memcpy(pBuf, BufSize, &buf[4], len - 4);
		len -= 4u;
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
	/*- 返回接收长度 */
	return (CM_INT32)len;
}

/**
* @brief 区域状态请求组播发送
* @param pBuf 发送报文指针 取值范围：非空
* @param BufLen 发送报文长度 取值范围：0~0x7FFFFFFF
* @return 发送结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN Area_State_Multi_Send(IN const CM_UINT8* pBuf, IN CM_INT32 BufLen)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;
    /*- 入参指针防空 */
    if(NULL != pBuf)
    {
		/*- 组播发送 */
    	rt = CM_UDP_Send_Msg(AREA_MULTI_COMM_CFG_PTR->Socket_Send, pBuf, BufLen, inet_addr(AREA_MULTI_COMM_CFG_PTR->IP_Multicast),AREA_MULTI_COMM_CFG_PTR->Port_Recv);
    }
    else
    {
    	/*空指针返回失败*/
    }
    /*- 返回发送结果 */
    return rt;
}

/**
* @brief 区域状态请求组播接收
* @param pBuf 接收报文指针 取值范围：非空
* @param BufLen 接收报文缓冲区大小 取值范围：0~0xFFFFFFFF
* @param timeRcv 接收时的时间戳，单位ms
* @return 接收报文长度
* - 1~0xFFFFFFFF 接收报文长度
* - 0 接收失败
*/
CM_INT32 Area_State_Multi_Recv(CM_UINT8* pBuf, IN CM_UINT32 BufSize, OUT CM_UINT32* timeRcv)
{
	/*- 变量初始化 */
	CM_UINT8 buf[Area_RAW_MSG_SIZE] = {0};
	CM_UINT16 len = (CM_UINT16)sizeof(buf);
	ENUM_CM_RETURN rt = ENUM_CM_FALSE;
	/*- 指针防空*/
	if((NULL == pBuf) || (0u == BufSize))
	{
		return 0;
	}
	/*- 从接收线程获取输入报文 */
	rt = CM_MQ_Read(&(AREA_MULTI_COMM_CFG_PTR->MsgQ), buf, &len);
	/*- 是否获取成功 */
	if ((ENUM_CM_TRUE == rt) && (len > 4u) && ((CM_UINT32)(len - 4u) <= BufSize))
	{
		/*- 输出接收数据 */
        if(NULL != timeRcv)
        {
            *timeRcv = CM_LongFromChar(buf);
        }
        CM_Memcpy(pBuf, BufSize, &buf[4], len - 4);
		len -= 4u;
	}
	else
	{
		/*- 接收长度为0 */
		len = 0u;
	}
	/*- 返回接收长度 */
	return (CM_INT32)len;
}

/**
 * @brief 清空接收缓冲区
 */
void Area_Arb_ClearMsgQ(void)
{
    (void)CM_MQ_Flush(&(AREA_UNI_COMM_CFG_PTR->MsgQ));
    (void)CM_MQ_Flush(&(ARB_COMM_CFG_PTR->MsgQ));
    (void)CM_MQ_Flush(&(AREA_MULTI_COMM_CFG_PTR->MsgQ));
}

/**
 * @brief 仲裁接收线程
 * @param STRU_ARB_IP_CFG_T-仲裁相关通信配置
 */
static CM_THREAD_FUNC_T t_Area_Arb_UdpRecvThread(IN STRU_ARB_COMM_CFG_T *arg)
{
    /*- 变量初始化 */
    STRU_ARB_COMM_CFG_T *pCtrl = (STRU_ARB_COMM_CFG_T *)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;               /* 函数返回值 */
    CM_UINT8 *rcvBuf = NULL;
    CM_INT32 len;       /* 报文长度 */
    CM_UINT32 srcIP;    /* 源IP */
    CM_UINT16 srcPort;  /* 源端口 */
    CM_SOCKADDR_T addr; /* 地址转换*/

    void* pmask = NULL;
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);

    MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP_Local, pCtrl->port);
    /*- 循环接收UDP数据 */
    while (1)
    {
        /*- UDP阻塞接收 */
        rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
        if (NULL != rcvBuf)
        {
            len = CM_UDP_Recv_Msg(pCtrl->Socket, &rcvBuf[0u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize), &srcIP, &srcPort);
            /*- 是否收到有效数据 */
            if (len > 0)
            {
                /*- 源IP端口是否合法 */
                if ((srcIP != 0) && (srcPort != 0))
                {
                    /*- @alias 将收到的报文写入线程接收队列 */
                    // 					MSCP_LOG_MSG("!!! area recv len = %d \r\n",len);
                    /*- 保存通信数据 */
                    rt = CM_MQ_UpData(&pCtrl->MsgQ, (CM_UINT16)CM_SIGNED_INT_EXP(len));
                    /*- 数据保存是否成功 */
                    if (ENUM_CM_TRUE == rt)
                    {
                        /*成功无操作*/
                    }
                    else
                    {
                        /*- 防御性清空*/
                        rt = CM_MQ_Clear(&pCtrl->MsgQ);
                        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
                    }
                }
                else
                {
                    /*- 来自非预期IP端口的数据*/
                    addr.sin_addr.s_addr = srcIP;
                    CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
                }
            }
            else
            {
                /*- 接收出错 */
                MSCP_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->port, len);
                (void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
            }
        }
        else
        {
            /*获取队列指针失败，清空队列*/
            rt = CM_MQ_Clear(&pCtrl->MsgQ);
            MSCP_LOG_MSG("buf clear\n");
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
        }
    }
    return NULL;
}

/**
 * @brief 区域间组播接收线程
 * @param 
 */
static CM_THREAD_FUNC_T t_Area_Multi_UdpRecvThread(IN STRU_AREA_MULTICAST_COMM_T *arg)
{
    /*- 变量初始化 */
    STRU_AREA_MULTICAST_COMM_T *pCtrl = (STRU_AREA_MULTICAST_COMM_T *)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;               /* 函数返回值 */
    CM_UINT8 *rcvBuf = NULL;
    CM_INT32 len;       /* 报文长度 */
    CM_UINT32 srcIP;    /* 源IP */
    CM_UINT16 srcPort;  /* 源端口 */
    CM_SOCKADDR_T addr; /* 地址转换*/

    void* pmask = NULL;
    pmask = (void*)(0x01u|0x02u);
    (void)ThreadCtl(_NTO_TCTL_RUNMASK, pmask);
    
    MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP_Multicast, pCtrl->Port_Recv);
    /*- 循环接收UDP数据 */
    while (1)
    {
        /*- UDP阻塞接收 */
        rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
        if (NULL != rcvBuf)
        {
            len = CM_UDP_Recv_Msg(pCtrl->Socket_Recv, &rcvBuf[4u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize - 4u), &srcIP, &srcPort);
            /*- 是否收到有效数据 */
            if (len > 0)
            {
                /*- 源IP端口是否合法 */
                if ((srcIP != 0) && (srcPort != 0))
                {
                    /*- @alias 将收到的报文写入线程接收队列 */
					CM_LongToChar((CM_UINT32)(CM_GetTick()/CM_UNSIGNED_MILLION), rcvBuf);
                    /*- 保存通信数据 */
                    rt = CM_MQ_UpData(&pCtrl->MsgQ, (CM_UINT16)CM_SIGNED_INT_EXP(len+4u));
                    /*- 数据保存是否成功 */
                    if (ENUM_CM_TRUE == rt)
                    {
                        /*成功无操作*/
                    }
                    else
                    {
                        /*- 防御性清空*/
                        rt = CM_MQ_Clear(&pCtrl->MsgQ);
                        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
                    }
                }
                else
                {
                    /*- 来自非预期IP端口的数据*/
                    addr.sin_addr.s_addr = srcIP;
                    CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
                }
            }
            else
            {
                /*- 接收出错 */
                AREA_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->Port_Recv, len);
                (void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
            }
        }
        else
        {
            /*获取队列指针失败，清空队列*/
            rt = CM_MQ_Clear(&pCtrl->MsgQ);
            AREA_LOG_MSG("buf clear\n");
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
        }
    }
    return NULL;
}
/**
 * @brief 初始化仲裁模式下使用的IP
 */
static void s_Area_Arb_IP_Init(void)
{
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;

     /** 获取区域网络配置(状态请求) */
    rt = CM_Memcpy(AREA_UNI_COMM_CFG_PTR->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(AREA_UNI_COMM_CFG_PTR->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(AREA_UNI_COMM_CFG_PTR->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(AREA_UNI_COMM_CFG_PTR->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);

    AREA_UNI_COMM_CFG_PTR->port = g_PFM_Cfg.Local_Cfg.Port_Area_State;/**<  端口号 */

    AREA_LOG_MSG("AREA 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);
        
    /*获取仲裁网络配置*/
    rt = CM_Memcpy(ARB_COMM_CFG_PTR->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(ARB_COMM_CFG_PTR->IP_Arb, 32, g_PFM_Cfg.Arb_CFG.IP_Arb,32);/**<  对地通信IP */
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);   
    
    ARB_COMM_CFG_PTR->port = g_PFM_Cfg.Arb_CFG.Port_Arb;

    MSCP_LOG_MSG("ARB CFG %s:%d->%s:%d\n", ARB_COMM_CFG_PTR->IP_Local, 
        ARB_COMM_CFG_PTR->port,ARB_COMM_CFG_PTR->IP_Arb,ARB_COMM_CFG_PTR->port);

    /*获取区域间组播通信配置(主地主组播状态)*/
    rt = CM_Memcpy(AREA_MULTI_COMM_CFG_PTR->IP_Local, 32, g_PFM_Cfg.Local_Cfg.IP_4x2,32);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    rt = CM_Memcpy(AREA_MULTI_COMM_CFG_PTR->IP_Multicast, 32, g_PFM_Cfg.Local_Cfg.IP_Area_Multicast, 32);
    CM_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_2, TSCP_DARK_ASSERT_1);

    AREA_MULTI_COMM_CFG_PTR->Port_Recv = g_PFM_Cfg.Local_Cfg.Port_Area_Recv;
    AREA_MULTI_COMM_CFG_PTR->Port_Send = g_PFM_Cfg.Local_Cfg.Port_Area_Send;

    MSCP_LOG_MSG("AREA MULTICAST CFG %s:%d->%s:%d\n", AREA_MULTI_COMM_CFG_PTR->IP_Local, AREA_MULTI_COMM_CFG_PTR->Port_Send,
        AREA_MULTI_COMM_CFG_PTR->IP_Multicast,AREA_MULTI_COMM_CFG_PTR->Port_Recv);

}
/**
 * @brief 区域间但播接收线程
 */
static CM_THREAD_FUNC_T t_Area_Uni_UdpRecvThread(IN STR_Area_IP_Cfg *arg)
{
    /*- 变量初始化 */
    STR_Area_IP_Cfg *pCtrl = (STR_Area_IP_Cfg *)arg; /* 线程控制信息 */
    ENUM_CM_RETURN rt = ENUM_CM_FALSE;               /* 函数返回值 */
    CM_UINT8 *rcvBuf = NULL;
    CM_INT32 len;       /* 报文长度 */
    CM_UINT32 srcIP;    /* 源IP */
    CM_UINT16 srcPort;  /* 源端口 */
    CM_SOCKADDR_T addr; /* 地址转换*/

    CM_UINT32 cpu_mask = 0;
    /*- 本线程锁定在 A53 core 1 */
    cpu_mask = (0x04u);
    set_thread_affinity(cpu_mask);
    MSCP_LOG_MSG("IP:%s:%d UDP recv Start\n", pCtrl->IP_Local, pCtrl->port);
    /*- 循环接收UDP数据 */
    while (1)
    {
        /*- UDP阻塞接收 */
        rcvBuf = CM_MQ_Get_BufAddr(&pCtrl->MsgQ);
        if (NULL != rcvBuf)
        {
            len = CM_UDP_Recv_Msg(pCtrl->Socket, &rcvBuf[4u], (CM_INT32)CM_UNSIGNED_SHORT_EXP(pCtrl->MsgQ.maxMsgSize - 4u), &srcIP, &srcPort);
            /*- 是否收到有效数据 */
            if (len > 0)
            {
                /*- 源IP端口是否合法 */
                if ((srcIP != 0) && (srcPort != 0))
                {
                    /*- @alias 将收到的报文写入线程接收队列 */
					CM_LongToChar((CM_UINT32)(CM_GetTick()/CM_UNSIGNED_MILLION), rcvBuf);
                    /*- 保存通信数据 */
                    rt = CM_MQ_UpData(&pCtrl->MsgQ, (CM_UINT16)CM_SIGNED_INT_EXP(len+4u));
                    /*- 数据保存是否成功 */
                    if (ENUM_CM_TRUE == rt)
                    {
                        /*成功无操作*/
                    }
                    else
                    {
                        /*- 防御性清空*/
                        rt = CM_MQ_Clear(&pCtrl->MsgQ);
                        CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_1);
                    }
                }
                else
                {
                    /*- 来自非预期IP端口的数据*/
                    addr.sin_addr.s_addr = srcIP;
                    CM_RE_ASSERT(0, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_2);
                }
            }
            else
            {
                /*- 接收出错 */
                AREA_LOG_MSG("warning ASSERT1103: port %d rx err(len=%d)\n", pCtrl->port, len);
                (void)CFM_DarkLog_Storage(DARK_LOG_HEX, TSCP_DARK_WARNING, 4U, DARK_FAULT_CODE_MERGE(NET_MODE, DARK_FAULT_CODE_FUN_ORDER_8, TSCP_DARK_ASSERT_1));
            }
        }
        else
        {
            /*获取队列指针失败，清空队列*/
            rt = CM_MQ_Clear(&pCtrl->MsgQ);
            AREA_LOG_MSG("buf clear\n");
            CM_RE_ASSERT(ENUM_CM_TRUE == rt, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_11, TSCP_DARK_ASSERT_4);
        }
    }
    return NULL;
}
