/**
  ******************************************************************************
  * @file    net_srv.c
  * @author  wangfq
  * @version V1.0
  * @date    2026-03-02
  * @brief   net message handle: unpack, exeute, response
  *
  ******************************************************************************
  */ 
#include "CONFIG.h"
#include "net_srv.h"
#include "eth_driver.h"
#include "wchnet.h"
#include "MQTTPacket.h"
#include <string.h>
#include <stdlib.h>
#include "cmcng.h"
#include "simple_json.h"
#include "tcp_json_srv.h"


uint32_t slen;
char g_dev_number_str[13] = "";
uint8_t g_flag_timestamp = 0; 

#define KEEPALIVE_ENABLE         1                          //Enable keep alive function


#define maxLenTemp  430
static char temp_guide[maxLenTemp] = "";

static void reset_temp_guide()
{
    memset(temp_guide, 0, maxLenTemp);
}


//************************************************************************10
#define KEEPLIVE_ENABLE         1                                //Enable keeplive function


Local_Net_Cfg local_net_cfg = {{0x00, 0x08, 0xdc, 0x33, 0x44, 0x55}, {192,168,1,188}, {255,255,255,0}, {192, 168,1,1}, "", 5550,NET_REPORT_INTERVAL, 5505, PORT_TCP_DEFAULT, MAX_CLEAR_COUNTER_INTERVAL};

NET_CENTER_INFO net_center_info = {{192,168,1,222}, 5505, PORT_TCP_DEFAULT, 5505, ""};
IOT_NET_INFO iot_net_info = {"",  1883, "", "", ""};
IOT_Topic    g_iot_topic = {0, "", ""};
uint8_t RemoteIP[4] = {0,0,0,0};

Net_State g_net_state = {0,0, 0};


uint16_t srcport = 6000;   
//UINT8 UDPDESIP[4]   = {255,255,255,255};                                           /* ????????????????????,?????????��???????????????????? */
//UINT16 aport=1000;											                   /* CH579?????????? */
uint32_t g_wdg_counter = 0;

#if NET_SSC_ENABLE

uint8_t SocketId_TCP;
uint8_t SocketId_UDP ;
uint8_t socket[WCHNET_MAX_SOCKET_NUM];                           //Save the currently connected socket
uint8_t SocketRecvBuf[WCHNET_MAX_SOCKET_NUM][RECE_BUF_LEN];      //socket receive buffer
uint8_t MyBuf[RECE_BUF_LEN];


#define         MAX_TMP_BUF_LEN     64
#define         MAX_MQTTBUF_LEN     512 //384     //512
char mqtt_username[64] = {0};
char mqtt_password[32] = {0};
char mqtt_clientid[64] = {0};
uint8_t mqttBuf[MAX_MQTTBUF_LEN];
uint8_t TmpBuf[MAX_TMP_BUF_LEN] = "";

MQTTPacket_connectData mqttData = MQTTPacket_connectData_initializer;

uint8_t flag_mqtt_ping_send = 0;
uint8_t flag_mqtt_ping_err = 0;            //++, 0 normal, >0 send and no response
uint8_t g_mqtt_ping_counter = 0;            // 

void clear_mqtt_buf(void)
{
    memset(mqttBuf, 0, MAX_MQTTBUF_LEN);
}

#endif /* NET_SSC_ENABLE */

/*********************************************************************
 * @fn      mStopIfError
 *
 * @brief   check if error.
 *
 * @param   iError - error constants.
 *
 * @return  none
 */
void mStopIfError(u8 iError)
{
    if (iError == WCHNET_ERR_SUCCESS) return;
    printf("Error: 0x%02X\r\n", (u16)iError);
}

#if NET_SSC_ENABLE

void mqtt_connect(void)
{
    int len = 0;
    mqttData.username.cstring = iot_net_info.username;
    mqttData.password.cstring = iot_net_info.password;
    mqttData.clientID.cstring = g_dev_number_str;    //TODO:  ?��????????????????????
    mqttData.keepAliveInterval = MQTT_KEEPALIVE_INTERVAL;
    
    PRINT("username:%s\r\n", mqttData.username.cstring);
    PRINT("password:%s\r\n", mqttData.password.cstring);
    PRINT("clientID:%s\r\n", mqttData.clientID.cstring);
    
    clear_mqtt_buf();
    len = MQTTSerialize_connect(mqttBuf, sizeof(mqttBuf), &mqttData);
//    Transport_SendPacket(mqttBuf, len);
    WCHNET_SocketSend(SocketId_TCP, (uint8_t *)mqttBuf, &len);
    
}

