
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef CFG_DEV_TYPE_LAND_CA
/* 标准C库头文件. */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <time.h>

/* 用户代码头文件. */
#include "cmd.h"
#include "fifo.h"
#include "ca_main.h"
#include "ca_csg.h"
#include "debug.h"
#include "ca_cau.h"
#include "ca_dbg.h"
#include "ca_param.h"
#include "ca_network.h"


/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private typedef -----------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
csg_t csg;
int csg_reconn_times = 0;
extern int cau_collect_flag;
//extern int upg_state;
//char csg_deliver_path[128] = {0};

/* Private function prototypes -----------------------------------------------*/
extern void _csg_server_set(int32_t ip, uint16_t port);

/* Internal functions --------------------------------------------------------*/
CMD(csg_server_set,
    csg_server_set_cmd,
    "csg server A.B.C.D <1-65535>",
    "Csg\n"
    "Server\n"
    "IPv4 address\n"
    "UDP port\n")
{
    _csg_server_set(inet_addr((char*)argv[0]), strtol((char*)argv[1], NULL, 10));
    
    return CMD_SUCCESS;
}

CMD(socket_close,
    socket_close_cmd,
    "socket_close",
    "close socket fd\n")
{
    //_csg_server_set(inet_addr((char*)argv[0]), strtol((char*)argv[1], NULL, 10));
    printh("socket fd=%d closed\r\n", csg.fd);
    close(csg.fd);
    csg.fd = -1;
    
    return CMD_SUCCESS;
}


void _csg_server_set(int32_t ip, uint16_t port)
{
    /* 比较配置 */
    if (csg.server_ip != ip
        || csg.server_port != port)
    {
        csg.server_ip = ip;
        csg.server_port = port;

        /* 发送数据. */
        bzero(&csg.server, sizeof(csg.server));
        csg.server.sin_family = AF_INET;
        csg.server.sin_addr.s_addr = csg.server_ip;
        csg.server.sin_port = htons(csg.server_port);
    }
}

/* 配置保存函数. */
int _csg_config_save(vty_t* vty)
{
    int16_t i = 0;
    struct in_addr addr;

    addr.s_addr = csg.server_ip;
    vty_out(vty, "csg server %s %d%s", inet_ntoa(addr), csg.server_port, VTY_NEWLINE);
    i++;

    return i;
}

#if 0
/* 校验收到包的包头, 长度, 校验码. */
int32_t _csg_pkt_check(char *pkt, int32_t len)
{
    csg_pkt_head_t *head = (csg_pkt_head_t*)pkt;
    csg_pkt_tail_t *tail = (csg_pkt_tail_t*)(pkt + len - CSG_TAIL_LEN);
    uint16_t checksum = 0;
    uint16_t i = 0;

    if (head->head != 0x55aa)
    {
        DBG(DBG_M_PD_CSG_ERR, "Pkt head %x error!\r\n", head->head);
        return E_ERROR;
    }
    if( tail->tail != 0x5a5a)
    {
        DBG(DBG_M_PD_CSG_ERR, "Pkt tail %x error!\r\n", tail->tail);
        return E_ERROR;
    }

    if (head->len != (len - CSG_TOTLE_LEN))
    {
        DBG(DBG_M_PD_CSG_ERR, "Pkt len %d(%d) error!\r\n", len - CSG_TOTLE_LEN, head->len);
        return E_ERROR;
    }
    
    for (i = CSG_HEAD_LEN; i < len - CSG_TAIL_LEN; i++)
    {
        checksum += (uint8_t)pkt[i];
    }
    if (checksum != tail->checksum)
    {
        DBG(DBG_M_PD_CSG_ERR, "Pkt checksum %x(%x) error!\r\n", checksum, tail->checksum);
        return E_ERROR;
    }
    
    return E_NONE;
}
#endif

/* 包头填充. */
void _csg_head_init(char *pkt, uint16_t cmd, uint16_t len)
{
    LandPkHead *head = (LandPkHead *)pkt;
    memcpy(head, csg.buf_send, sizeof(LandPkHead));

    head->Head = START_FLAG;
    head->Len = len + LandPackHeadTailLen;
    head->Type = cmd;
    head->ID = sysctrl.dev_hex_id;
    //head->LifeCnt = 1;
    head->gNum = 1;
    head->gNumIndex = 0;
}