void MQTT_Subscribe(char *topic,  unsigned char msgid)
{
    int len = 0, req_qos = 0;
    MQTTString topicString = MQTTString_initializer;
    topicString.cstring = topic;
    clear_mqtt_buf();
    len = MQTTSerialize_subscribe(mqttBuf, sizeof(mqttBuf), 0, msgid, 1, &topicString, &req_qos);
//    Transport_SendPacket(mqttBuf, len);
    WCHNET_SocketSend(SocketId_TCP, (uint8_t *)mqttBuf, &len);
}


void dg_subscribe_display_topic(void)
{
    char *mBuff = (char *)malloc(256);
    if(mBuff == NULL)
    {
        return;
    }
    memset(mBuff, 0, 256);
    
    if(g_iot_topic.clientid_enable)
    {
        sprintf(mBuff, "%s/%s", g_iot_topic.topic_sub, iot_net_info.client_id);
    }
    else
    {
        sprintf(mBuff, "%s/%s", g_iot_topic.topic_sub, g_dev_number_str);
    }
    
    {
    PRINT("\r\nWill subscribe display_topic:\n%s\r\n", mBuff);
    }
    MQTT_Subscribe(mBuff, 1);
    
    free(mBuff);
}


void MQTT_Pingreq()
{
    uint8_t ping_buf[2];
    int buf_len = sizeof(ping_buf);
    int ping_len = MQTTSerialize_pingreq(ping_buf, buf_len);
//    Transport_SendPacket(ping_buf, ping_len);
    WCHNET_SocketSend(SocketId_TCP, (uint8_t *)ping_buf, &buf_len);
}

void mqtt_publish(char *topic, char *message, int req_qos)
{
    uint32_t len = 0;
    clear_mqtt_buf();
    
    {
        PRINT("\nWill_publish_topid:%s, message:%s\n", topic, message);
    }
    
    MQTTString topicString = MQTTString_initializer;
    int msglen = strlen(message);
    topicString.cstring = topic;
    len = MQTTSerialize_publish(mqttBuf, sizeof(mqttBuf), 0, req_qos, 0, 0, topicString, (unsigned char *)message, msglen);
//    Transport_SendPacket(mqttBuf, len);
    WCHNET_SocketSend(SocketId_TCP, (uint8_t *)mqttBuf, &len);
}

void dev_initialize_pub(void)
{
    char *mBuff = (char *)malloc(256);
    if(mBuff == NULL)
    {
        return;
    }
    memset(mBuff, 0, 256);
    
    sprintf((char *)mBuff, "{\"Method\":\"Initialize\", \"Device_id\": \"%s\","
    "\"Extra_Info\":{\"Code\":\"%s\",\"CSQ\":%d, \"Version\":\"%s\"}}", g_dev_number_str, "0", 0,  FIRMWARE_VER);
    //mqtt_publish((char *)"gtpc/display/Initialize", gbufSend, 0);
    
    PRINT("\r\nWill publish initialize_topic:\n%s\r\n", mBuff);
    
    mqtt_publish((char *)(g_iot_topic.topic_pub), (char *)mBuff, 0);
    
    free(mBuff);
}

void dev_response_heartbeat(char *dat)
{
    char *mBuff = (char *)malloc(256);
    if(mBuff == NULL)
    {
        return;
    }
    memset(mBuff, 0, 256);
    if(dat == NULL)
    {
        sprintf((char *)mBuff, "{\"Method\":\"Heartbeat\", \"Data\":{\"Device_id\": \"%s\"}}", g_dev_number_str);
    } else {
        sprintf((char *)mBuff, "{\"Method\":\"Heartbeat\", \"Data\":{\"Device_id\": \"%s\",\"Remark\":\"%s\"}}", g_dev_number_str, dat);
    }  
    // mqtt_publish("gtpc/display/Initialize", gbufSend, 0);  
    mqtt_publish((char *)(g_iot_topic.topic_pub), (char *)mBuff, 0); 
    
    free(mBuff);
}

void mqtt_deserialize_publish(char* topic, char* msg, int length)
{    
//    if(g_flag_debug)
//    {
//        printf("display_mqtt_callback rev topic: %s\n msg:%s, len:%d\r\n", topic, msg, length);
//    }
    if(strstr(topic, (char *)TOPIC_DEFAULT_SUBSCRIBE) != NULL)  //
    {
        manage_mqtt_recv_message(msg, length);
    }
    else
    {   
        {
            PRINT("\n%s, line:%d, other topic:%s, msg:%s.\n", __FUNCTION__, __LINE__, topic, msg);
        }
    }
        
}

void tcp_send_test()
{
    uint8_t ping_buf[5] = {0x33, 0x32, 0x33,0x30,0x39};
    int buf_len = 5;
//    Transport_SendPacket(ping_buf, ping_len);
    WCHNET_SocketSend(SocketId_TCP, (uint8_t *)ping_buf, &buf_len);
}