void _csg_cheaksum(char *pkt, uint16_t len)
{ 
    unsigned int checksum = 0;
    unsigned int *ptmp = (unsigned int *)(pkt + 4);
    int i;
    int tlen = (len + 16) >> 2;

    for (i = 0; i < tlen; i++)
    {
        checksum += *ptmp;
        ptmp++;
    }
    
    LandPkTail *tail = (LandPkTail *)(pkt + sizeof(LandPkHead) + len);
    tail->CheckSum = checksum;
    tail->EndFlag1 = END_FLAG;   
}


int _csg_socket_open(unsigned int uiIp, unsigned short usPort)
{
    int sock;  
    int opt;
    struct timeval timeout;
    socklen_t optlen;
    int ret;
    
    /* 创建 socket. */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        log_err(LOG_DEBUG, "ERROR at socket create return %s!", safe_strerror(errno));
        return E_SYS_CALL;
    }
    LOG("sock=%d", sock);

    opt = 1024*500;
    optlen = sizeof(opt);
    setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &opt, optlen);

    //超时时间
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;

    optlen = sizeof(timeout);
    ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, optlen);
    if (ret == -1) 
    {
        LOG("设置SOCKET选项: [%d]%s 失败",errno, strerror(errno));
        close(sock);
        return -1;
    }
    //set_nonblock(sock);

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
#if 0
    addr.sin_addr.s_addr = inet_addr("192.168.1.20");
#else
    addr.sin_addr.s_addr = uiIp;//inet_addr(ip);
#endif
    addr.sin_port = htons(usPort);
    ret = connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
    if (ret == 0)
        return sock;
    if (errno == EINPROGRESS || errno == EWOULDBLOCK)
    {
        fd_set wfds;
        FD_ZERO(&wfds);
        FD_SET(sock, &wfds);

        struct timeval tv = { 0 };
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        ret = select(sock + 1, NULL, &wfds, NULL, &tv);
        if (ret == 0)
        {
            LOG("connect timeout!\n");
        }
        else if (ret > 0)
        {
            if (FD_ISSET(sock, &wfds))
            {
                return sock;
            }
        }
    }
    LOG("errno[%d:%s]", errno, strerror(errno));
    
    close(sock);
    sock = -1;
    return sock;
}

int _csg_connect()
{
    if (csg.fd <= 0)
    {
        csg.fd = _csg_socket_open(csg.server_ip, csg.server_port);
        LOG("fd=%d", csg.fd);
        if (csg.fd <= 0)
        {
            csg.fd = -1;
            return -1;
        }        
    }
    return 0;
}

int _csg_recv_packet(char *buf)
{
    char *precvbuf = buf;
    int rd_size;
    rd_size = recv(csg.fd, precvbuf, sizeof(LandPkHead), 0);
    if (rd_size < 0)
    {
        LOG("recv faile.errno[%d]:%s", errno, strerror(errno));
        return -1;
    }

    LandPkHead *head = (LandPkHead *)precvbuf;
    
    if(head->Head != 0x5555AAAA || (head->Len != 64 && head->Len != 1052))
    {
        LOG("朗德协议客户端接收到错误数据包头, FD = %d",csg.fd);
        return -1;
    }

    int data_size = head->Len - sizeof(LandPkHead);
    precvbuf += sizeof(LandPkHead); 
    
    rd_size = recv(csg.fd, precvbuf, data_size, 0);
    if (rd_size < 0)
    {
        LOG("recv faile.errno[%d]:%s", errno, strerror(errno));
        return -1;
    } 
    return rd_size + sizeof(LandPkHead);
}