/*********************************************************************
 * @fn      WCHNET_CreateTcpSocket
 *
 * @brief   Create TCP Socket
 *
 * @return  none
 */
void WCHNET_CreateTcpSocket(void)
{
    uint8_t i = 0;
    uint8_t ret;
    uint32_t len;
    SOCK_INF TmpSocketInf;

    memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
    memcpy((void *) TmpSocketInf.IPAddr,  net_center_info.lssc_ip, 4);
    TmpSocketInf.DesPort = net_center_info.tcp_port;
    TmpSocketInf.SourPort = srcport++; // local_net_cfg.port_dev_udp;
    TmpSocketInf.ProtoType = PROTO_TYPE_TCP;
    TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
    i = WCHNET_SocketCreat(&SocketId_TCP, &TmpSocketInf);
  
    {  
        PRINT("WCHNET_SocketCreate %d,desIP:%d.%d.%d.%d, des_port:%d, srcport:%d\r\n", SocketId_TCP, net_center_info.lssc_ip[0],net_center_info.lssc_ip[1],net_center_info.lssc_ip[2],net_center_info.lssc_ip[3], TmpSocketInf.DesPort, TmpSocketInf.SourPort);
    }
    mStopIfError(i);
    i = WCHNET_SocketConnect(SocketId_TCP);                        //make a TCP connection
    if(i == WCHNET_ERR_SUCCESS)
    {
        PRINT("Tcp_Connect_Success!:%d\n", SocketId_TCP);
        g_net_state.flag = 3; 

        // tcp_send_test();
    }
    mStopIfError(i);
}


void WCHNET_CreateTcpMqttSocket(void)
{
    uint8_t i;
    uint8_t ret;
    uint32_t len;
    SOCK_INF TmpSocketInf;

    memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
    memcpy((void *) TmpSocketInf.IPAddr,  RemoteIP, 4);     
    TmpSocketInf.DesPort = iot_net_info.mqtt_port;  // net_center_info.tcp_port;
    TmpSocketInf.SourPort =  local_net_cfg.port_dev_udp + 1;
    TmpSocketInf.ProtoType = PROTO_TYPE_TCP;
    TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
    i = WCHNET_SocketCreat(&SocketId_TCP, &TmpSocketInf);
  
    {  
        PRINT("WCHNET_MQTT_SocketCreate %d,desIP:%d.%d.%d.%d, des_port:%d, srcport:%d\r\n", SocketId_TCP, RemoteIP[0],RemoteIP[1],RemoteIP[2],RemoteIP[3], iot_net_info.mqtt_port, TmpSocketInf.SourPort);
    }
    mStopIfError(i);
    i = WCHNET_SocketConnect(SocketId_TCP);                        //make a TCP connection
    if(i == WCHNET_ERR_SUCCESS)
    {
        g_net_state.flag = 3; 
    }
    mStopIfError(i);
}


/*********************************************************************
 * @fn      WCHNET_UdpServerRecv
 *
 * @brief   UDP Receive data function
 *
 *@param    socinf - socket information.
 *          ipaddr - The IP address from which the data was sent
 *          port - source port
 *          buf - pointer to the data buffer
 *          len - received data length
 * @return  none
 */
void WCHNET_UdpServerRecv(struct _SOCK_INF *socinf, uint32_t ipaddr, uint16_t port, uint8_t *buf, uint32_t len)
{
    uint8_t ip_addr[4], i;

//    PRINT("Remote IP:");
    for (i = 0; i < 4; i++) {
        ip_addr[i] = ipaddr & 0xff;
//        PRINT("%d ", ip_addr[i]);
        ipaddr = ipaddr >> 8;
    }

    PRINT("srcport = %d len = %d socketid = %d,buf:\r\n%s\r\n", port, len,
            socinf->SockIndex, buf);

    manage_udp_message(socinf->SockIndex, ip_addr, port, buf, len);
}

/*********************************************************************
 * @fn      WCHNET_CreateUdpSocket
 *
 * @brief   Create UDP Socket
 *
 * @return  none
 */
void WCHNET_CreateUdpSocket(void)
{
    uint8_t i;
    SOCK_INF TmpSocketInf;

    memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
//    memcpy((void *) TmpSocketInf.IPAddr, UDPDESIP, 4);
//    TmpSocketInf.DesPort = local_net_cfg.port_ssc_udp;  //5500
    TmpSocketInf.SourPort = local_net_cfg.port_dev_udp; //srcport;// local_net_cfg.port_dev_udp; // 4900
    TmpSocketInf.ProtoType = PROTO_TYPE_UDP;
    TmpSocketInf.RecvStartPoint = (uint32_t)SocketRecvBuf;  //
    TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
    TmpSocketInf.AppCallBack = WCHNET_UdpServerRecv;
    i = WCHNET_SocketCreat(&SocketId_UDP, &TmpSocketInf);
    PRINT("i:%d,WCHNET_SocketCreatUdp %d srcport %d\r\n", i, SocketId_UDP, TmpSocketInf.SourPort);
    mStopIfError(i);
    g_net_state.flag = 2;
}