int _csg_send_packet(uint16_t cmd, char *data, uint16_t len)
{
    int32_t rv = 0;
    char pkt[2048] = {0};
    _csg_head_init(pkt, cmd, len);
    
    memcpy(pkt + sizeof(LandPkHead), data, len);
    _csg_cheaksum(pkt, len);

    rv = send(csg.fd, pkt, len + LandPackHeadTailLen, 0);
    if (rv < 0)
    {
        DBG(DBG_M_CA_CSG_ERR, "Sendto return %s!\r\n", safe_strerror(errno));
        close(csg.fd);
        csg.fd = -1;
        return E_SYS_CALL;
    }

    return E_NONE;
}

int _csg_response_force_id()
{
    int len = 36;
    char data[36] = {0};
    _csg_send_packet(Res_ForceReqID, data, len);
    return 0;
}

int _csg_response_realtime_data(int sendtype)
{
    //1 填写8相电流 3相电压数据 
    float cauValues[11] = {0};
    debug_pkt_realdata_t realdata = {0}; 
    
    _dbg_get_current_cau_values(cauValues);
    
    realdata.proVer = 0x00000363;
    time_t t;
    time(&t);
    realdata.utc = t - SHIQUCHA;
    realdata.powertatus = 0;
    realdata.batteryStatus = 1;
    realdata.vbat = pwr.vbat;
    realdata.vsc = pwr.vsc;
    realdata.vout = pwr.vout;

    RtdPack_t *prtd = &realdata.rtd;
    prtd->StartFlag1 = sysctrl.dev_hex_id;
    prtd->FarmeType = sendtype;
    prtd->RunSecCnt = t - sysctrl.start_time;
    prtd->Local_Vbat = pwr.vbat;
    prtd->RMS_Ia = cauValues[0];
    prtd->RMS_Ib = cauValues[1];
    prtd->RMS_Ic = cauValues[2];
    prtd->RMS_In = cauValues[3];
    prtd->RMS_Ground = cauValues[4];
    prtd->RMS_rIa = cauValues[5];
    prtd->RMS_rIb = cauValues[6];
    prtd->RMS_rIc = cauValues[7]; 
    prtd->RMS_Va = cauValues[8];
    prtd->RMS_Vb = cauValues[9];
    prtd->RMS_Vc = cauValues[10];
    prtd->endFlag = 0x0A0D;
    DBG(DBG_M_CA_CSG, "RMS_Ia=%f \n", prtd->RMS_Ia);
    DBG(DBG_M_CA_CSG, "RMS_Ib=%f \n", prtd->RMS_Ib);
    DBG(DBG_M_CA_CSG, "RMS_Ic=%f \n", prtd->RMS_Ic);
    DBG(DBG_M_CA_CSG, "RMS_In=%f \n", prtd->RMS_In);
    DBG(DBG_M_CA_CSG, "RMS_Ground=%f \n", prtd->RMS_Ground);
    DBG(DBG_M_CA_CSG, "RMS_rIa=%f \n", prtd->RMS_rIa);
    DBG(DBG_M_CA_CSG, "RMS_rIb=%f \n", prtd->RMS_rIb);
    DBG(DBG_M_CA_CSG, "RMS_rIc=%f \n", prtd->RMS_rIc);

    WarringPack_t *pwar = &realdata.war;
    pwar->StartFlag1 = sysctrl.dev_hex_id; 
    pwar->endFlag = 0x0A0D;
    pwar->RunSecCnt = t - sysctrl.start_time;
    
    _csg_send_packet(Res_ReqRTD2, (char *)&realdata, sizeof(debug_pkt_realdata_t));
    return 0;
}

void _csg_set_system_time(unsigned int time)
{
    struct tm *p =localtime((time_t *)&time); 
    char buf[128] = {0};          
    sprintf(buf,"date -s \"%d-%d-%d %d:%d:%d\"",1900+p->tm_year,1+p->tm_mon,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
    LOG("%s U32:0x%08x",buf,time);
    system(buf);
    system("hwclock -w");
}


int _csg_set_utc_time(char *databuf, int datalen)
{
    if (datalen != sizeof(csg_utc_t))
    {
        int result = 0;
        DBG(DBG_M_CA_CSG_ERR, "msg reallen:%d,expect len:%d\n", datalen, sizeof(csg_utc_t));
        return  _csg_send_packet(Res_SetUTC, (char *)&result, sizeof(result));
    }

    csg_utc_t *msg = (csg_utc_t *)databuf;
    unsigned int stime = msg->utc + SHIQUCHA;
    
    if (abs(stime - time(NULL)) > 60)
    {
        unsigned int tmp = time(NULL) - sysctrl.start_time;
        _csg_set_system_time(stime);
        sysctrl.start_time = time(NULL) - tmp;
    }

    csg_utc_t ack = {0};
    ack.utc = time(NULL) - SHIQUCHA;
    _csg_send_packet(Res_SetUTC, (char *)&ack, sizeof(csg_utc_t));
    return 0;
}

void _csg_reboot_system()
{
    unsigned int ack[9] = {0};
    _csg_send_packet(Res_Reboot, (char *)&ack, sizeof(ack));
    reboot_system(LOG_CSG, BOOT_REMOTE_RESET);
}

int _csg_get_system_config()
{
    struct in_addr addr;
    
    strncpy((char *)pparam_config->gateway.DeviceNum, host.name, 15);

    inet_pton(AF_INET, device_info.host_ip, &addr);
    memcpy(pparam_config->gateway.LocalIP1, &addr.s_addr, 4);

    memcpy(pparam_config->gateway.ServerIP1, &csg.server.sin_addr.s_addr, 4);
    pparam_config->gateway.ServerIP1_Port = csg.server_port;

    char buf[64] = {0};
    sprintf(buf, "V%s", host.version);
    strcpy((char *)pparam_config->gateway.reserved, buf);
    
    _csg_send_packet(Res_ReqSysCfg, (char *)&pparam_config->gateway, sizeof(GateWay_t));
    return 0;
}

int _csg_set_system_config(char *databuf, int datalen)
{
    if (datalen != sizeof(GateWay_t))
    {
        int result = 0;
        DBG(DBG_M_CA_CSG_ERR, "msg reallen:%d,expect len:%d\n", datalen, sizeof(GateWay_t));
        return  _csg_send_packet(Res_SetSysCfg, (char *)&result, sizeof(result));
    }

    GateWay_t *pcfg = (GateWay_t *)databuf;
    if (strncmp((char *)pcfg->apn, (char *)pparam_config->gateway.apn, 
            sizeof(pparam_config->gateway.apn)) != 0)
    {
        _network_change_apn((char *)pcfg->apn);
    }

    strncpy(host.name, (char *)pcfg->DeviceNum, 15);
    sysctrl.dev_hex_id = dev_id_2_hex(host.name);

    
    sprintf(device_info.host_ip, "%d.%d.%d.%d", pcfg->LocalIP1[0], 
            pcfg->LocalIP1[1], pcfg->LocalIP1[2], pcfg->LocalIP1[3]);

    char serverip[16] = {0};
    sprintf(serverip, "%d.%d.%d.%d", pcfg->ServerIP1[0], 
        pcfg->ServerIP1[1], pcfg->ServerIP1[2], pcfg->ServerIP1[3]);
    csg.server_ip = inet_addr(serverip);
    LOG("serverip=0x%x", csg.server_ip);
    LOG("%d %d %d %d", csg.server_ip & 0xff, (csg.server_ip >> 8) & 0xff, 
        (csg.server_ip >> 16) & 0xff, (csg.server_ip >> 24) & 0xff);
    csg.server_port = (uint16_t)pcfg->ServerIP1_Port;
    LOG("CommunicationMode=%d\n", pcfg->CommunicationMode);
    
    memcpy(&pparam_config->gateway, databuf, datalen);

    param_save();

    vtysh_config_save();
    uint8_t mac[MAC_ADDR_LEN] = {0};
    mac_generate_from_ip(device_info.host_ip, mac);
    memcpy(device_info.mac, mac, MAC_ADDR_LEN);
    vtysh_eth0_save();
    vtysh_device_save();
    reboot_system(LOG_DEBUG, BOOT_REMOTE_IP_CHANGE);
    return 0;
}


int _csg_get_device_config()
{
    _csg_send_packet(Res_ReqDevCfg, (char *)&pparam_config->landHexCfg, sizeof(LandDevCfg_t));
    return 0;
}

int _csg_set_device_config(char *databuf, int datalen)
{
    if (datalen != sizeof(LandDevCfg_t))
    {
        int result = 0;
        DBG(DBG_M_CA_CSG_ERR, "msg reallen:%d,expect len:%d\n", datalen, sizeof(LandDevCfg_t));
        return  _csg_send_packet(Res_SetDevCfg, (char *)&result, sizeof(result));
    }

    memcpy(&pparam_config->landHexCfg, databuf, sizeof(LandDevCfg_t));

    param_save();
    return 0;
}

int _csg_get_cau_cfg()
{
    char buf[1024] = {0};
    int i;
    int len;
    for (i = 0; i < 24; i++)
    {
        memcpy(buf + i * 32, &pparam_config->cauParam[i], 24);
    }
    len = 32 * 24;
    _csg_send_packet(Res_ReqCauCfg, buf, len);
    return 0;
}

int _csg_set_cau_cfg(char *databuf, int datalen)
{
    int i;
    
    if (datalen != 1024)
    {
        DBG(DBG_M_CA_CSG_ERR, "msg reallen:%d,expect len:1024\n", datalen);
        int result = 0;
        return  _csg_send_packet(Res_SetCauCfg, (char *)&result, sizeof(result));
    }

    for (i = 0; i < 24; i++)
    {
        memcpy(&pparam_config->cauParam[i], databuf + i * 32, 24);
    }
    param_save();
    
    int result = 1;
    return  _csg_send_packet(Res_SetCauCfg, (char *)&result, sizeof(result));
}

int _csg_upgrade_arm(char *databuf, int datalen, LandPkHead *head)
{
    csg_upgrade_response_t ack = {0};
    static FILE *upgradefp = NULL;
    static int file_len = 0;
    char upgrade_file[128] = {0};
    
    if (datalen != sizeof(csg_upgrade_t))
    {
        DBG(DBG_M_CA_CSG_ERR, "msg reallen:%d,expect len:%d\n", datalen, sizeof(csg_upgrade_t));
        ack.status = 1;
        return _csg_send_packet(Res_AppUpdate, (char *)&ack, sizeof(ack));
    }

    csg_upgrade_t *pmsg = (csg_upgrade_t *)databuf;
    LOG("len=%d gNum=%d gNumIndex=%d\n", pmsg->len, head->gNum, head->gNumIndex);

    if (head->gNumIndex == 0)
    {
        if (upgradefp)
        {
            fclose(upgradefp);
            upgradefp = NULL;
        }
        
        if (upgradefp == NULL)
        {
            sprintf(upgrade_file, "%s/%s", UPDATE_FILE_PATH, UPDATE_TMP_FILE_NAME);
            upgradefp = fopen(upgrade_file, "wb");
            if (upgradefp == NULL)
            {
                printh("open file error[%d]:%s", errno, strerror(errno));
                return -1;
            }
        }
    }

    int size = pmsg->len;
    int wrlen = fwrite(pmsg->data, 1, size, upgradefp);
    if (wrlen != size)
    {
        size = size - wrlen;
        wrlen = fwrite(pmsg->data+wrlen, 1, size, upgradefp);
        printh("write again:size=%d, wrlen=%d\n", size, wrlen);
        file_len += wrlen;
    }
    file_len += wrlen;

    if (head->gNum == head->gNumIndex + 1)
    {
        fclose(upgradefp);
        upgradefp = NULL;
        ack.status = 0;
        _csg_send_packet(Res_AppUpdate, (char *)&ack, sizeof(ack));
        LOG("update success!!!");
        char cmd[128] = {0};
        snprintf(cmd, 127, "mv %s/%s %s/%s", UPDATE_FILE_PATH, UPDATE_TMP_FILE_NAME,
                                                UPDATE_FILE_PATH, UPDATE_FILE_NAME);
        system(cmd);
        system("sync");
        printh("ls -l | grep update*\n");
        system("ls -l | grep update*");
        reboot_system(LOG_DEBUG, BOOT_LOCAL_ARM_UPGRADE);
    }
    ack.status = 0;
    _csg_send_packet(Res_AppUpdate, (char *)&ack, sizeof(ack));
    return 0;
}

#if 0
int _csg_upload_realtime_data()
{
    LOG("\n");
    RtdPack_t rtd = {0}; 

    //1 填写8相电流 3相电压数据 
    float cauValues[11] = {0};
    _dbg_get_current_cau_values(cauValues);
    
    rtd.StartFlag1 = 601000001;
    rtd.FarmeType = 0;
    time_t t;
    time(&t);
    rtd.RunSecCnt = t - sysctrl.start_time;
    rtd.Local_Vbat = 0;
    rtd.RMS_Ia = cauValues[0];
    rtd.RMS_Ib = cauValues[1];
    rtd.RMS_Ic = cauValues[2];
    rtd.RMS_In = cauValues[3];
    rtd.RMS_Ground = cauValues[4];
    rtd.RMS_rIa = cauValues[5];
    rtd.RMS_rIb = cauValues[6];
    rtd.RMS_rIc = cauValues[7]; 
    rtd.RMS_Va = cauValues[8];
    rtd.RMS_Vb = cauValues[9];
    rtd.RMS_Vc = cauValues[10];
    rtd.endFlag = 0x0A0D;
    _csg_send_packet(Res_ReqRTD2, NULL, (char *)&rtd, sizeof(RtdPack_t));
    return 0;
}
#endif


char *time2str(char *str)
{
    time_t t;
    struct tm *ptm;
    time(&t);
    ptm = localtime(&t);
    sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d",ptm ->tm_year+1900,ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    return str;
}
int _csg_recv_process(char *buf)
{
    if (_csg_recv_packet(buf) < 0)
    {
        return -1;
    }

    LandPkHead *head = (LandPkHead *)buf;
    //----------------------------
    char str[128] = {0};
    time2str(str);
    int dataLen = head->Len - LandPackHeadTailLen;
    char *pdata = buf + sizeof(LandPkHead);
    DBG(DBG_M_CA_CSG, "%s cmd=0x%x len=%d\n", str, head->Type, dataLen);
    //----------------------------
    switch (head->Type)
    {
    case Cmd_ForceReqID:
        _csg_response_force_id();
        break;
    case Cmd_ReqRTD2:
        _csg_response_realtime_data(1);
        break;
    case Cmd_SetUTC:
        _csg_set_utc_time(pdata, dataLen);
        break;
    case Cmd_Reboot:
        _csg_reboot_system();
        break;
    case Cmd_ReqSysCfg:
        _csg_get_system_config();
        break;
    case Cmd_SetSysCfg:
        _csg_set_system_config(pdata, dataLen);
        break;
    case Cmd_ReqDevCfg:
        _csg_get_device_config();
        break;
    case Cmd_SetDevCfg:
        _csg_set_device_config(pdata, dataLen);
        break;
    case Cmd_ReqCauCfg:
        _csg_get_cau_cfg();
        break;
    case Cmd_SetCauCfg:
        _csg_set_cau_cfg(pdata, dataLen);
        break;
    case Cmd_AppUpdate:
        _csg_upgrade_arm(pdata, dataLen, head);
        break;
    default:
        break;
    }
    return 0; 
}

void *_csg_recv_handle()
{
    char *buf = csg.buf_send;
    while (1)
    {
        if (csg.fd > 0)
        {
            _csg_recv_process(buf);
        }
        usleep(100*1000);
    }
}

void *_csg_manage_handle(void *arg)
{
    unsigned int cur_time, diff_time, last_time;

    cur_time = time(NULL);
    last_time = cur_time;
    while (1)
    {
        if (pparam_config->gateway.ServerIP1[0] == 0 
            || pparam_config->gateway.ServerIP1[1] == 0
            || pparam_config->gateway.ServerIP1[2] == 0
            || pparam_config->gateway.ServerIP1[3] == 0 
            || pparam_config->gateway.ServerIP1_Port == 0
            || pparam_config->gateway.CommunicationMode != 1)
        {
            sleep(1);
            DBG(DBG_M_CA_CSG_ERR, "param error: ServerIP1:%d.%d.%d.%d ServerIP1_Port:%d CommunicationMode:%d\r\n", 
            pparam_config->gateway.ServerIP1[0], pparam_config->gateway.ServerIP1[1], 
            pparam_config->gateway.ServerIP1[2], pparam_config->gateway.ServerIP1[3], 
            pparam_config->gateway.ServerIP1_Port, pparam_config->gateway.CommunicationMode);
            continue;
        }
        if (_csg_connect() < 0)
        {
            csg_reconn_times++;
            sleep(10);
            continue;
        }
        csg_reconn_times = 0;
        
        cur_time = time(NULL);
        diff_time = CPUMS_DIFF(last_time, cur_time);
        //LOG("diff_time=%d uploadSpace = %d", diff_time, pparam_config->gateway.uploadSpace);
        //if (diff_time >= pparam_config->gateway.uploadSpace)
        if (cau_collect_flag == 1)
        {
            cau_collect_flag = 0;
            last_time = cur_time;
            DBG(DBG_M_CA_CSG, "auto send:_csg_response_realtime_data");
            _csg_response_realtime_data(0);
        }
        
        usleep(200*1000);
    }
}


/* 后台通讯公共部分初始化. */
int32_t _csg_handle_init_common(void)
{
    //struct sockaddr_in server;
    struct sched_param param;
    pthread_attr_t attr;
    pthread_t pid;
    int32_t rv = 0;

#if 0
    /* 配置线程RR调度, 优先级70 */
    pthread_attr_init(&attr);
    param.sched_priority = 70;
    pthread_attr_setschedpolicy(&attr, SCHED_RR);
    pthread_attr_setschedparam(&attr, &param);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    rv = pthread_create(&pid, &attr, _csg_send_handle, NULL);
    if (rv != 0)
    {
        log_err(LOG_CSG, "PD can't create pthread %d!", rv);
        return E_SYS_CALL;
    }
    else
    {
        thread_m_add("CSG_SEND", pid);
    }
    pthread_attr_destroy(&attr);
#endif

    /* 配置线程RR调度, 优先级70 */
    pthread_attr_init(&attr);
    param.sched_priority = 70;
    pthread_attr_setschedpolicy(&attr, SCHED_RR);
    pthread_attr_setschedparam(&attr, &param);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    rv = pthread_create(&pid, &attr, _csg_recv_handle, NULL);
    if (rv != 0)
    {
        log_err(LOG_CSG, "PD can't create recv pthread %d!", rv);
        return E_SYS_CALL;
    }
    else
    {
        thread_m_add("CSG_RCVE", pid);
    }
    pthread_attr_destroy(&attr);

    /* 配置线程RR调度, 优先级70 */
    pthread_attr_init(&attr);
    param.sched_priority = 70;
    pthread_attr_setschedpolicy(&attr, SCHED_RR);
    pthread_attr_setschedparam(&attr, &param);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    rv = pthread_create(&pid, &attr, _csg_manage_handle, NULL);
    if (rv != 0)
    {
        log_err(LOG_CSG, "PD can't create manage pthread %d!", rv);
        return E_SYS_CALL;
    }
    else
    {
        thread_m_add("CSG_MANAGE", pid);
    }
    pthread_attr_destroy(&attr);

    return E_NONE;
}


/* Interface functions -------------------------------------------------------*/
/* 后台通讯模块初始化. */
int32_t csg_handle_init(void)
{
    int32_t rv = 0;

    memset(&csg, 0, sizeof(csg_t));
    csg.fd = -1;
    
    /* 初始化模块. */
    LD_E_RETURN(DBG_M_CA_CSG_ERR, _csg_handle_init_common());

    cmd_install_element(CONFIG_NODE, &csg_server_set_cmd);
    cmd_install_element(ENABLE_NODE, &socket_close_cmd);

    /* 注册配置保存函数 */
    rv = cmd_config_node_config_register(CONFIG_PRI_CSG, _csg_config_save);
    if (rv != E_NONE)
    {
        log_err(LOG_CSG, "Command save register ERROR %d!", rv);
        return rv;
    }

    return E_NONE;
}

#endif