void reset_net_active_timeup(void)
{
    if(g_activ_counter){
        g_activ_counter = 0;
    }
}


/*********************************************************************
 * @fn      WCHNET_DataManage
 *
 * @brief   Data loopback function.
 *
 * @param   id - socket id.
 *
 * @return  none
 */
void WCHNET_DataManage(uint8_t id)
{
    uint32_t len;
    memset(MyBuf, 0, RECE_BUF_LEN);
    
    unsigned char dup;
	unsigned short packetid;

	int qos;
	unsigned char retained;
	MQTTString topicName;
	unsigned char* payload;
	int payloadlen;
	unsigned char *p=payload;
    
    
    
    len = WCHNET_SocketRecvLen(id, NULL);                                               //query length
    WCHNET_SocketRecv(id, MyBuf, &len);                                                 //Read the data of the receive buffer into MyBuf
//    totallen = len;
    PRINT("Receive socketid:%d, Len = %d, MyBuf__:%s\r\n", id, len, MyBuf);    
    
    if(g_sub_code_enable.iot_enable){
        switch(MyBuf[0] >> 4)
        {
            case CONNACK:
                PRINT("connack\r\n");
//                g_mqtt_con_flag=1;
                dg_subscribe_display_topic();
                dev_initialize_pub();
                reset_net_active_timeup();
                break;

            case PUBLISH: 
                // use *dup, *qos, *retained, *packetid, *topicName, *payload, * payloadlen Will not work, miss some char from raw data.
               MQTTDeserialize_publish(&dup,&qos,&retained,&packetid,&topicName,&payload,&payloadlen,MyBuf,len);
                memset(TmpBuf, 0, MAX_TMP_BUF_LEN);
                memcpy(TmpBuf, topicName.lenstring.data, topicName.lenstring.len);
//                TmpBuf[topicName.lenstring.len] = 0x0;
                mqtt_deserialize_publish(TmpBuf, payload, payloadlen);
//                memset(payload, 0, payloadlen);
                if(g_mqtt_ping_counter< 8){
                    g_mqtt_ping_counter = 8;
                }
                reset_net_active_timeup();
            //TODO: need to check if len-received is out, prevent overflow.
                break;
                
            case SUBACK:
//                sub_flag=1;
            
                break;
            case PINGRESP:
               // printf("RecvPing\n");
            //TODO: if need this?
                if(flag_mqtt_ping_err)
                {
                    flag_mqtt_ping_err = 0;
                }
                reset_net_active_timeup();
                break;
            default:

                break;
        }
    }
    else{
        manage_tcp_message(id,  MyBuf, len);
        reset_net_active_timeup();
    }
    g_net_state.flag = 4;
    
        
}

#endif /* NET_SSC_ENABLE */




/*********************************************************************
 * @fn      WCHNET_HandleSockInt
 *
 * @brief   Socket Interrupt Handle
 *
 * @param   socketid - socket id.
 *          intstat - interrupt status
 *
 * @return  none
 */
void WCHNET_HandleSockInt(uint8_t socketid, uint8_t intstat)
{
#if NET_SSC_ENABLE
    uint8_t i;
    
    // Route JSON protocol socket events (both TCP + TCP_LISTEN internal)
    if (socketid == g_json_socket_listen || socketid == (g_json_socket_listen + 1)) {
        tcp_json_handle_sock_int(socketid, intstat);
        return;
    }
    
    g_net_state.intstat = intstat;
    
    if (intstat & SINT_STAT_RECV)                              //receive data
    {
        WCHNET_DataManage(socketid);                         //Data loopback
    }
    if (intstat & SINT_STAT_CONNECT)                           //connect successfully
    {
#if KEEPLIVE_ENABLE
        WCHNET_SocketSetKeepLive(socketid, ENABLE);
#endif
        WCHNET_ModifyRecvBuf(socketid, (uint32_t) SocketRecvBuf[socketid], RECE_BUF_LEN);
        
        {
            PRINT("TCP Connect Success\r\n");
            PRINT("socket id: %d\r\n", socketid);
        }
        
        // if(g_sub_code_enable.iot_enable){
        //     mqtt_connect();
        // }
    }
    if (intstat & SINT_STAT_DISCONNECT)                         //disconnect
    {        
        {
            PRINT("TCP Disconnect\r\n");
        }
//        WCHNET_SocketClose(socketid, 0);
        g_net_state.flag = 1;
    }
    if (intstat & SINT_STAT_TIM_OUT)                             //timeout disconnect
    {
//        for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) {            //delete disconnected socket id
//            if (socket[i] == socketid) {
//                socket[i] = 0xff;
//                break;
//            }
//        }
//        if(g_flag_debug)
        {
            PRINT("TCP Timeout\r\n");
        }
//        WCHNET_SocketClose(socketid, 0);
        g_net_state.flag = 1;
        // WCHNET_CreateTcpSocket();
    }
#else  /* !NET_SSC_ENABLE — all sockets belong to JSON handler */
    tcp_json_handle_sock_int(socketid, intstat);
#endif
}


#if NET_SSC_ENABLE

void dbn_net_ssc_srv(void)
{
    uint8_t _flag_timestamp = 0;
    static uint32_t _report_counter = 0;        //�ϱ�ʱ�������
    
    //Check net if connect
    if(g_net_state.flag < 3)
    {
        return;
    }
    
    if((g_net_state.intstat & SINT_STAT_RECV) || (g_net_state.intstat & SINT_STAT_CONNECT))
    {
    
        //check if update timestamp
        if(!g_flag_timestamp)
        {
            if(mstick() - _report_counter > 2000)
            {      
                //printf("_will_require_timestamp, _report_counter:%d, mstick:%d\n", _report_counter, mstick());
                dev_get_timestamp_send();
                _report_counter = mstick();
            }
            return;
        }
        
        //send heartbeat
        if(mstick() - _report_counter > 9000)
        {
            _report_counter = mstick();
            dev_send_heartbeat();
        }
    }
    
    
}

void poll_mqtt(void)
{
    if(g_net_state.flag < 2)
    {
        return;
    }
    
//    if(g_mqtt_con_flag == 0)
//    {
//        return;
//    }
//    
    if(flag_mqtt_ping_send)
    {
        flag_mqtt_ping_send = 0;
        flag_mqtt_ping_err++;
        {
            PRINT("send_mqtt_ping:%d\n", flag_mqtt_ping_err);
        }
        MQTT_Pingreq();
    }
}

#endif /* NET_SSC_ENABLE */


/*******************************************************************************
* Function Name  : GetMacAddr
* Description    : ϵͳ��ȡMAC��ַ
* Input          : pMAC:ָ�������洢Mac��ַ�Ļ���
* Output         : None
* Return         : None
*******************************************************************************/
void GetMacAddr(unsigned char *pMAC)
{
	uint8_t transbuf[6],i;
	
	FLASH_GetMACAddress(transbuf);
	for(i=0;i<6;i++)
	{
		pMAC[5-i]=transbuf[i];
	
	}
}


// ��IPv4��ַ�ַ���ת��Ϊ4�ֽڵ�uint8_t���飬�������ϸ�Ĵ�����
int get_ipstr_to_array(char *src, uint8_t *dst) {
    if (src == NULL || dst == NULL) {
        return -1;
    }

    int part_count = 0;
    char *token = NULL;
    char *saveptr = NULL;
    const char *delim = ".";
    char src_copy[16];
    strncpy(src_copy, src, sizeof(src_copy));
    src_copy[15] = '\0';
    
    token = strtok_r(src_copy, delim, &saveptr);
    while (token != NULL && part_count < 4) {
        char *endptr = NULL;
        long val = strtol(token, &endptr, 10);
        if (*endptr != '\0' || val < 0 || val > 255) {
            return -2;
        }
        dst[part_count++] = (uint8_t)val;
        token = strtok_r(NULL, delim, &saveptr);
    }
    if (part_count != 4) {
        return -3;
    }
    if (token != NULL || (saveptr != NULL && *saveptr != '\0')) {
        return -4;
    }
    return 0;
}


#if NET_SSC_ENABLE

void unpack_ssc_count_off(uint8_t socket,uint8_t count_mode, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
{
    uint16_t i,j;
    uint16_t tmplen = 0;
    int serPort = 0;
    
    char *p = (char *)buf;
    char *mBuff = (char *)malloc(400);
    
    if(mBuff == NULL)
    {
//        PRINT("__unpack_net_udp_err, malloc_failed.\n");
        return;
    }
    if(count_mode == 0)
    {
        memset(mBuff, 0, 400);
        simple_parse_json(p, DPG_API_KEY_PARAMS, mBuff);
        tmplen = strlen(mBuff);
        
        if(tmplen == 0)
        {
            free(mBuff);
            return;
        }
        p = mBuff;
        
        reset_temp_guide();
        simple_parse_json(p, DPG_API_KEY_PORT, temp_guide);
        for(i = 0; i < strlen(temp_guide); i++)
        {
            if((serPort > 0x39) || (serPort < 0x30))
            {
                break;
            }
            serPort *= 10;
            serPort += temp_guide[i] - 0x30;
        }
    }
    
    uint8_t qw = 1;
	uint8_t ds = 1;
	uint8_t mode = 0;
    mode |= 1;
    memset(mBuff, 0, 400);
   
    sprintf(mBuff,"{" 
            "\"Method\": \"%s\","
            "\"Code\":0,"
            "\"Message\":\"\","
            "\"Data\":{"
            "\"Ip\": \"%d.%d.%d.%d\","
            "\"Port\": %d,"
            "\"Mac\": \"%02X-%02X-%02X-%02X-%02X-%02X\","
            "\"SubnetMask\": \"%d.%d.%d.%d\","
            "\"Server_Ip\": \"%d.%d.%d.%d\","
            "\"Gateway\": \"%d.%d.%d.%d\","
            "\"Iot_Host\":\"%s\","
            "\"Iot_Port\":%d,"
            "\"UserName\":\"%s\","
            "\"Device_id\":\"%s\","
            "\"Device_type\":\"%d\","
            "\"Area_amount\": %d,"
            "\"Dev_amount\": %d,"
            "\"Dev_mode\":%d,"
            "\"Version\":\"%s,H%s,S%s\""
            "}}", 
            SSC_Code_Count_Off, 
            local_net_cfg.lip[0],local_net_cfg.lip[1],local_net_cfg.lip[2],local_net_cfg.lip[3],
            serPort,
            local_net_cfg.mac[0], local_net_cfg.mac[1], local_net_cfg.mac[2], local_net_cfg.mac[3], local_net_cfg.mac[4], local_net_cfg.mac[5],
            local_net_cfg.sub[0], local_net_cfg.sub[1], local_net_cfg.sub[2], local_net_cfg.sub[3],
            //net_center_info.lssc_ip[0], net_center_info.lssc_ip[1], net_center_info.lssc_ip[2], net_center_info.lssc_ip[3],
            net_center_info.lssc_ip[0], net_center_info.lssc_ip[1], net_center_info.lssc_ip[2], net_center_info.lssc_ip[3],
            local_net_cfg.gw[0], local_net_cfg.gw[1], local_net_cfg.gw[2], local_net_cfg.gw[3],
            iot_net_info.remote_addr, iot_net_info.mqtt_port, iot_net_info.username,
            g_dev_number_str,
            g_dg_sub_dev_type,      //g_dg_device_type,
            qw, ds, mode,
            PRODUCT_MODEL, HARDWARE_VER,FIRMWARE_VER);
    slen = strlen(mBuff);
    
    if(count_mode == 0)
    {
        WCHNET_SocketUdpSendTo(socket, (uint8_t *)mBuff, &slen, ip, COM_LSSC_MESSAGE_UDP_PORT);
    }
    else
    {
        WCHNET_SocketUdpSendTo(SocketId_UDP, (uint8_t *)mBuff, &slen, net_center_info.lssc_ip, COM_LSSC_MESSAGE_UDP_PORT);
    
    }
    
    free(mBuff);
}


void unpack_ssc_device_reset(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
{
    // ��λ�豸
    uint16_t tmplen = 0;
    char *p = (char *)buf;
    char *mBuff = (char *)malloc(512);
    if(mBuff == NULL)
    {
        PRINT("__unpack_ssc_device_net_set_err, malloc_failed.\n");
        return;
    }
    //printf("Recv_net_set:%s\n", buf);
    memset(mBuff, 0, 512);
    simple_parse_json(p, DPG_API_KEY_PARAMS, mBuff);
    tmplen = strlen(mBuff);
    if(tmplen == 0)
    {
        free(mBuff);
        return;
    }
    p = mBuff;
    
    reset_temp_guide();
    simple_parse_json(p, DPG_API_KEY_DEVICE_ID, temp_guide);
    if(strcmp(temp_guide, g_dev_number_str) != 0)
    {
        free(mBuff);
        return;
    }
    
    memset(mBuff, 0, 512);    
    sprintf(mBuff,"{" 
        "\"Method\": \"%s\","
        "\"Code\":0,"
        "\"Message\":\"Success\","
        "\"Data\":{"
        "\"Device_id\":\"%s\""
        "}}", SSC_Code_Dev_Reset, g_dev_number_str);
    slen = strlen(mBuff);
    WCHNET_SocketSend(socket, (uint8_t *)mBuff, &slen);
    
    free(mBuff);
    Delay_Ms(100);
    NVIC_SystemReset();
    
}



void unpack_ssc_tran_sub(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
{
    uint16_t i, j;
    uint16_t tmplen = 0;
    char *p = (char *)buf;
    
    char *mBuff = (char *)malloc(512);
    
    if(mBuff == NULL)
    {
        return;
    }    
    memset(mBuff, 0, 512);
    
    simple_parse_json(p, DPG_API_KEY_PARAMS, mBuff);
    tmplen = strlen(mBuff);
    if(tmplen == 0)
    {
        free(mBuff);
        return;
    }
    p = mBuff;     
    reset_temp_guide();
    simple_parse_json(p, DPG_API_KEY_DEVICE_ID, temp_guide);
    
    if(strcmp(temp_guide, g_dev_number_str) != 0)
    {
        free(mBuff);
        return;
    }
    
    reset_temp_guide();
    uint8_t _dev_type = 0;
    simple_parse_json(p, SSC_Code_Dev_Type, temp_guide);
//    printf("get_dev_type_str:%s\n", temp_guide);
    for(i = 0; i < strlen(temp_guide); i++)
    {
        if((temp_guide[i] >= 0x30) && (temp_guide[i] <= 0x39))
        {
            _dev_type *= 10;
            _dev_type += temp_guide[i] - 0x30;
        }
    }

    
    free(mBuff);
}


void unpack_ssc_timestamp(uint8_t *buf, uint32_t len)
{
    uint16_t tmplen = 0;
    static uint8_t _first = 0;
    char *p = (char *)buf;
    char *mBuff = (char *)malloc(150);
    if(mBuff == NULL)
    {
//        PRINT("__unpack_ssc_collect_cjq_acs_response_err, malloc_failed.\n");
        return;
    }
    //printf("Recv_net_timestamp_response:%s\n", buf);
    memset(mBuff, 0, 150);
    simple_parse_json(p, DPG_API_KEY_DATA, mBuff);
    if(strlen(mBuff) == 0)
    {
        free(mBuff);
        return;
    }
    p = mBuff;
    
    reset_temp_guide();
    simple_parse_json(p, DPG_API_KEY_DEVICE_ID, temp_guide);
    tmplen = strlen(temp_guide);
    if(tmplen == 0)
    {
        free(mBuff);
        return;
    }
    
//    PRINT("\n%s, line:%d, temp:%s, device_id:%s\n", __FUNCTION__, __LINE__, mBuff, g_dev_number_str);
    if(strstr(temp_guide, g_dev_number_str) == NULL)
    {
        free(mBuff);
        return;
    }
    g_activ_counter = 0;    // mstick();		// reset active_counter 
	
    uint32_t _counter = 0;
    uint16_t i = 0;
    reset_temp_guide();
    simple_parse_json(p, KEY_CODE_Time_Counter, temp_guide);    
    //printf("timestampStr:%s, p:%s\n", temp_guide, p);
    for(i = 0; i < strlen(temp_guide); i++)
    {
        if((temp_guide[i] > 0x39) || (temp_guide[i] < 0x30))
        {
            break;
        }
        _counter *= 10;
        _counter += temp_guide[i] - 0x30;
    }
        
    free(mBuff);
    
//    uint32_t _c_counter = get_rtc_counter();
    
    if(_first == 0)
    {
        //printf("before_settime,rtc_counter:%d\n", get_rtc_counter());
        _first = 1;
                    
        uint16_t py,pmon,pday, phour, pmin, psec ;
//        RTC_GetTime(&py,&pmon, &pday, &phour, &pmin, &psec);
//        printf("\nGet_time %d-%d-%d %d:%d:%d\n", py, pmon, pday, phour, pmin, psec);
//        set_rtc_from_timecount(_counter);
//        RTC_GetTime(&py,&pmon, &pday, &phour, &pmin, &psec);
//        printf("\nafter_settime_Get_time %d-%d-%d %d:%d:%d\n", py, pmon, pday, phour, pmin, psec);
//        printf("after_settime, rtc_counter:%d\n", get_rtc_counter());
    }
    
    if(g_flag_timestamp == 0)
    {
        g_flag_timestamp = 1;
        unpack_ssc_count_off(SocketId_UDP, 1, NULL, 0, NULL, 0);
    }
    else
    {
//        rcv_acs_dus_report_reponse();
    }
}



void manage_tcp_message(uint8_t socket, uint8_t *buf, uint32_t len)
{
    uint16_t tmplen = 0;
    char *p = (char *)buf;
    
    char *mMethod = (char *)malloc(20);
    if(mMethod == NULL)
    {
//        PRINT("__unpack_net_udp0_err, malloc_failed.\n");
        return;
    }
    
    memset(mMethod, 0, 20);
    simple_parse_json(p, DPG_API_KEY_METHOD, mMethod);
    
    if(strstr(mMethod, SSC_Code_TimeStamp) != NULL)
    {
        unpack_ssc_timestamp(buf, len);
    }
    
    free(mMethod);
}

void manage_udp_message(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len)
{
    uint16_t tmplen = 0;
    char *p = (char *)buf;
    
    char *mMethod = (char *)malloc(20);
    if(mMethod == NULL)
    {
//        PRINT("__unpack_net_udp0_err, malloc_failed.\n");
        return;
    }
    
    memset(mMethod, 0, 20);
    simple_parse_json(p, DPG_API_KEY_METHOD, mMethod);
    
   
    if(strstr(mMethod, SSC_Code_Count_Off) != NULL)
    {
        unpack_ssc_count_off(socket, 0, ip, port, buf, len);
    }
    else if(strstr(mMethod, SSC_Code_Dev_Reset) != NULL)
    {
        unpack_ssc_device_reset(socket, ip, port, buf, len);
    }
//    else if(strstr(mMethod, SSC_Code_Device_Net_Set) != NULL)
//    {
//        unpack_ssc_device_net_set(socket, ip, port, buf, len);
//    }
    else if(strstr(mMethod, SSC_Code_Tran_Sub) != NULL)
    {
        unpack_ssc_tran_sub(socket, ip, port, buf, len);
    }
//    else if(strstr(mMethod, SSC_Code_Radar_Reset) != NULL)
//    {
//        unpack_ssc_radar_reset(socket, ip, port, buf, len);
//    }
    
    
    free(mMethod);
    
}



void manage_mqtt_recv_message(char * msg, int length)
{
    uint8_t i = 0;
    uint16_t tmplen = 0;
    // Validate input parameters
    if(msg == NULL || length <= 0) {
        PRINT("Invalid MQTT message parameters\n");
        return;
    }

    reset_temp_guide();
    simple_parse_json(msg, DPG_API_KEY_METHOD, temp_guide);
    
    if(strlen(temp_guide) == 0)
    {
        PRINT("\nmethod is none..\n");
        return;
    }
    PRINT("Rcv_Dis_LED_m:%s\n", temp_guide);
    if(strstr(temp_guide, "Heartbeat") != NULL)
    {
        dev_response_heartbeat(NULL);
    }
     else {
        PRINT("Unknown MQTT method: %s\n", msg);
    }
}

#endif /* NET_SSC_ENABLE */





/*********************************************************************
 * @fn      WCHNET_HandleGlobalInt
 *
 * @brief   Global Interrupt Handle
 *
 * @return  none
 */
void WCHNET_HandleGlobalInt(void)
{
    uint8_t intstat;
    uint16_t i;
    uint8_t socketint;

    intstat = WCHNET_GetGlobalInt();                              //get global interrupt flag
    if (intstat & GINT_STAT_UNREACH )                              //Unreachable interrupt
    {
        PRINT("GINT_STAT_UNREACH\r\n");
    }
    if (intstat & GINT_STAT_IP_CONFLI)                            //IP conflict
    {
        PRINT("GINT_STAT_IP_CONFLI\r\n");
    }
    if (intstat & GINT_STAT_PHY_CHANGE)                           //PHY status change
    {
        i = WCHNET_GetPHYStatus();
        if (i & PHY_Linked_Status)
            PRINT("PHY Link Success\r\n");
    }
    if (intstat & GINT_STAT_SOCKET)                               //socket related interrupt
    {                             
        for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) {
            socketint = WCHNET_GetSocketInt(i);
            if (socketint) {
                PRINT("SockInt: sock=%d stat=0x%02X\n", i, socketint);
                WCHNET_HandleSockInt(i, socketint);
            }
        }
    }
}



void net_srv_init(void)
{
    uint8_t i;
    
    if(g_net_state.flag == 0)
    {
        i = ETH_LibInit(local_net_cfg.lip, local_net_cfg.gw, local_net_cfg.sub, local_net_cfg.mac);          //Ethernet library initialize
        mStopIfError(i);
        if (i == WCHNET_ERR_SUCCESS)
        {
            PRINT("WCHNET_LibInit Success\r\n");
            g_net_state.flag = 1;
            
            #if KEEPLIVE_ENABLE                                              //Configure keeplive parameters
            {
                struct _KEEP_CFG cfg;

                cfg.KLIdle = 20000;
                cfg.KLIntvl = 15000;
                cfg.KLCount = 9;
                WCHNET_ConfigKeepLive(&cfg);
            }
            #endif
#if NET_SSC_ENABLE
            memset(socket, 0xff, WCHNET_MAX_SOCKET_NUM);
#endif
            
        }
        
    }
    
    if(g_net_state.flag == 1)
    {
#if NET_SSC_ENABLE
        WCHNET_CreateUdpSocket();
#endif
        tcp_json_srv_init();        // Start JSON protocol TCP listener on port 5960
#if !NET_SSC_ENABLE
        g_net_state.flag = 2;       // Skip SSC init, advance state directly
#endif
    }
    
    
}

