#include "common_func.hpp"
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/types.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/sockios.h>
#include <linux/rtc.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <stdlib.h>
#include <memory.h>
#include <string>
#include <list>
#include <iostream>
#include <fstream>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <memory.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "dirent.h"
#include <iconv.h>
#include <termios.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/xpressive/xpressive_dynamic.hpp>
#include <zlog.h>
#include "global.hpp"
#include "dbaccess/sql_db.hpp"


#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
#define MAX_WAIT_TIME 1
#define MAX_NO_PACKETS 1
#define ICMP_HEADSIZE 8
#define PACKET_SIZE 4096
struct timeval tvsend, tvrecv;
struct sockaddr_in dest_addr, recv_addr;
int sockfd;
pid_t pid;
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];

static boost::mutex s_config_mu;

extern zlog_category_t *zct;
extern zlog_category_t *zbt;

std::string GetLocalTimeWithMs(void) {
    std::string defaultTime = "19700101000000000";
    try {
        struct timeval curTime;
        gettimeofday(&curTime, NULL);
        int milli = curTime.tv_usec / 1000;

        char buffer[80] = {0};
        struct tm nowTime;
        localtime_r(&curTime.tv_sec, &nowTime); //闂傚倷鑳堕、濠傗枖濞戙垺鏅濋柕�?濇�?�椤�?粙�?�洪鈧粔瀵哥矆閸℃稒鐓欐繛鍫濈仢閺�??喖鏌ｉ敐澶�?�喚闁哄�?绋掔换婵�?礋椤愵澀�?梻浣割吔閺夊灝�?�?悗瑙�?礃椤ㄥ﹥淇婇悜钘壩ч柛婊€鐒︿簺闂傚倷绀侀幖�?�﹀�?閸愭祴鏋栨繛鎴欏灩閸ㄥ倿骞�?ǎ顒€濡介柣鎾亾闁�?��?�绠嶉崕鍗灻�?敃鍌涘仼闂侇剙绉甸悡鏇㈡煙闁箑澧柛锝�?秺閺岋絾骞婇柛鏂跨Ф缁瑦寰勯幇鍨櫍闂侀潧臎閸滀焦啸缂傚倸鍊烽悞锕€鐣峰Ο琛℃灃闁哄洢鍨归悡婵�?煠濞村鏉归柛瀣崌閹兘鏌囬敂鍙�?箓�?�洪崨濠�?嚂闁瑰嚖鎷�
        strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", &nowTime);

        char currentTime[84] = {0};
        snprintf(currentTime, sizeof(currentTime), "%s%03d", buffer, milli);
        return currentTime;
    } catch (...) {
        zlog_warn(zct, "GetLocalTimeWithMs failed, use default time");
        return defaultTime;
    }
}

int code_convert(const char *from_charset, const char *to_charset, char *inbuf, size_t inlen, char *outbuf, size_t outlen) {
    iconv_t cd;
    char **pin = &inbuf;
    char **pout = &outbuf;
    cd = iconv_open(to_charset, from_charset);
    if (cd == 0) {
        zlog_warn(zct, "iconv_open failed");
        return -1;
    }

    memset(outbuf, 0, outlen);
    if ((int)iconv(cd, pin, &inlen, pout, &outlen) == -1) {
        zlog_warn(zct, "iconv failed");
        iconv_close(cd);
        return -2;
    }
    iconv_close(cd);
    *pout = '\0';
    return 0;
}

int InitGpio(unsigned int gpioN, unsigned int inout) {
    int fd = 0;
    char tmp[100] = {0};
    //闂傚倷鑳堕幊鎾绘倶濮樿泛绠伴柛婵�?劜椤洟鏌熸潏鈺佲偓宄闂備浇宕�?慨鎶芥倿閿曞倸纾块柟璺哄閸�?剦鏁嗛柛鏇ㄥ亝椤ユ繈姊洪幖鐐插姷闂傚�?瀚伴、鏇㈡晸閿燂�?
    fd = open("/sys/class/gpio/export", O_WRONLY);
    if (-1 == fd) {
        zlog_warn(zbt, "open gpio export file error");
        return 1;
    }
    //闂傚倷鐒﹂惇褰掑垂瑜版帗鍋柛銉墻閺佸鏌ｉ悙�?�?紬io
    sprintf(tmp, "%d", gpioN);
    if (write(fd, tmp, strlen(tmp)) < 0) {
        zlog_warn(zbt, "write file operation error:%s", tmp);
        close(fd);
        return 2;
    }

    close(fd);
    sleep(1);
//闂傚倸鍊烽悞锕€�?�?Ο鑲╃煋闁割偅娲橀崑�?�堟煕閻�?彃鍘o闂傚倷绀侀幖�?�﹀磹婵犳艾绠犻柟鎹愵嚙缁犳牠鏌ㄩ悤鍌涘�?

    sprintf(tmp, "/sys/class/gpio/gpio%d/direction", gpioN);

    zlog_info(zbt, "open GPIO = %s", tmp);
    fd = open(tmp, O_WRONLY);
    if (-1 == fd) {
        zlog_warn(zbt, "open gpio direction file error");
        close(fd);
        return 3;
    }

    if (inout == 0) {
        zlog_info(zbt, "=====InitGpio=====in");
        if (-1 == write(fd, "in", sizeof("in"))) {
            zlog_warn(zbt, "[%d]write operation direction error", gpioN);
            close(fd);
            return 4;
        }
    } else if (inout == 1) {
        zlog_info(zbt, "=====InitGpio=====out");
        if (-1 == write(fd, "out", sizeof("out"))) {
            zlog_warn(zbt, "[%d]write operation direction error", gpioN);
            close(fd);
            return 5;
        }
    }
    close(fd);
    return 0;
}

int gpio_set(unsigned int gpioN, char x) {
    int fd = 0;
    char tmp[100] = {0};

    sprintf(tmp, "/sys/class/gpio/gpio%d/value", gpioN);

    //闂傚倷鑳堕幊鎾绘倶濮樿泛绠伴柛婵�?劜椤洟鏌熸潏鈺佲偓宄 value闂傚倷绀侀幖�?�﹀磹缁�?５娲晲閸涱亝鐎婚梺璺ㄥ櫐閹凤拷
    fd = open(tmp, O_WRONLY);
    if (-1 == fd) {
        zlog_warn(zbt, "[%s] open gpio export file error", tmp);
        close(fd);
        return (-1);
    }
    //闂備浇宕�?慨宕囩矆娴ｈ娅犲ù鐘�?儐閸嬵亪鏌涢埄鍐�?�闁稿鍔戝濠�?醇閻旂儤鍒涢梺褰掓交閹凤�?
    if (x) {
        if (-1 == write(fd, "1", sizeof("1"))) {
            zlog_warn(zbt, "%d write operation value error", gpioN);
            close(fd);
            return (-2);
        }
    } else {
        if (-1 == write(fd, "0", sizeof("0"))) {
            zlog_warn(zbt, "%d write operation value errorn", gpioN);
            close(fd);
            return (-3);
        }
    }
    close(fd);
    return 0;
}

int gpio_read(unsigned int gpioN) {
    int fd = 0;
    char value;

    char tmp[100] = {0};

    sprintf(tmp, "/sys/class/gpio/gpio%d/value", gpioN);

    //闂傚倷鑳堕幊鎾绘倶濮樿泛绠伴柛婵�?劜椤洟鏌熸潏鈺佲偓宄 value闂傚倷绀侀幖�?�﹀磹缁�?５娲晲閸涱亝鐎婚梺璺ㄥ櫐閹凤拷
    fd = open(tmp, O_RDONLY);
    if (-1 == fd) {
        zlog_warn(zbt, "%d open gpio export file error", gpioN);
        return (-1);
    }
    //闂備浇宕�?慨鏉懨洪埡鍜佹晪鐟滄垿濡甸幇鐗堟櫢闁跨噦鎷� value闂傚倷绀侀幖�?�﹀磹缁�?５娲晲閸涱亝鐎婚梺璺ㄥ櫐閹凤拷
    if (-1 == read(fd, &value, sizeof(value))) {
        zlog_warn(zbt, "%d read gpiovalue is fail", gpioN);
        close(fd);
        return (-2);
    }
    close(fd);
    return value;
}

int config_uart(const char *port, int speed) {
    int iFd = open(port, O_RDWR | O_NOCTTY);
    if (iFd < 0) {
        zlog_warn(zbt, "open port:%s failed", port);
        return -1;
    }
    struct termios opt;
    tcgetattr(iFd, &opt);
    cfsetispeed(&opt, speed);
    cfsetospeed(&opt, speed);
    if (tcgetattr(iFd, &opt) < 0) {
        zlog_error(zbt, "tcgetattr failed");
        return -1;
    }
    opt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
    opt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    opt.c_oflag &= ~(OPOST);
    opt.c_cflag &= ~(CSIZE | PARENB | CBAUD);
    opt.c_cflag |= (CS8 | speed);
    opt.c_cc[VMIN] = 1;
    opt.c_cc[VTIME] = 1;
    if (tcsetattr(iFd, TCSANOW, &opt) < 0) {
        zlog_error(zbt, "tcsetattr failed");
        return -2;
    }
    tcflush(iFd, TCIOFLUSH);
    return iFd;
}

int write_data(int fd, char *buff, int len) {
    int ret;
    ret = write(fd, buff, len);
    if (ret < 0) {
        zlog_error(zct, "write failed");
        return -1;
    }
    return ret;
}

int read_data(int fd, char *buff, int len, int timeout) {
    int ret;
    struct timeval to;
    fd_set rdfds;

    to.tv_sec = 0;
    to.tv_usec = timeout;

    FD_ZERO(&rdfds);
    FD_SET(fd, &rdfds);

    if (timeout > 0) {
        ret = select(fd + 1, &rdfds, NULL, NULL, &to);
        if (ret <= 0) {
            return ret;
        }
    }

    ret = read(fd, buff, len);
    if (ret < 0) {
        zlog_error(zct, "read_data failed");
        return -1;
    }
    buff[ret] = '\0';
    return ret;
}

int ModifyMac(char *buff) {
    FILE *fp = NULL;
    fp = fopen("/opt/system/mac", "w");
    if (fp == NULL) {
        zlog_error(zbt, "fail to open /opt/system/mac");
        return 1;
    }
    fprintf(fp, buff);
    fprintf(fp, "\n");
    fclose(fp);
    system("cp /opt/system/mac /opt/system/macbak");
    system("/opt/Cidn/init.sh");
    return 0;
}

void mssleep(unsigned long microseconds) {
    struct timespec req;
    struct timespec rem;
    req.tv_sec = microseconds / 1000000;
    req.tv_nsec = (microseconds % 1000000) * 1000;
    nanosleep(&req, &rem);
}

std::string GetCurrentTime() {
    struct tm nowtime;
    struct timeval tv;
    char time_now[128];
    gettimeofday(&tv, NULL);
    localtime_r(&tv.tv_sec, &nowtime);
    sprintf(time_now, "%d-%d-%d %d:%d:%d.%03d ", nowtime.tm_year + 1900, nowtime.tm_mon + 1, nowtime.tm_mday, nowtime.tm_hour, nowtime.tm_min, nowtime.tm_sec, (int)(tv.tv_usec / 1000));
    std::string strtime_now = std::string((char *)time_now);
    return strtime_now;
}

tm *get_current_date() {
    time_t t = time(NULL);
    struct tm *tm_info = localtime(&t);
    int iyear = 0;
    int imonth = 0;
    int day = 0;
    iyear = tm_info->tm_year + 1900;
    imonth = tm_info->tm_mon + 1;
    day = tm_info->tm_mday;
    zlog_info(zct, "year = %d,month = %d,day = %d", iyear, imonth, day);
    return tm_info;
}

int system_custom(const char *cmd, char *buf) {
    FILE *fp;
    int res;
    char temp[1024] = {0};
    if (cmd == NULL) {
        zlog_error(zct, "cmd is NULL");
        return -1;
    }

    if ((fp = popen(cmd, "r")) == NULL) {
        zlog_error(zct, "popen error");
        return -1;
    } else {
        buf[0] = '\0';
        while (fgets(temp, sizeof(temp), fp)) {
            strcat(buf, temp);
        }
        res = pclose(fp);
    }

    char *p;
    int pos = 0;
    p = strstr(buf, "\n");
    if (p != NULL) {
        pos = p - buf;
        buf[pos] = '\0';
    }

    return res;
}

void GetTimeNet(char *timebuf, int type) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    int millisecond = tv.tv_usec / 1000;
    if (type == 0) {
        sprintf(timebuf, "%ld%03d", tv.tv_sec, millisecond);
    } else {
        sprintf(timebuf, "%ld", tv.tv_sec);
    }
}

std::string GetRTC(char *timestamp, int &millisecond) {
    time_t rtc_timestamp;
    struct tm tm;
    struct timespec ts;
    char rtcTime[100] = {0x00};
    int fd = open("/dev/rtc0", O_RDONLY);
    if (fd < 0) {
        zlog_error(zct, "fail to open /dev/rtc0");
        return "";
    } 
    struct rtc_time rtc_tm;
    if (ioctl(fd, RTC_RD_TIME, &rtc_tm) < 0) {
        zlog_error(zct, "fail to ioctl RTC_RD_TIME");
        return "";
    } 
    clock_gettime(CLOCK_REALTIME, &ts);
    millisecond = (int)(ts.tv_nsec / 1000000);
    printf("RTC date/time is %d-%d-%d, %02d:%02d:%02d\n", rtc_tm.tm_year + 1900, rtc_tm.tm_mon + 1, rtc_tm.tm_mday, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
    sprintf(rtcTime, "%d-%d-%d, %02d:%02d:%02d", rtc_tm.tm_year + 1900, rtc_tm.tm_mon + 1, rtc_tm.tm_mday, rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);

    // 闂備浇�?�х换鎰崲閹版澘鏋侀柛�?�囧发_time缂傚倸鍊搁崐鐑芥倿閿曞倸绠板┑鐘崇閸婂灚銇勯弽銊р姇濠殿垱鎸抽弻鐔煎�?�閹板灚缍堢紓浣风贰閸ｏ綁�??婚悢鐑樺珰闁斥晛鍟扮粣鏃堟煟閻樺啿濮夐柛鏂跨┘me_t闂傚倷绀侀幖�?�﹀�?椤愶附鍋夐柣鎾冲濞戙垹閿ゆ俊銈傚亾缂佺媴缍侀弻銊╂偆閸屾稑�?��
    tm.tm_year = rtc_tm.tm_year;
    tm.tm_mon = rtc_tm.tm_mon;
    tm.tm_mday = rtc_tm.tm_mday;
    tm.tm_hour = rtc_tm.tm_hour;
    tm.tm_min = rtc_tm.tm_min;
    tm.tm_sec = rtc_tm.tm_sec;
    tm.tm_isdst = -1; // 婵犵數鍋為崹�?曞�?�閸濄儳�?撻柧蹇ｅ亞缁犻箖鏌涢妷�?�煎�?闁�?�鍔戦弻鏇熺�?�閸喖�?跺┑鈥冲级閸庢娊婀侀梺缁橈供閸犳牠鍩�?椤掍胶澧い顏勫暣閺佹捇鏁撻敓锟�?

    rtc_timestamp = mktime(&tm);

    if (rtc_timestamp == -1) {
        zlog_error(zct, "fail to mktime");
        return "";
    }
    printf("RTC timestamp is %ld,millisecond = %d\n", rtc_timestamp, millisecond);
    sprintf(timestamp, "%ld", rtc_timestamp);   
    close(fd);
    return std::string(rtcTime);
}

std::string ReadStrByOpt(std::string filename, std::string config, std::string option) {
    boost::mutex::scoped_lock lock(s_config_mu);
    Json::Value root;
    Json::Reader reader;
    std::string value;
    std::fstream is;
    is.open(filename.c_str(), std::ios::in);
    if (reader.parse(is, root)) {
        value = root[config]["option"][option].asString();
    }
    is.close();
    return value;
}

std::vector<DataNodeUpdate> ReadStrUpdate(std::string filename) {
    boost::mutex::scoped_lock lock(s_config_mu);
    Json::Value root, hwVersion;
    Json::Reader reader;
    std::vector<std::string> value;
    std::vector<DataNodeUpdate> vecDataNodeUpdate;
    DataNodeUpdate datanodeUpdate;
    std::fstream is;
    is.open(filename.c_str(), std::ios::in);
    if (reader.parse(is, root)) {
        zlog_info(zbt, "root = %d", root.size());
        for (size_t i = 0; i < root.size(); i++) {
            hwVersion = root[i]["hw_vesion"];
            for (size_t j = 0; j < hwVersion.size(); j++) {
                datanodeUpdate.hwVersion.push_back(hwVersion[j].asString());
            }
            datanodeUpdate.strUpdataFileName = root[i]["fw_name"].asString();
            datanodeUpdate.strSoftVersion = root[i]["sf_vesion"].asString();
            zlog_info(zbt, "strUpdataFileName = %s, strSoftVersion = %s", datanodeUpdate.strUpdataFileName.c_str(), datanodeUpdate.strSoftVersion.c_str());
            vecDataNodeUpdate.push_back(datanodeUpdate);
        }
    }
    is.close();

    return vecDataNodeUpdate;
}

void ReadStrConfig(std::string filename) {
    Json::Value root, gateWay, dataNode;
    std::fstream is;
    Json::Reader reader;
    is.open(filename.c_str(), std::ios::in);
    std::string zigbeeChannel;
    if (reader.parse(is, root) == 0) {
        zlog_error(zbt, "fail to parse file:%s", filename.c_str());
        return;
    }
    gateWay = root["gateWay"];
    dataNode = root["dataNodeArray"];
    zlog_info(zbt, "dataNode = %d", dataNode.size());
    for (size_t i = 0; i < dataNode.size(); i++) {
        std::string softVersion = dataNode[i]["softVersion"].asString();
        std::string bpNo = dataNode[i]["bpNo"].asString();
        std::string wakeupTime = dataNode[i]["wakeupTime"].asString();
        int viff = dataNode[i]["viff"].asInt();
        std::string StaticTime = dataNode[i]["StaticTime"].asString();
        int configFlag = dataNode[i]["configFlag"].asInt();
        int rangeValue = dataNode[i]["range"].asInt();
        int updateValue = dataNode[i]["update"].asInt();
        std::string zigbeeLongAddr = dataNode[i]["zigbeeLongAddr"].asString();
        int accFlag = dataNode[i]["accFlag"].asInt();
        int temTopFlag = dataNode[i]["temTopFlag"].asInt();
        std::string startBrands = dataNode[i]["startBrands"].asString();
        int waveInterVal = dataNode[i]["waveInterVal"].asInt();
        std::string zigbeePanId = dataNode[i]["zigbeePanId"].asString();
        int waveTime = dataNode[i]["waveTime"].asInt();
        int zigbeePower = dataNode[i]["zigbeePower"].asInt();
        int zigbeeRetry = dataNode[i]["zigbeeRetry"].asInt();
        std::string stopBrands = dataNode[i]["stopBrands"].asString();
        int featureInterVal = dataNode[i]["featureInterVal"].asInt();
        int zigbeeFlag = dataNode[i]["zigbeeFlag"].asInt();
        std::string zigbeeDesAddr = dataNode[i]["zigbeeDesAddr"].asString();
        int ZigbeeRetryGap = dataNode[i]["zigbeeRetryGap"].asInt();
        std::string dataNodeNo = dataNode[i]["dataNodeNo"].asString();
        int initFlag = dataNode[i]["initFlag"].asInt();
        std::string faultFrequency = dataNode[i]["faultFrequency"].asString();
        int temBotFlag = dataNode[i]["temBotFlag"].asInt();
        std::string bateryV = dataNode[i]["bateryV"].asString();
        int ACCSampleTime = dataNode[i]["ACCSampleTime"].asInt();
        std::string firstPowerTime = dataNode[i]["firstPowerTime"].asString();
        std::string serialNo = dataNode[i]["serialNo"].asString();
        std::string zigbeeAddr = dataNode[i]["zigbeeAddr"].asString();
        std::string productNo = dataNode[i]["productNo"].asString();
        std::string timeStamp = dataNode[i]["timeStamp"].asString();
        zigbeeChannel = dataNode[i]["zigbeeChannel"].asString();
        int RSSI = dataNode[i]["RSSI"].asInt();
        std::string hardVersion = dataNode[i]["hardVersion"].asString();
        std::string envelopeBandPass = dataNode[i]["envelopeBandPass"].asString();
        int samplingRate = dataNode[i]["samplingRate"].asInt();
        std::string dataNodeName = dataNode[i]["dataNodeName"].asString();
        int status = dataNode[i]["status"].asInt();
        int EquipSta = dataNode[i]["equipSta"].asInt();
        char insertSql[1024] = {0};
        char whereCon[100] = {0x00};
        sprintf(whereCon, "dataNodeNo = '%s'", dataNodeNo.c_str());
        int rows = sqlite_db_ctrl::instance().GetTableRows(T_SENSOR_INFO(TNAME), whereCon);
        if (rows > 0) continue;
        sprintf(insertSql, "'%s','%s','%d','%d','%d','%d','%d','%d',\
                    '%s','%s','%s','%s','%s','%d',\
                    '%d','%d','%d','%s','%d','%s',\
                    '%s','%d','%d','%d','%s','%d','%s','%s',\
                    '%s','%d','%s','%s','%s',\
                    '%d','%d','%d','%d','%d','%s','%d','%d','%d','0','0,0'",
                dataNodeNo.c_str(), dataNodeName.c_str(), initFlag, accFlag, zigbeeFlag, temTopFlag, temBotFlag, EquipSta, hardVersion.c_str(), softVersion.c_str(), bpNo.c_str(), serialNo.c_str(), firstPowerTime.c_str(), atoi(wakeupTime.c_str()), atoi(StaticTime.c_str()),
                waveTime, atoi(bateryV.c_str()), productNo.c_str(), configFlag, startBrands.c_str(), stopBrands.c_str(), featureInterVal, waveInterVal, samplingRate, "", rangeValue, envelopeBandPass.c_str(), faultFrequency.c_str(), zigbeePanId.c_str(),
                atoi(zigbeeChannel.c_str()), zigbeeAddr.c_str(), zigbeeLongAddr.c_str(), zigbeeDesAddr.c_str(), zigbeePower, zigbeeRetry, ZigbeeRetryGap, ACCSampleTime, status, timeStamp.c_str(), viff, RSSI, updateValue);
        int res = sqlite_db_ctrl::instance().InsertData(T_SENSOR_INFO(TNAME), insertSql);
        if (res != 0)
        {
            zlog_error(zbt, "res:%d", res);
        }
        
    }
   
    is.close();
}

void ImportConfig(std::string filename) {
    Json::Value root, gateWay, dataNode;
    std::fstream is;
    Json::Reader reader;
    int res = 0;
    is.open(filename.c_str(), std::ios::in);
    if (!is.is_open()) {
        zlog_error(zbt, "fail to open:%s", filename.c_str());
        return;
    }

    if (reader.parse(is, root) == 0) {
        zlog_error(zbt, "fail to parse:%s", filename.c_str());
        return;
    }
    std::string zigbeeChannel;
    Json::Value jsSystemSetting, jsonValnet, jsonValnet1, jsSystemInfo, jsonValZigbee, jsondataNodeArray;    
    
    jsSystemInfo = root["SystemInfo"];
    jsonValZigbee = root["zigbee"];
    jsonValnet1 = root["eth1"];
    jsonValnet = root["eth0"];
    jsSystemSetting = root["ServerConfig"];
    jsondataNodeArray = root["dataNodeArray"];
    char insertSql[1024] = {0};
    for (size_t i = 0; i < jsondataNodeArray.size(); i++) {
        Json::Value valNode = jsondataNodeArray[i];
        std::vector<std::string> vecDataNode;
        for (size_t j = 0; j < valNode.size(); j++) {
            vecDataNode.push_back(std::string(valNode[j].asString()));
        }
        char dataNodeName[100] = {0x00};
        hexToAscii(vecDataNode[1].c_str(), dataNodeName);
        memset(insertSql, 0, 1024);
        sprintf(insertSql, "'%s','%s','%s','%s','%s','%s','%s','%s',\
                    '%s','%s','%s','%s','%s','%s',\
                    '%s','%s','%s','%s','%s','%s',\
                    '%s','%s','%s','%s','%s','%s','%s','%s',\
                    '%s','%s','%s','%s','%s',\
                    '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                vecDataNode[0].c_str(), dataNodeName, vecDataNode[2].c_str(), vecDataNode[3].c_str(), 
                vecDataNode[4].c_str(), vecDataNode[5].c_str(), vecDataNode[6].c_str(), 
                vecDataNode[7].c_str(), vecDataNode[8].c_str(), vecDataNode[9].c_str(), vecDataNode[10].c_str(),
                vecDataNode[11].c_str(), vecDataNode[12].c_str(), vecDataNode[13].c_str(), vecDataNode[14].c_str(),
                vecDataNode[15].c_str(), vecDataNode[16].c_str(), vecDataNode[17].c_str(), vecDataNode[18].c_str(),
                vecDataNode[19].c_str(), vecDataNode[20].c_str(),
                vecDataNode[21].c_str(), vecDataNode[22].c_str(), vecDataNode[23].c_str(), vecDataNode[24].c_str(),
                vecDataNode[25].c_str(), vecDataNode[26].c_str(), vecDataNode[27].c_str(), vecDataNode[28].c_str(), 
                vecDataNode[29].c_str(), vecDataNode[30].c_str(),
                vecDataNode[31].c_str(), vecDataNode[32].c_str(), vecDataNode[33].c_str(), vecDataNode[34].c_str(), 
                vecDataNode[35].c_str(), vecDataNode[36].c_str(), vecDataNode[37].c_str(), vecDataNode[38].c_str(), 
                vecDataNode[39].c_str(), vecDataNode[40].c_str(),
                vecDataNode[41].c_str(), vecDataNode[42].c_str(), vecDataNode[43].c_str(), vecDataNode[44].c_str(),
                vecDataNode[45].c_str(),vecDataNode[46].c_str());
        res = sqlite_db_ctrl::instance().InsertData(T_SENSOR_INFO(TNAME), insertSql);
        if (res != 0){
            zlog_error(zbt, "res:%d", res);
        }
    }

    WriteStr2Config(SERVERCONFIG, "Server", "localServerIpAddress", jsSystemSetting["ServerIpAddress"].asString());
    WriteStr2Config(SERVERCONFIG, "Server", "localServerPort", jsSystemSetting["ServerPort"].asString());
    WriteStr2Config(SERVERCONFIG, "Server", "CommMode", "2");
    WriteStr2Config(SERVERCONFIG, "Server", "UserName", jsSystemSetting["UserName"].asString());
    WriteStr2Config(SERVERCONFIG, "Server", "Password", jsSystemSetting["Password"].asString());
    WriteStr2Config(SERVERCONFIG, "Server", "APN", jsSystemSetting["APN"].asString());
    char APN[100] = {0x00};
    std::string apn = jsSystemSetting["APN"].asString();
    sprintf(APN, "sed -i '15c \t\t\t\t/opt/quectel-CM/quectel-CM -s %s > /dev/null &' /etc/init.d/S95check5G", apn.c_str());
    system(APN);

    WriteStr2Config(ZIGBEECONFIG, "Zigbee", "channel", jsonValZigbee["channel"].asString());
    WriteStr2Config(ZIGBEECONFIG, "Zigbee", "PanID", jsonValZigbee["PanID"].asString());

    WriteStr2Config(SYSTEMINFOFILE, "Version", "GateWayVersion", jsSystemInfo["GateWayVersion"].asString());
    WriteStr2Config(SYSTEMINFOFILE, "Version", "SystemVersion", jsSystemInfo["SystemVersion"].asString());
    WriteStr2Config(SYSTEMINFOFILE, "Version", "WebVersion", jsSystemInfo["WebVersion"].asString());
    WriteStr2Config(SYSTEMINFOFILE, "Version", "GateWayHwVesion", jsSystemInfo["GateWayHwVesion"].asString());
    WriteStr2Config(SYSTEMINFOFILE, "Version", "GateWayProduct", jsSystemInfo["GateWayProduct"].asString());  

    char whereCon[1024] = {0};
    char updateSql[1024] = { 0 };
    sprintf(updateSql, "zigbeePanID = '%s',zigbeeChannel = '%s'",\
            jsonValZigbee["PanID"].asString().c_str(),jsonValZigbee["channel"].asString().c_str());
    sprintf(whereCon, "gatewayMAC='%s'", GlobalConfig::MacAddr_G.c_str());
    sqlite_db_ctrl::instance().UpdateTableData(T_GATEWAY_INFO(TNAME), updateSql, whereCon);  
}

int UpdataDataNodeConfig(std::string filename) {
    std::vector<DataNodeInfo> vecDataNode; //婵犵數濮伴崹鐟帮耿鏉堛劍娅犳俊銈傚亾閸�?�亶鏌熺�?电ǹ浠ч柍缁樻閺屽秷顧侀柛鎾存皑缁瑦�?�勯幇鍨櫆闂佸憡娲﹂崢浠�??箟閼姐倗纾藉ù锝�?嚃濞�?絿绱撻崒娑欑殤闁硅弓鍗冲畷鍗炩�?�濡晝鏇㈡⒑绾懏褰х紒鐘冲灥閳诲秹鏁撻敓锟�?
    //婵犵數鍋涢顓熸叏娴兼潙纾块柟缁㈠櫘閺佸霉閸忓吋缍戠紒鈧崒鐐寸厪濠㈣埖鐩顕€鏌ｉ幘瀵告�?闁逞屽�?椤旀牠宕伴弽顐ｅ床闁瑰鍋炲▍鐘绘煥閺囨浜惧銈嗘穿缂嶄線宕洪埀顒併亜閹烘垵顏╂俊�?�ｏ耿閺屾盯濡烽鐐�?�?嶅銈嗗姧閹凤拷
    std::ifstream csv_data(filename, std::ios::in);
    int iRet = 0;
    if (!csv_data.is_open()) {
        zlog_error(zbt, "UpdataDataNodeConfig fail to open:%s", filename.c_str());
        return -1;
    } 
    std::string line;
    std::vector<std::string> words; //婵犵數濮伴崹鐟帮耿鏉堛劍娅犳俊銈傚亾閸�?�亶鏌熺�?电ǹ浠ч柍缁樻閺屽秷顧侀柛鎾存皑缁瑦�?�勯幇鍨櫆闂佸憡娲﹂崢浠�??箟閼姐倗纾藉ù锝�?嚃濞�?絿绱撻崒娑欑殤闁硅弓鍗冲畷鍗炩�?�濡晝鏇㈡⒑绾懏褰х紒鐘冲灥閳诲秹鏁撻敓锟�?
    std::string word;

    DataNodeInfo dataNode;
    // ------------闂備浇宕�?慨鏉懨洪埡鍜佹晪鐟滄垿濡甸幇鏉跨倞�?�ゆ巻鍋撻柡瀣╃窔閺岋絽螖閳ь剟鎮ч崱娆戠焾闁跨噦鎷�?-----------------
    // 闂備浇宕�?慨鏉懨洪埡鍜佹晪鐟滄垿濡甸幇鏉跨倞�?�ゆ巻鍋撻柛鎰ㄥ亾闂備焦�?堕崕娲礈閿曞倸姹叉い鏍仦閸�?姵绻涢幋锝嗙彧閻庢熬鎷�
    getline(csv_data, line);

    std::istringstream sin;
    // 闂傚倷绀佸﹢杈ㄧ仚濡�?倧闄�?繛濠�?Υ娓氣偓�?�炲鎮╅崘鑼酱闂佽崵�?村ú锕併亹閸愵亜绶ら柛褎顨嗛悡娑樏归敐鍛儓�?�わ綀鍋愰埀顒冾潐閹碱偊骞忛敓锟�?
    while (getline(csv_data, line)) {
        words.clear();
        sin.clear();
        sin.str(line);
        while (getline(sin, word, ',')) {           
            words.push_back(word);
        }
        std::string mac = words[1];
        if (mac != GlobalConfig::MacAddr_G) {
            iRet = -2;
            break;
        }
        dataNode.ZigbeeLongAddr = words[7];
        dataNode.FeatureInterVal = atoi(words[16].c_str());
        dataNode.WaveInterVal = atoi(words[17].c_str());
        dataNode.SamplingRate = atoi(words[18].c_str());        

        if (words[19].find("8g") != std::string::npos) {
            dataNode.Range = 0;
        } else if (words[19].find("16g") != std::string::npos) {
            dataNode.Range = 1;
        } else if (words[19].find("32g") != std::string::npos) {
            dataNode.Range = 2;
        } else if (words[19].find("64g") != std::string::npos) {
            dataNode.Range = 3;
        } else if (words[19].find("50g") != std::string::npos) {
            dataNode.Range = 0;
        }

        dataNode.ACCSampleTime = atoi(words[20].c_str());
        dataNode.VIntegralFilterFrequency = atoi(words[21].c_str());
        dataNode.ZigbeePower = atoi(words[22].c_str());
        dataNode.ZigbeeRetry = atoi(words[23].c_str());
        int update = atoi(words[24].c_str());
        if (update == 1) vecDataNode.push_back(dataNode);
    }
    csv_data.close();    
    if (vecDataNode.size() == 0) {
        iRet = -3;
        zlog_error(zbt, "UpdataDataNodeConfig vecDataNode is 0");
        return iRet;
    }    
    
    char whereCon[1024] = {0};
    char updateSql[1024] = {0};    
    for (size_t i = 0; i < vecDataNode.size(); i++) {
        sprintf(updateSql, "range='%d',samplingRate='%d',AccSampleTime = '%d',viff ='%d' ,ZigbeePower = '%d',ZigbeeRetry = '%d',UpdateFlag = 0", vecDataNode[i].Range,
                vecDataNode[i].SamplingRate, vecDataNode[i].ACCSampleTime, vecDataNode[i].VIntegralFilterFrequency, vecDataNode[i].ZigbeePower, vecDataNode[i].ZigbeeRetry);
        sprintf(whereCon, "dataNodeNo='%s'", vecDataNode[i].ZigbeeLongAddr.c_str());

        iRet = sqlite_db_ctrl::instance().UpdateTableData(T_SENSOR_INFO(TNAME), updateSql, whereCon);
        if (iRet != 0) {
            zlog_error(zbt, "UpdataDataNodeConfig UpdateTableData fail");
            return -4;
        }
        memset(whereCon, 0x00, sizeof(whereCon));
        memset(updateSql, 0x00, sizeof(updateSql));
    }     
    iRet = vecDataNode.size();   
    return iRet;
}

int WriteStr2Config(std::string filename, std::string config, std::string option, std::string value, bool listable) {
    boost::mutex::scoped_lock lock(s_config_mu);
    Json::Value root;
    Json::Value subroot;
    Json::Value list;
    Json::Value op;
    Json::Reader reader;
    std::fstream is;
    is.open(filename.c_str(), std::ios::in);
    if (!is.is_open()) {
        zlog_error(zct, "fail to open: %s", filename.c_str());
        return 1;
    }
    if (reader.parse(is, root) == 0) {
        zlog_error(zct, "fail to parse: %s", filename.c_str());
        return 2;
    }
   
    subroot = root[config];
    if (listable) {
        list = root[config]["list"];
    } else {
        op = root[config]["option"];
    }
    
    is.close();

    if (listable) {
        list[option].append(Json::Value(value));
        subroot["list"] = list;
    } else {
        op[option] = Json::Value(value);
        subroot["option"] = op;
    }
    root[config] = subroot;
    Json::StyledWriter sw;
    std::ofstream os;
    os.open(filename.c_str());
    os << sw.write(root);
    os.close();
    return 0;
}

std::string GetLocalMac(const char *net) {
    int sock_mac;
    struct ifreq ifr_mac;
    char mac_addr[30];
    sock_mac = socket(AF_INET, SOCK_STREAM, 0);
    if (sock_mac == -1) {
        zlog_error(zct, "[GetLocalMac] fail to create socket");
        return "";
    }
    memset(&ifr_mac, 0, sizeof(ifr_mac));
    strncpy(ifr_mac.ifr_name, net, sizeof(ifr_mac.ifr_name) - 1);
    if ((ioctl(sock_mac, SIOCGIFHWADDR, &ifr_mac)) < 0) {
        zlog_error(zct, "mac ioctl error");
        return "";
    }
    sprintf(mac_addr, "%02x%02x%02x%02x%02x%02x", (unsigned char)ifr_mac.ifr_hwaddr.sa_data[0], (unsigned char)ifr_mac.ifr_hwaddr.sa_data[1], (unsigned char)ifr_mac.ifr_hwaddr.sa_data[2], (unsigned char)ifr_mac.ifr_hwaddr.sa_data[3], (unsigned char)ifr_mac.ifr_hwaddr.sa_data[4],
            (unsigned char)ifr_mac.ifr_hwaddr.sa_data[5]);
    zlog_info(zbt, "net :%s, local mac:%s", net, mac_addr);
    close(sock_mac);
    return std::string(mac_addr);
}

std::string GetGwIp_(const char *eth_name) {
    int sockfd;
    char gwip_[16] = {0};
    if (-1 == (sockfd = socket(PF_INET, SOCK_STREAM, 0))) {
        zlog_error(zct, "[GetGwIp_] fail to create socket");
        return "";
    }
    struct ifreq req;
    struct sockaddr_in *host;

    bzero(&req, sizeof(struct ifreq));
    strcpy(req.ifr_name, eth_name);
    ioctl(sockfd, SIOCGIFADDR, &req);
    host = (struct sockaddr_in *)&req.ifr_addr;
    close(sockfd);
    if (host) {
        strcpy(gwip_, inet_ntoa(host->sin_addr));
    }
    return std::string(gwip_);
}

std::string IpAddrInit() {
    const char *WLAN2 = "wlan2";
    const char *WLAN0 = "wlan0";
    const char *ETH0 = "eth0";
    const char *USB0 = "usb0";
    const char *WWAN0 = "wwan0";
    const char *ETH1 = "eth1";
    const char *ETH2 = "eth2";
    std::string strip = "";
    strip = GetGwIp_(WLAN0);
    if (strip.compare("0.0.0.0") != 0) {
        //zlog_info(zct, "[IpAddrInit] wlan0: %s", strip.c_str());
        return strip;
    }
    strip = GetGwIp_(WLAN2);
    if (strip.compare("0.0.0.0") != 0) {
        //zlog_info(zct, "[IpAddrInit] wlan2: %s", strip.c_str());
        return strip;
    }
    strip = GetGwIp_(ETH1);
    if (strip.compare("0.0.0.0") != 0 && strip.compare("192.168.188.188") != 0) {
        //zlog_info(zct, "[IpAddrInit] eth1: %s", strip.c_str());
        return strip;
    }
    strip = GetGwIp_(ETH2);
    if (strip.compare("0.0.0.0") != 0 && strip.compare("192.168.188.188") != 0) {
        //zlog_info(zct, "[IpAddrInit] eth2: %s", strip.c_str());
        return strip;
    }
    strip = GetGwIp_(ETH0);
    if (strip.compare("0.0.0.0") != 0) {
        //zlog_info(zct, "[IpAddrInit] eth0: %s", strip.c_str());
        return strip;
    }
    strip = GetGwIp_(USB0);
    if (strip.compare("0.0.0.0") != 0) {
        //zlog_info(zct, "[IpAddrInit] usb0: %s", strip.c_str());
        return strip;
    }
    strip = GetGwIp_(WWAN0);
    if (strip.compare("0.0.0.0") != 0) {
        //zlog_info(zct, "[IpAddrInit] wwan0: %s", strip.c_str());
        return strip;
    }
    zlog_warn(zct, "[IpAddrInit] ip: %s", strip.c_str());
    return strip;
}

int SetTime(unsigned long seconds, int milliseconds) {
    struct timeval tv;
    time_t timep = (time_t)seconds;
    tv.tv_sec = timep;
    tv.tv_usec = milliseconds * 1000;
    return settimeofday(&tv, NULL);
}

void ZoneConfig(std::string zoneid) {
    int a = 0;
    std::string zonelists[] = {"UTC+12", "UTC+11", "UTC+10", "UTC+9", "UTC+8", "UTC+7", "UTC+6", "UTC+5", "UTC+4", "UTC+3", "UTC+2", "UTC+1", "UTC+0", "UTC-1", "UTC-2", "UTC-3", "UTC-4", "UTC-5", "UTC-6", "UTC-7", "UTC-8", "UTC-9", "UTC-10", "UTC-11"};
    for (size_t i = 0; i < sizeof(zonelists); i++) {
        if (zoneid.compare(zonelists[i]) == 0) {
            a = i;            
            zlog_info(zbt, "[ZoneConfig] zoneid:%s, a: %d", zoneid.c_str(), a);
            break;
        }
    }
    switch (a) {
        case 0: zoneid = "GMT-12"; break;
        case 1: zoneid = "GMT-11"; break;
        case 2: zoneid = "GMT-10"; break;
        case 3: zoneid = "GMT-9"; break;
        case 4: zoneid = "GMT-8"; break;
        case 5: zoneid = "GMT-7"; break;
        case 6: zoneid = "GMT-6"; break;
        case 7: zoneid = "GMT-5"; break;
        case 8: zoneid = "GMT-4"; break;
        case 9: zoneid = "GMT-3"; break;
        case 10: zoneid = "GMT-2"; break;
        case 11: zoneid = "GMT-1"; break;
        case 12: zoneid = "GMT-0"; break;
        case 13: zoneid = "GMT+1"; break;
        case 14: zoneid = "GMT+2"; break;
        case 15: zoneid = "GMT+3"; break;
        case 16: zoneid = "GMT+4"; break;
        case 17: zoneid = "GMT+5"; break;
        case 18: zoneid = "GMT+6"; break;
        case 19: zoneid = "GMT+7"; break;
        case 20: zoneid = "GMT+8"; break;
        case 21: zoneid = "GMT+9"; break;
        case 22: zoneid = "GMT+10"; break;
        case 23: zoneid = "GMT+11"; break;
    }
    char cmd[256] = {0};
    memset(cmd, 0, 256);
    sprintf(cmd, "sudo ln -sf /usr/share/zoneinfo/Etc/%s  /etc/localtime", zoneid.c_str());
    system(cmd);
    zlog_info(zbt, "change timezone success!");
}

std::string GetFileContent(std::string filename, int line) {
    std::string strFileContent("");
    std::ifstream ifileOut(filename.c_str());
    if (!ifileOut.is_open()) {
        zlog_error(zct, "fail to open:%s", filename.c_str());
        return strFileContent;
    }
    
    int i = 1;
    while (!ifileOut.eof()) {
        if (line == 0) {
            std::string strTemp("");
            getline(ifileOut, strTemp);
            strFileContent += strTemp;
            strFileContent += "\r\n";
        } else {
            std::string strTemp("");
            getline(ifileOut, strTemp);
            if (line == i) {
                strFileContent = strTemp;
                break;
            }
        }
        ++i;
    }
    ifileOut.close();    
    return strFileContent;
}

// BOOST闂傚倷鑳堕崕鐢�?�磻閹捐绀夌€广儱顦介�?鍡�?�節婵犲倻澧曠紒鈧崱妯肩闁糕剝锚缁旈箖鏌嶈閸撴瑩宕姘肩劷闊洦绋戠粻�?�辨喐韫囨洘鍏滈柍�?�鍓�?穱濠�?Χ閸ヮ灝銏ゆ煟椤撴繄绐旈柟顖欑劍缁诲懘�?�?弴銏♀拺闂傚牃鏅犲�?�界節閵忊埗�?�堚�?﹂崶顒€绀冩い鏃囧琚濋梻浣�?�閸�??棝宕伴幘璇参ラ柨鐕傛�?
bool CheckIP(const char *ip) {
    boost::xpressive::cregex reg_ip =
        boost::xpressive::cregex::compile("(25[0-4]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])[.](25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])[.](25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])[.](25[0-4]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])");
    return boost::xpressive::regex_match(ip, reg_ip);
}

bool IsValidMask(std::string mask) {
    int iRet = -1;

    // 闂備浇�?�х换鎰崲閹版澘绠查柛鎴︿憾�?婃椽�?�?埡鍛€嶅┑鐘�?閿氭い�?�炴喘瀹曟﹢顢欓挊澶�?�紦闂備胶鎳撻崥鈧悹浣�?叀瀹曟垿骞橀�?銉ョ�?闂佸憡渚楅崢娲礌閺嶎厽鈷戦柛娑橈工缁�?�帗淇婇锝庢當闁伙絿鍏樺畷鐔碱敆娴ｉ攱鍞�?�繝鐢靛仦閸ㄥ爼鏁�??梺缁樻尰閸ㄥ潡�??诲澶娢ㄩ柨鏂垮⒔閻ｆ儳鈹戦悙瀛�?�稇婵☆偅绻堥悰顕€骞�??敃鈧～鍛存煃閵夈儳锛嶅ù婊愭�? 闂傚倷鑳堕崑銊╁磿閼碱剙鍨濋柛�?�犲灱婵娊鏌嶉�?鍕偓瑙�?閵堝�?�绠鹃柟瀵镐紳椤忓牊鍋傞柟杈鹃�??閻撴稑霉閿濆懏鎲搁柟鐣屽█閺岋繝宕卞▎蹇旂亪闂佹悶鍔戠粻鏍极閹剧粯鏅搁柨鐕傛�??
    struct in_addr s;
    iRet = inet_pton(AF_INET, mask.c_str(), &s);

    // 闂備礁鎼ˇ閬嶅磿閹版澘绀堟慨姗嗗墰閺�?箓鏌＄仦璇插姎缂佺�?�缍侀弻鐔兼焽閿曗偓�?�ь喗銇勯銈�?枅鐎殿喖鐖奸崺锟犲磼濞戞艾�??�?繝鐢靛仩椤曟粓骞忛敓锟�1闂傚倷鐒︾€笛呯矙閹达附鍎�?�〒�?�ｅ亾�?�ゃ垺宀搁崺锟犲川椤撶偛鎸ら梺鐟板悑閻ｎ�?宕归搹鍦噮闂傚倷绀侀幖�?�︽偋閸℃蛋鍥ㄥ閺夋垹鏌ч梺闈涱槴閺�?粓宕曞澶�??厱闁规惌鍘介惁浠�?⒒娓氣偓濞煎�?�介崟�?�唵婵☆垯璀﹂悞浠�??煥閻曞倹瀚�
    if (iRet == 1) {
        // 婵犵數鍋涢顓熸叏閺夋嚚瑙勵槹鎼达絿顦繝銏ｆ硾閻偐澹曢崗鑲╃瘈濠电姴鍊搁弳鐔兼煙閻ｅ�?鏋涢柡灞诲€濆畷顐﹀礋椤�?喎浜鹃柛褎顨呰繚闁瑰吋鐣崹娲磿閻旇偐鍙撻柛銉ｅ�?�椤ｈ尙绱掓笟鍥ф珝闁哄瞼鍠撻幏鐘诲焺閸愵亞鐛㈤梺鑽ゅУ閸旀宕伴幇顔剧煓濠㈣泛�?肩�?�鍏间繆椤栨繂鍚归柣銊ヮ煼閺岋絾�?旈�?�鈶╁濡�?們鍔岄ˇ鐗堢┍婵犲浂鏁�?柣鏃傜節缁ㄥ�?�洪崨濠�?畵閻庢凹鍠氶崰濠囨晸閿燂�?
        unsigned int addr = ntohl(s.s_addr);

        // 闂備礁鎼ˇ閬嶅磿閹版澘绀堟慨姗嗗墰閺�?箓鏌涘▎蹇ｆШ闁崇�?�?�?鍫曟倷閺夋埈�?嗛梺璋庡啰鐒哥€殿喖鐖奸崺锟犲磼濠х偓�?嶉梻浣虹《閺�?粓銆�?崼銉ョ劦妞ゆ帊鑳堕埊鏇熴亜閵娿儳澧︽い銏＄�??閹峰懘宕烽娑欑亙闂備浇娉曢崳锕傚�??閿燂�?
        std::bitset<32> b((int)addr);
        std::string strMask = b.to_string();

        // 闂傚倷绀侀幖�?�ゆ偖椤愶箑纾块柛娆忣槺閻濊埖淇婇婵嗗惞�?�も晞灏欓埀顒€鍘滈崑鎾绘煕閹板吀绨芥い鏃�?�?″娲川婵犲倻�?�勫┑鐐�?槹閻╊垶骞冩ウ娆�?Ь缂備緡鍣崣鍐极閸岀偞鍤�?い鏍电稻閼哥懓鈹戦悙鏉戠仸闁瑰皷鏅犲畷銏ゅ箚瑜�?�弸鏃堟煥閻曞倹瀚�"01"闂傚倷鐒︾€笛呯矙閹达附鍤愭い鏍�?亼閳ь剙鎳撻ˇ鍦偓娈垮枤鏋顏冨嵆閸┾偓妞ゆ帒鍊荤粻鏂�?�熆鐠哄�?顦柛瀣�?閳藉�?鈻嶉�?�绨婚柨鏇樺灲椤㈡�?�宕奸悢鍛婄彨闁诲�?�鍘滈崑鎾绘煕閹邦厼鍔ゆ繛鍫灦�?婃椽宕崟�?�患闁诲�?�绋堥弲娑樺�?闂佸綊妫跨粈浣衡偓�?�槸椤法鎹勬笟�?�氬壉濠电偛鎳庣换�?�€�?婚敐澶娢╅柕澶堝労娴犲ジ姊洪悜鈺佸⒉闁荤啙鍛潟闁哄�?鐗嗙粻锝夋煟閹邦垰钄肩紒鈧�?ｎ喗鈷戞繛鑼额嚙濞呮瑩鏌熼崙銈嗗�?
        return (strMask.find("01") == std::string::npos);
    }

    return false;
}

int getSysIntValue(char *key) {
    if (key == NULL) {
        zlog_error(zct, "key is NULL");
        return 0;
    }
    FILE *fp = NULL;
    int value = 0;  
    fp = fopen(key, "r");
    if (fp == NULL) {
        zlog_error(zct, "could not open %s file", key);
        return 1;
    }

    fscanf(fp, "%d", &value);
    fclose(fp);
    return value;
}
void GetSysStatusCMT(int& cpu_use,int& mem_use,int& disk_remain,int& cpu_temp)
{
    long mem_used = -1;
    long mem_free = -1;
    long mem_total = -1;
    long mem_cached = -1;
    char name1[20];
    std::string strMemTotal = GetFileContent("/proc/meminfo", 1);
    std::string strMemFree = GetFileContent("/proc/meminfo", 2);
    std::string strMemCache = GetFileContent("/proc/meminfo", 5);

    sscanf(strMemTotal.c_str(), "%s%ld", name1, &mem_total);
    sscanf(strMemFree.c_str(), "%s%ld", name1, &mem_free);
    sscanf(strMemCache.c_str(), "%s%ld", name1, &mem_cached);
    mem_used = mem_total - mem_free;
    float fMemRate = 1.0 * mem_used / mem_total;

    char name[8];
    double cpu_user = -1;
    double cpu_total = -1;
    long int user, nice, sys, idle, iowait, irq, softirq;
    std::string strCpu1 = GetFileContent("/proc/stat", 1);
    sscanf(strCpu1.c_str(), "%s%ld%ld%ld%ld%ld%ld%ld", name, &user, &nice, &sys, &idle, &iowait, &irq, &softirq);
    sleep(1);
    long int userNext, niceNext, sysNext, idleNext, iowaitNext, irqNext, softirqNext;
    std::string strCpu2 = GetFileContent("/proc/stat", 1);
    sscanf(strCpu2.c_str(), "%s%ld%ld%ld%ld%ld%ld%ld", name, &userNext, &niceNext, &sysNext, &idleNext, &iowaitNext, &irqNext, &softirqNext);
    cpu_total = (userNext + niceNext + sysNext + idleNext + iowaitNext + irqNext + softirqNext) - (user + nice + sys + idle + iowait + irq + softirq);
    cpu_user = userNext - user;
    float rateUser = cpu_user * 100.0 / cpu_total;
    if (rateUser > 95) {
        rateUser = 92;
    }
    char hardTotal[32];
    char hardFree[32];
    char rateHardUse[32];
    char chRes[100];
    memset(chRes, 0, 100);

    char hardName[32];
    char hardUse[32];
    const char *getEmmcInfo = "df -h | grep /opt";
    system_custom(getEmmcInfo, chRes);
    sscanf(chRes, "%s%s%s%s%s", hardName, hardTotal, hardUse, hardFree, rateHardUse);

    std::string strhardTotal(hardTotal);
    std::string strhardFree(hardFree);
    std::string strrateHardUse(rateHardUse);

    char key[128] = {0};
    memset(key, 0, sizeof(key));
    sprintf(key, "/sys/class/thermal/thermal_zone0/temp");
    int temp = getSysIntValue(key);
    cpu_use = rateUser;
    mem_use = fMemRate * 100;
    disk_remain = atoi(strhardFree.substr(0, strhardFree.length() - 1).c_str());
    cpu_temp = temp / 1000.0;
}
std::string GetSysStatus(Json::Value &jsData) {
    long mem_used = -1;
    long mem_free = -1;
    long mem_total = -1;
    long mem_cached = -1;
    char name1[20];
    std::string strMemTotal = GetFileContent("/proc/meminfo", 1);
    std::string strMemFree = GetFileContent("/proc/meminfo", 2);
    std::string strMemCache = GetFileContent("/proc/meminfo", 5);

    sscanf(strMemTotal.c_str(), "%s%ld", name1, &mem_total);
    sscanf(strMemFree.c_str(), "%s%ld", name1, &mem_free);
    sscanf(strMemCache.c_str(), "%s%ld", name1, &mem_cached);
    mem_used = mem_total - mem_free;
    float fMemRate = 1.0 * mem_used / mem_total;

    char name[8];
    double cpu_sys = -1;
    double cpu_user = -1;
    double cpu_total = -1;
    long int user, nice, sys, idle, iowait, irq, softirq;
    std::string strCpu1 = GetFileContent("/proc/stat", 1);
    sscanf(strCpu1.c_str(), "%s%ld%ld%ld%ld%ld%ld%ld", name, &user, &nice, &sys, &idle, &iowait, &irq, &softirq);
    sleep(1);
    long int userNext, niceNext, sysNext, idleNext, iowaitNext, irqNext, softirqNext;
    std::string strCpu2 = GetFileContent("/proc/stat", 1);
    sscanf(strCpu2.c_str(), "%s%ld%ld%ld%ld%ld%ld%ld", name, &userNext, &niceNext, &sysNext, &idleNext, &iowaitNext, &irqNext, &softirqNext);
    cpu_total = (userNext + niceNext + sysNext + idleNext + iowaitNext + irqNext + softirqNext) - (user + nice + sys + idle + iowait + irq + softirq);
    cpu_user = userNext - user;
    cpu_sys = sysNext - sys;
    float rateUser = cpu_user * 100.0 / cpu_total;
    float rateSys = cpu_sys * 100.0 / cpu_total;
    if (rateUser > 95) {
        rateUser = 92;
    }
    char hardTotal[32];
    char hardFree[32];
    char rateHardUse[32];
    char chRes[100];
    memset(chRes, 0, 100);

    char hardName[32];
    char hardUse[32];
    const char *getEmmcInfo = "df -h | grep /opt";
    system_custom(getEmmcInfo, chRes);
    sscanf(chRes, "%s%s%s%s%s", hardName, hardTotal, hardUse, hardFree, rateHardUse);

    std::string strhardTotal(hardTotal);
    std::string strhardFree(hardFree);
    std::string strrateHardUse(rateHardUse);

    char key[128] = {0};
    memset(key, 0, sizeof(key));
    sprintf(key, "/sys/class/thermal/thermal_zone0/temp");
    int temp = getSysIntValue(key);

    Json::FastWriter fw;
    jsData["dataNodeGatewayNo"] = GlobalConfig::MacAddr_G;
    jsData["cpuUserUse"] = rateUser;
    jsData["memoryTotal"] = (int)mem_total;
    jsData["memoryFree"] = (int)mem_free;
    jsData["memoryUse"] = fMemRate * 100;
    jsData["hardDiskTotal"] = atof(strhardTotal.substr(0, strhardTotal.length() - 1).c_str());
    jsData["hardDiskFree"] = atof(strhardFree.substr(0, strhardFree.length() - 1).c_str());
    jsData["temperature"] = temp / 1000.0;
    jsData["temperatureNR5G"] = atoi(GlobalConfig::NR5GTemp.c_str());

    float total = atof(strhardTotal.substr(0, strhardTotal.length() - 1).c_str());
    float free = atof(strhardFree.substr(0, strhardFree.length() - 1).c_str());
    float use = ((total - free) / total) * 100;
    jsData["hardDiskUse"] = use;
    jsData["cpuSystemUse"] = rateSys;

    char localtimestamp[32] = {0};
    GetTimeNet(localtimestamp, 1);
    std::string nowTimetamp = std::string(localtimestamp);
    jsData["updateTime"] = nowTimetamp;
    std::string strJson = fw.write(jsData);
    return strJson;
}

// 闂備浇�?�х换鎰崲閹邦儵娑�?�旈埀顒勬偩閻戣姤鍋勯柛婵�?劗閺�?牠�?�虹捄銊ユ珢闁瑰嚖鎷�?16闂備礁鎼ˇ�?�﹀疾濠婂懐�?欓柟杈剧畱閺勩儲淇婇妶鍛殜闁�?�鎸搁埥澶娾枎濡崵鏆俊鐐�?�?崹鎶芥倿閿曗偓椤�?顢旈崼�?�ｆ櫌婵炶揪绲挎灙缂併劊鍎茬换娑㈠�?�閻�?潙纰嶉梺鍦拡閸�?�?銆佸棰濇晩闁兼亽鍎遍崝鍛存⒑閸濆�??鏆欓柛濠傜秺閹箖鏌嗗鍡椻偓鍨�?�閹寸偟鎳愭繛鍫熺懃閳�?�垿鍩ラ崱妤�?�?嶉悗瑙勬礃閸旀瑩�??幘缁樻櫢闁跨噦鎷�
unsigned char hexCharToByte(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    return 0; // 闂備浇�?�уù鐑藉极婵犳艾鐒�?い鎺嶈兌閵嗘帡鏌よぐ鎺旂�?闁哄矉绻濆畷姗€顢旈崟鎴秮閺岋繝宕ㄩ銏犲Е闂佽鍨伴崯鏉戠暦閻旂⒈鏁冮柕鍫濇閸犳洜绱撻崒娆戝妽�?�ゃ劍鍔楅幏瀣晲閸�?煈�?�熷┑鐘绘涧濞�?�附绂嶉妶澶�?厸闁稿本绋戦�?�呯磼閳ь剟鍩�?閿燂�?0
}

// 闂備浇�?�х换鎰殽韫囨稑绠柨鐕傛�??16闂備礁鎼ˇ�?�﹀疾濠婂懐�?欓柟杈剧畱閺勩儲淇婇妶鍛殜闁�?�鎸搁埥澶娾枎濡崵鏆俊鐐�?�?崹鎶芥倿閿斿墽�?欏鑸靛姈閸ゆ垿鏌ら�?銉︽毄闁靛牜鍣ｅ铏规兜閸滀礁娈�?┑鐘噰閸�??捇鏌ｉ悩鍐插闁哥姵鎹囬崺鈧い鎺嶈兌閳洘銇勯妸銉Ч濞ｅ洤锕、�?�€�?�?閻樺�?鈧剟�?�虹憴鍕靛晱闁哥姵宀搁幆宀�?晸閿燂拷
int hexStringToBytes(const char *hexStr, unsigned char *bytes, size_t bytesSize) {
    size_t hexLen = strlen(hexStr);
    if (hexLen % 2 != 0) {
        zlog_error(zct, "hexLen:%d is odd", hexLen);
        return -1; // Hex闂備浇�?�х€涒晝�?欓幒妞尖偓鍐醇閵�?�喗鏅炴繛杈剧到濠€�?嶅煝閺冨牊鐓涢悘鐐�?�嚙閸旀粍鎱ㄩ敐鍡�?�妤犵偞鐗�?�蹇涘�?�瑜忛弳鐘电磽娴ｉ潧�?�?閻忓繑鐟╅獮蹇涙偐鐠囧弬銊╂煥閺傚灝寤洪柨鏇炲€归悡鏇㈡倵閿濆�?�骞�?柣鎾村�?�閺岋繝宕遍鐔奉伓
    }
    if (bytesSize < hexLen / 2) {
        zlog_error(zct, "bytesSize:%d < hexLen:%d", bytesSize, hexLen);
        return -1; // 闂備浇�?�х€涒晝�?欓幒妞尖偓鍐╁緞鐎ｂ晝绠�?銈嗘尪閸ㄥ綊�??告笟鈧弻鐔封枔閸喗鐏撻梺娲�?�幖椤戝�??婚敐澶娢╅柕澶堝労娴犲ジ姊洪棃娑欐悙婵炲眰鍔嶇粋宥咁潰瀹€鈧悿鈧柟鑹版彧缁插潡骞�?�ぐ鎺撶厽闁斥晛鍟�?鎺�?�煕濡崵澧紒鍌氱Ч楠炴帡�??崫鍕闂佽崵鍠撴晶妤冩�?�閿熺姵鐓欓柟�?�嗗�?鍊┑鐐碘拡娴滎�?銆佸Δ浣瑰缂佸娉曢�?搴ㄦ⒒娴ｅ憡鍟為柤瑙�?劤闇夌€瑰�??澹�??弸鏃堟煙鐎电ǹ袥闁稿鎸搁埥澶娾枎濡崵鏆┑鐘�?�暯濡插嫰骞忛敓锟�
    }

    for (size_t i = 0; i < hexLen; i += 2) {
        unsigned char highNibble = hexCharToByte(hexStr[i]);
        unsigned char lowNibble = hexCharToByte(hexStr[i + 1]);
        bytes[i / 2] = (highNibble << 4) | lowNibble;
    }

    return 0; // 闂傚倷鑳堕幊鎾绘偤閵娾晛绀夐柡鍥╁枑閸欏繘鏌ㄩ悤鍌涘
}

void stringToHex(const char *str, char *hexStr) {
    while (*str) {
        sprintf(hexStr, "%02x", (unsigned char)*str);
        hexStr += 2;
        str++;
    }
    *hexStr = '\0';
}

void hexToAscii(const char *hexStr, char *asciiStr) {
    int len = strlen(hexStr);
    int i, j = 0;

    for (i = 0; i < len; i += 2) {
        // 闂備浇宕�?慨鏉懨洪埡鍜佹晪鐟滄垿濡甸幇鏉跨倞闁靛ě鈧弸鏍⒑闂堟稓澧曢悗�?�嵆瀹曠數鈧綆鍠�?�崐�?�?�閹寸偟鎳愭繛鍫熒戦妵鍕�?�濠婂懐鐛㈤梺缁樹緱閸犳岸骞戦崟顖涙�?閻熸瑥瀚烽�?�?ユ⒒娴ｅ懙鍦崲閹达箑纾块柣鎾崇瘍瑜版帒骞㈡繛鎴烆焽椤斿�?�?�?妶搴′航闁告瑢鍋撶紓浣插亾閻�?綆鍠楅悡娑樏归敐鍛喐闁�?�?濞€閺岋繝宕遍鐔�?�伓
        int byte;
        sscanf(&hexStr[i], "%2x", &byte);
        // 闂備浇�?�х换鎰崲閹邦儵娑樷枎閹捐櫕杈堥梺鎸庣箓椤︻垶�??告笟鈧弻鐔风暋閻�?�牊鎷辩紓浣�?�贰閸ｏ綁�??婚悢鐑樺珰闁斥晛鍟扮粣鏃堟煟閻樺啿濮夐柛鐘虫崌閸┾偓妞ゆ帒鍊归弳鈺呮煙閾忣偅灏甸柤娲憾瀵濡烽敃鈧崜�?�㈡⒑閸涘﹤鐏﹂柍鐟伴拤II闂備浇�?�х€涒晝�?欓幒妞尖偓鍐醇閵�?�喗鏅為梺璺ㄥ櫐閹凤�?
        asciiStr[j++] = (char)byte;
    }
    // 濠电姷鏁搁崕鎴犵礊閳ь剚銇�?弴鍡楀�?閸欏繘鏌ｉ幇顕呮毌闁稿鎸搁埥澶娾枎濡崵鏆俊鐐�?�?崹鎶芥倿閿斿墽�?欏鑸靛姈閸ゆ垶銇勯幒鎴濃偓鍦焊濠靛鈷戦柛婵嗗濡叉椽鏌涢悩铏磳�?�ゃ垺鐗犻弫鎾绘晸閿燂拷
    asciiStr[j] = '\0';
}

unsigned char ch2hex(char ch) {
    static const char *hex = "0123456789ABCDEF";
    for (unsigned char i = 0; i != 16; ++i)
        if (ch == hex[i]) return i;
    return 0;
}


char *solve(char *dest, const char *src) {
    int i = 0;
    int cnt = 0;
    unsigned char *d = (unsigned char *)dest;
    while (*src) {
        if (i & 1) {
            d[cnt++] |= ch2hex(*src);
        } else {
            d[cnt] = ch2hex(*src) << 4;
        }
        src++;
        i++;
    }
    return dest;
}

void swap(char *data) {
    int tmp;
    tmp = data[1];
    data[1] = data[0];
    data[0] = tmp;
}

int OpenWatchDog() {
    int fd = -1;
    InitGpio(GlobalConfig::GPIO_G.hardWatchDog, 1);
    gpio_set(GlobalConfig::GPIO_G.hardWatchDog, 1); //婵犲痉鏉库偓鏇㈠磹瑜版巻鈧箓宕堕鈧弸渚�?鏌熼梻纾�?厡鐎规挷绶氶弻�?�绠涢敐鍛凹缂備胶�?电敮锟犲蓟閳╁啰鐟瑰┑鐘插暙椤忥�?
    if (0 > (fd = open("/dev/watchdog", O_WRONLY))) {
        zlog_error(zbt, "fail to open /dev/watchdog");
    }
    return fd;
}

int WriteWatchDog(int fd) {
    if (1 != write(fd, "0", 1)) {
        zlog_error(zbt, "fail to feed watchdog");
        return 1;
    }
    return 0;
}

std::string TrimStringLeft(const char *szData, const char *szTargets) {
    std::string strData = szData;
    int nPos = 0;
    nPos = strData.find(szTargets);
    while (nPos == 0) {
        strData.erase(nPos, 1);
        nPos = strData.find(szTargets);
    }
    return strData;
}

std::string TrimStringRight(const char *szData, const char *szTargets) {
    std::string strData = szData;
    int nPos = 0;
    nPos = strData.rfind(szTargets);
    while ((nPos == (int)(strData.size() - 1)) && (nPos >= 0)) {
        strData.erase(nPos, 1);
        nPos = strData.rfind(szTargets);
    }
    return strData;
}

std::string GetOneContent(const char *szData, int nRow, const char *szSeparate) {
    std::string strParam = "";
    std::string strTemp = szData;
    int nFirstPos = -1;
    for (int i = 0; i < nRow; i++) {
        nFirstPos = strTemp.find(szSeparate, nFirstPos + 1);
        if (nFirstPos < 0) return strParam.c_str();
    }

    int nSecondPos = strTemp.find(szSeparate, nFirstPos + 1);
    if (nSecondPos < 0) {
        strParam = strTemp.substr(nFirstPos + 1);
    } else {
        strParam = strTemp.substr(nFirstPos + 1, nSecondPos - nFirstPos - 1);
    }
    
    strParam = TrimStringRight(strParam.c_str(), " ");
    strParam = TrimStringLeft(strParam.c_str(), " ");  
    return strParam.c_str();
}

int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop) {
    zlog_info(zbt, "[set_opt] speed:%d, bits:%d, event:%c, stop:%d", nSpeed, nBits, nEvent, nStop);
    struct termios newtio, oldtio;
    if (tcgetattr(fd, &oldtio) != 0) { //濠电姷顣藉Σ鍛村磻閳ь剟鏌涚�?ｎ偅灏扮紒缁樼洴瀵爼骞�?鐐插闂佽崵鍠�?ú鏍涘┑鍡欐殾闁挎繂顦伴弲鏌ユ煕閳╁喚鐒�?柨鏇炲€归悡鏇熸叏濡搫鈷旈柣锝堜含閹叉悂鎮ч崼銏犲绩闂佽鍠曠划娆撳极閹剧粯鏅搁柨鐕傛�??
        zlog_error(zbt, "tcgetattr fail");
        return -1;
    }
    bzero(&newtio, sizeof(newtio));
    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

    switch (nBits) {
        case 7: newtio.c_cflag |= CS7; break;
        case 8: newtio.c_cflag |= CS8; break;
        default:
            zlog_error(zbt, "invalid nbits:%d", nBits);
            break;
    }

    switch (nEvent) {
        case 'O':
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            newtio.c_iflag |= (INPCK | ISTRIP);
            break;
        case 'E':
            newtio.c_iflag |= (INPCK | ISTRIP);
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            break;
        case 'N': newtio.c_cflag &= ~PARENB; break;
        default:
            zlog_error(zbt, "invalid event:%c", nEvent);
            break;
    }

    switch (nSpeed) //闂備浇宕�?慨宕囩矆娴ｈ娅犲ù鐘�?儐閸嬵亪鏌涢埄鍐︿粶闁哄鐗犻弻鏇＄疀鐎ｎ亞浠煎銈冨劜椤ㄥ﹪�?婚敐鍛牚闁归偊鍘奸锟�?
    {
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;
        case 460800:
            cfsetispeed(&newtio, B460800);
            cfsetospeed(&newtio, B460800);
            break;
        default:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            zlog_error(zbt, "invalid speed:%d, use B9600", nSpeed);
            break;
    }
    if (nStop == 1) //闂備浇宕�?慨宕囩矆娴ｈ娅犲ù鐘�?儐閸嬵亪鏌涢埄鍐�?�缁惧墽�?换婵囩節閸屾凹浼岄梺鍛婃尰閸庢娊婀侀梺鎸庣箓缁绘垹鈧熬鎷�
        newtio.c_cflag &= ~CSTOPB;
    else if (nStop == 2)
        newtio.c_cflag |= CSTOPB;
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;
    tcflush(fd, TCIFLUSH);
    if ((tcsetattr(fd, TCSANOW, &newtio)) != 0) {
        zlog_error(zbt, "tcsetattr fail");
        return -1;
    }
    return 0;
}

void IniReadValue(const char *section, const char *key, char *val, const char *file) {
    FILE *fp;
    int i = 0;
    int lineContentLen = 0;
    int position = 0;
    char lineContent[LINE_CONTENT_MAX_LEN];
    bool bFoundSection = false;
    bool bFoundKey = false;
    fp = fopen(file, "r");
    if (fp == NULL) {
        zlog_error(zbt, "fail to open %s", file);
        return;
    }

    while (feof(fp) == 0) {
        memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
        fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
        if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n')) {
            continue;
        }

        // check section
        if (strncmp(lineContent, section, strlen(section)) == 0) {
            bFoundSection = true;
            // printf("Found section = %s\n", lineContent);
            while (feof(fp) == 0) {
                memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
                fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
                // check key
                if (strncmp(lineContent, key, strlen(key)) == 0) {
                    bFoundKey = true;
                    lineContentLen = strlen(lineContent);
                    // find value
                    for (i = strlen(key); i < lineContentLen; i++) {
                        if (lineContent[i] == '=') {
                            position = i + 1;
                            break;
                        }
                    }
                    if (i >= lineContentLen) break;
                    strncpy(val, lineContent + position, strlen(lineContent + position));
                    lineContentLen = strlen(val);
                    for (i = 0; i < lineContentLen; i++) {
                        if ((lineContent[i] == '\0') || (lineContent[i] == '\r') || (lineContent[i] == '\n')) {
                            val[i] = '\0';
                            break;
                        }
                    }
                } else if (lineContent[0] == '[') {
                    break;
                }
            }
            break;
        }
    }
    fclose(fp);
    if (!bFoundSection) {
        zlog_error(zbt, "No section = %s", section);
    } else if (!bFoundKey) {
        zlog_error(zbt, "No key = %s", key);
    }    
}

int readStringValue(const char *section, const char *key, char *val, const char *file) {
    zlog_info(zct, "section = %s, key = %s, file = %s", section, key, file);
    if (section == NULL || key == NULL || val == NULL || file == NULL) {
        zlog_error(zct, "input parameter, section:%s, key:%s, val:%s, file:%s exist NULL", section, key, val, file);
        return -1;
    }
    char sect[SECTION_MAX_LEN];
    memset(sect, 0, SECTION_MAX_LEN);
    sprintf(sect, "[%s]", section);
    IniReadValue(sect, key, val, file);
    return 0;
}

int readIntValue(const char *section, const char *key, const char *file) {
    char strValue[STRVALUE_MAX_LEN];
    memset(strValue, '\0', STRVALUE_MAX_LEN);
    if (readStringValue(section, key, strValue, file) != 0) {        
        return 0;
    }
    return (atoi(strValue));
}

void IniWriteValue(const char *section, const char *key, char *val, const char *file) {
    FILE *fp;
    char lineContent[LINE_CONTENT_MAX_LEN];
    char strWrite[LINE_CONTENT_MAX_LEN];
    bool bFoundSection = false;
    bool bFoundKey = false;
    int err = 0;
    memset(lineContent, '\0', LINE_CONTENT_MAX_LEN);
    memset(strWrite, '\0', LINE_CONTENT_MAX_LEN);
    sprintf(strWrite, "%s=%s\n", key, val);
    fp = fopen(file, "r+");
    if (fp == NULL) {
        zlog_error(zct, "fail to open:%s", file);
        return;
    }

    while (feof(fp) == 0) {
        memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
        fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
        if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n')) {
            continue;
        }
        // check section
        if (strncmp(lineContent, section, strlen(section)) == 0) {
            bFoundSection = true;
            while (feof(fp) == 0) {
                memset(lineContent, 0, LINE_CONTENT_MAX_LEN);
                fgets(lineContent, LINE_CONTENT_MAX_LEN, fp);
                // check key
                if (strncmp(lineContent, key, strlen(key)) == 0) {
                    bFoundKey = true;
                    printf("%s: %s=%s\n", __func__, key, val);
                    fseek(fp, (0 - strlen(lineContent)), SEEK_CUR);
                    err = fputs(strWrite, fp);
                    if (err < 0) {
                        printf("%s err.\n", __func__);
                    }
                    break;
                } else if (lineContent[0] == '[') {
                    break;
                }
            }
            break;
        }
    }
    fclose(fp);
    if (!bFoundSection) {
        zlog_warn(zct, "No section = %s", section);
    } else if (!bFoundKey) {
        zlog_error(zct, "No key = %s", key);
    }    
}

int writeStringVlaue(const char *section, const char *key, char *val, const char *file) {
    char sect[SECTION_MAX_LEN];
    zlog_debug(zct, "section = %s, key = %s, file = %s", section, key, file);
    if (section == NULL || key == NULL || val == NULL || file == NULL) {
        zlog_error(zct, "input parameter(s) is NULL!");
        return -1;
    }
    memset(sect, 0, SECTION_MAX_LEN);
    sprintf(sect, "[%s]", section);
    IniWriteValue(sect, key, val, file);
    return 0;
}

int writeIntValue(const char *section, const char *key, int val, const char *file) {
    char strValue[STRVALUE_MAX_LEN];
    memset(strValue, 0, STRVALUE_MAX_LEN);
    sprintf(strValue, "%d", val);
    writeStringVlaue(section, key, strValue, file);
    return 0;
}

int getDiskInfo(char *diskTotal, char *diskFree) {
    DISK diskInfo;    
    /* 1.闂傚倷绀侀崥瀣磿閹惰�?�搴婇柤鑹扮�?娴滃綊鏌ㄩ悤鍌涘�?/home/婵犵數鍋為崹�?曞�?�閹间緡鏁勫璺衡看閻掕棄霉閻撳海鎽犻柛搴＄Ч閺屾�?�?�?妸銉ュ�?�闂佺ǹ�?�嗛幐楣冨�??閻樺樊鍟�?い鏂�?悑濞�?秹�?��?�崒娆愮グ�?�ゆ洘绮撻獮蹇涙晸閿燂拷 */
    statfs("/", &diskInfo);
    unsigned long long blocksize = diskInfo.f_bsize;
    unsigned long long totalsize = blocksize * diskInfo.f_blocks; 
                                                                  

    /* 2.闂傚倷绀侀崥瀣磿閹惰�?�搴婇柤鑹扮�?娴滃綊鏌涢妷锝呭闁崇粯�?�?弻�?�堫檨闁告挻姘ㄧ划娆�?緞鐏炵ǹ浜鹃柨婵嗙凹缁ㄥ鏌嶉柨瀣ⅹ闂囧鏌ㄥ┑鍡橆棤闁瑰啿鎳橀弻�?�囨喆閸曨厼鈷屽┑�?�硷工椤嘲顕ｉ崼鏇炵闁绘劕妯婃�?�鍛存⒒娴ｅ憡鍟為柣鐕佸灦瀹曞綊骞庨挊澶�??�?梺闈涚墕濞层劑�?屽顓犵鐎瑰�?�鍠曠花濂告煥濞戞艾鏋涢柡宀�?�?婵℃悂濡烽妷顔绘偅闂備線娼уú銈吤洪妸锔绢洸闁归棿鐒﹂弲鎼佹煥閻曞倹瀚� */
    unsigned long long freeDisk = diskInfo.f_bfree * blocksize;       //闂傚倷绀侀幉锟犲�?�閹绢喖鐤炬繛鍡樺灩缁€濠囨煙鐎电ǹ啸闁活厽纰嶇换娑橆啅椤旇崵鍑归梺鎸庣〒閸犳牠�?婚敐澶娢╅柕澶堝労娴犲ジ姊洪棃娑欐悙婵炲眰鍔嶇粋宥�?��?�娴ｈ娅㈤梺璺ㄥ櫐閹凤�?
//    unsigned long long availableDisk = diskInfo.f_bavail * blocksize; //闂傚倷绀侀幉锟犳偡椤栫偛鍨傞柟�?版閺�?�線鏌曢崼婵囧窛闁活厽纰嶇换娑橆啅椤旇崵鍑归梺鎸庣〒閸犲酣鈥﹂崸妤�?閱囬柛鈩冾殔閺嗙喐鎱ㄩ敐蹇斿�?
    
    sprintf(diskTotal, "%llu", totalsize >> 20);
    sprintf(diskFree, "%llu", freeDisk >> 20);
    return 1;
}

unsigned short cal_chksum(unsigned short *addr, int len) {
    int nleft = len;
    int sum = 0;
    unsigned short *w = addr;
    unsigned short answer = 0;
    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }
    if (nleft == 1) {
        *(unsigned char *)(&answer) = *(unsigned char *)w;
        sum += answer;
    }
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;
    return answer;
}

int socketHeart(const char *pSendData) {
    zlog_info(zct, "socketHeart");
    int sockfd;                       // Socket闂傚倷绀侀幖�?�﹀磹缁�?５娲晲閸涱亝鐎婚梺闈涚箞閸婃洜�?婚悽鍝ュ彄闁搞儯鍔忔竟�?�€鏌ｅΔ浣圭殤缂佽鲸�?掕灃閻庯綆鍋�?锟�?
    struct sockaddr_in serverAddr {}; // Server闂傚倷绶�?濠�?⒔閸曨偒鐔嗘俊�?�欒閻掍粙鏌涢幇鍏哥敖缁炬儳銈搁弻鐔煎箚瑜滈崵鐔兼煃瑜滈崜锕傚垂闁秴绠柛娑�?�摠閺呮悂鏌ㄩ悤鍌涘�?

    // 闂傚倷绀侀幉锛�?暜濡ゅ啰�?欓柟瀵�?�Х绾句粙鏌熺紒妯肩潉cket
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        zlog_error(zct, "Failed to create socket.");
        return 1;
    }

    // 闂備浇宕�?慨宕囩矆娴ｈ娅犲ù鐘�?儐閸嬵亪鏌涘┑鍫濈€瑀ver闂傚倷绶�?濠�?⒔閸曨偒鐔嗘俊�?�欒閻掍粙鏌涢幇銊︽珖闁崇懓绉归弻宥�?�煛娴ｅ憡娈ㄧ紓浣瑰敾閹凤拷
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(18393); // TCP婵犳鍠楃敮妤冪矙閹烘挾浠氭俊鐐€�?幑浣哥暦閻㈤潧鍨濋柍鍝勬媼閺佸秵鎱ㄥ鍡楀�?缂佸顦靛娲川婵犲�??鍣┑鐐存尭濠€�?嶅�??瑜版帗鏅搁柨鐕傛�?80
    inet_pton(AF_INET, "192.168.1.147", &serverAddr.sin_addr);

    // 闂備礁鎼ˇ�?�﹀疾濠靛纾�?�柣鎰仛閺嗘粓鏌熺紒銏犳灈缂佲偓閸℃稒鐓熺憸搴ｆ绾炬潳er
    if (connect(sockfd, reinterpret_cast<struct sockaddr *>(&serverAddr), sizeof(serverAddr)) == -1) {
        zlog_error(zct, "Failed to connect to the server.");
        close(sockfd);
        return 1;
    }

    // 闂傚倷绀侀幉锟犳偡閿曞倸鍨傞柛褎顨呴悞�?亜閹达絾纭舵い锔煎�?缁辨帡宕崟顐熸寖闂佸湱鎳撶�?�?即骞�?ぐ鎺濇晝闁挎繂妫崯鈧梻鍌欒兌椤㈠�?顢氶弽�?�炵獥闁哄稁鍋€閸�??挾鍠婃径瀣�?

    ssize_t bytesSent = send(sockfd, pSendData, strlen(pSendData), MSG_NOSIGNAL);
    if (bytesSent == -1) {
        zlog_error(zct, "Failed to send heartbeat packet.");
        close(sockfd);
        return 1;
    } else if (static_cast<size_t>(bytesSent) != strlen(pSendData)) {
        zlog_error(zct, "Partially sent heartbeat packet.");
        close(sockfd);
        return 1;
    }

    // 闂傚倷鑳舵灙缂佺�?鍨剁换娑欑節閸�??姤绋撻崰濠囧煛閻滅€攅t闂備礁鎼ˇ�?�﹀疾濠靛纾�?�柣鎰仛閺嗘粓鏌ㄩ悤鍌涘
    close(sockfd);
    return 0;
}

// Ping闂傚倷绀侀幉锟犲垂閸忓吋鍙忛柕�?濐槸�?规煡鏌ｉ�?�?�?闁哄拋鍓熼幃妤呭捶椤撶偘姘eout婵犵數鍋為崹�?曞�?�閸モ晝纾芥慨妯夸含閻捇鏌熺紒銏犳灈缂侇偄绉归弻銈囩矙鐠恒劋绮靛銇礁娲﹂埛鎺�?�煕鐏炲墽绠�?憸鎶婂懐纾奸弶鍫涘�?�缁犵偟鈧娲╃换婵嗩嚕閺夋埈娼╅弶鍫�?暕閵忋倖鈷戦柛婵嗗椤忣偅淇婇銈庢敵,10000 濠电姵�?�栭崳�?�滅礊閸℃稑纾�?�柛鈩冨喕缂嶆牠鏌ㄩ悤鍌涘=10 缂傚倸鍊风粈渚€篓閳ь剟鏌熼崙銈嗗�?
//闂傚倷鑳堕幊鎾绘偤閵娾晛绀夐柡鍥╁枑閸欏繑绻涢幋娆忕仾闁哄拋鍓氶幈銊ノ熼搹鐧哥礊缂備胶�?甸悡锟犲蓟濞戙垹�?妞ゆ牗绋戦锟�0闂傚倷鐒︾€笛呯矙閹达附鍤愭い鏍�?仜�?�呴梺鐟邦嚟婵數鈧艾�?烽弻鏇熷緞濡�?�浠紓浣瑰姈椤ㄥ﹤顕ｉ崼鏇炵厸闁�?�本绋撻崣鍡椻攽閻愰鍤�?柟鍑ゆ�??1闂傚倷鑳堕、濠囧�?�椤忓牆绠柨鐕傛�??-1
int Ping(const char *ips, int timeout) {
    struct timeval *tval;
    int maxfds = 0;
    fd_set readfds;

    int iRet = 0;
    struct sockaddr_in addr;
    struct sockaddr_in from;
    // 闂備浇宕�?慨鎶芥倿閿曞倸纾块柟�?板Г閸嬧晝绱撳搴㈡婵犵數鍎戠徊钘�?�洪悩璇�?�?婵犻潧娲ら�?嶆煥閻曞倹瀚�
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ips);

    int sockfd;
    // 闂傚倷绀侀幉锟犳偡閿曞倹鍋�?柡鍥╁У椤�?粙鏌ｉ鍛傛溈ket  闂傚倷绶�?�?�螞閹绢喖绠柨鐕傛�?  婵犵數濮烽。浠�?焵椤掆偓閸熷潡鍩�?椤掆偓缂嶅﹪骞冨Ο璇茬窞濠电偟鍋撻悡銏ゆ⒑閻愯棄鍔氶柛鐔锋健閿濈偤�?缁犲垼o 闂備礁鎼ˇ�?�﹀疾濠婂牊鍋￠柍鍝�?噹闂傤垶姊洪崹�?�呭剰�?�ゆ洝椴搁幈銊ヮ潨閸℃绠归悶�?�哺濮婄粯鎷呯粙璺ㄦ闂佺懓鍤�?幏锟�?
    sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (sockfd < 0) {
        zlog_error(zct, "ip:%s,socket error", ips);
        return -1;
    }

    struct timeval timeo;
    // 闂備浇宕�?慨鎶芥倿閿曞倸纾块柟�?板Г閸嬧晝绱撳鍥骏meOut闂傚倷绀侀幖�?�﹀�?椤愶附鍋夐柣鎾冲濞戙垺鏅搁柨鐕傛�??
    timeo.tv_sec = timeout / 1000;
    timeo.tv_usec = timeout % 1000;

    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo)) == -1) {
        zlog_error(zct, "ip:%s,setsockopt error", ips);
        close(sockfd);
        return -1;
    }

    char sendpacket[2048];
    char recvpacket[2048];
    // 闂備浇宕�?慨鎶芥倿閿曞倸纾块柟�?板Г閸嬧晝绱撳鍥х毇ng闂傚倷绀侀幉锟犳偋椤撱垹绠柨鐕傛�?
    memset(sendpacket, 0, sizeof(sendpacket));

    pid_t pid;
    // 闂傚倷绀侀幉锟犳偡閿曞倹鍋�?柡鍥╁У椤�?粙鏌ｉ埡濠冿紬D闂傚倷鐒︾€笛呯矙閹寸偟闄勯柡鍐ㄥ€荤粈濠囨煛閸愶絽浜剧紓浣割儏椤﹀�?顕ｈ閵嗘帗鍒婂濠囨⒒娴ｅ湱婀介柛鏂跨焸瀹曠敻鎮悥宄秂nce ID
    pid = getpid();

    struct ip *iph;
    struct icmp *icmp;

    icmp = (struct icmp *)sendpacket;
    icmp->icmp_type = ICMP_ECHO; //闂傚倷鐒﹂幃�?曞磿閹惰棄纾婚柣鎰棘閻旂ǹ绶為悘鐐村劤閻濅即姊绘担鍝ヤ虎妞ゆ垵娲ら敃銏ゆ晸閿燂拷
    icmp->icmp_code = 0;
    icmp->icmp_cksum = 0;
    icmp->icmp_seq = 0;
    icmp->icmp_id = pid;
    tval = (struct timeval *)icmp->icmp_data;
    gettimeofday(tval, NULL);
    icmp->icmp_cksum = cal_chksum((unsigned short *)icmp, sizeof(struct icmp)); //闂傚倷绀侀幖�?�ょ矙閸曨厽宕叉繝闈涱儐閸�??﹢鏌ㄩ悤鍌涘�?

    int n = sendto(sockfd, (char *)&sendpacket, sizeof(struct icmp), 0, (struct sockaddr *)&addr, sizeof(addr));
    if (n < 1) {
        zlog_error(zct, "ip:%s,sendto error", ips);
        close(sockfd);
        return -1;
    }

    // 闂傚倷娴�?～澶�?娴犲纾块弶鍫�?亖娴滃綊鏌ㄩ悤鍌涘
    // 闂傚倷鐒﹂惇褰掑垂绾懌浜瑰璺虹焷婵櫕銇�?幒鎴濐仼闁活厽顨嗛妵鍕冀閵娧�?暤闂佸憡蓱閹告娊�?婚悢鐓庣畳闁�?儤鍨�?慨搴ㄦ偡濠婂�?绶查柣妤佹尭閻ｅ嘲顫濈捄铏归獓闂佸�?�鐓堥崰鏍椤撶喓绠鹃悗鐢登�?�牎濠电�?鍋撴い锝�?礆g闂傚倷鐒﹂惇褰掑礉瀹€鈧埀顒佸�?閸撴�?鎳為柆�?�嗗殤�?�ゆ帒鍊块埞蹇涙⒑閸濆�??鏆婇柛瀣尵缁辨帗寰勭仦钘夊�?�濡ょ姷鍋�?��?��?�躲�?佸☉銏犖ч柛銉㈡櫓濡茬兘�?�绘担鍛婅�?�妞わ絼绮欏畷鎴﹀箻鐡掍�?�缍婇幃鈺咁敊閻撳�?��?�缂傚倷鑳剁划顖炴偋閻樿钃熼悘鐐�?櫕閺嗗�?�鏌涢幇顔间壕闁活厽顨婂娲倻閳轰�?�澹曢梺鍛婃煥閻倿鐛崱妯肩瘈闁搞�?鍔屾禒銏ゆ⒑鐠恒劌娅愰柟鍑ゆ�?
    int cnt = 0;
    while (1) {
        // 闂備浇宕�?慨鎶芥倿閿曞倸纾块柟�?板Г閸嬧晝绱撳鍥骏meOut闂傚倷绀侀幖�?�﹀�?椤愶附鍋夐柣鎾冲濞戙垹閿ゆ俊銈�?劍濞�?牠鎮楅崗澶婁壕闂佸憡鍔︽禍鐐�?敊閹邦兘鏀介柣鎰级椤ユ垿鏌涢幘瀵哥畺闁哄懎鐖奸幃鈺冩嫚閹绘帒鎸ゆ俊鐐�?�?悧妤冨垝瀹ュ�?鏄ラ柛灞剧⊕閸欏繑绻濋崹顐ｅ暗缂佸鍓熼弻鐔兼儌閸濄儳蓱闂佺懓鍢查幊搴ㄣ偑娴兼潙宸濇い鏃�?Г椤撳綊�?�绘担瑙勩仧闁绘挸顦甸獮蹇涙晸閿燂拷
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);
        maxfds = sockfd + 1;
        n = select(maxfds, &readfds, NULL, NULL, &timeo);
        if (n <= 0) {
            zlog_info(zct, "ip:%s,Time out error", ips);
            close(sockfd);
            iRet = -1;
            break;
        }

        // 闂傚倷娴�?～澶�?娴犲纾块弶鍫�?亖娴滃綊鏌ㄩ悤鍌涘
        memset(recvpacket, 0, sizeof(recvpacket));
        int fromlen = sizeof(from);
        n = recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen);
        zlog_info(zct, "recvfrom Len:%d", n);
        if (n < 1) {
            close(sockfd);
            iRet = 1;
            break;
        }

        char *from_ip = (char *)inet_ntoa(from.sin_addr);
        // 闂傚倷绀侀幉锛�?暜閸�?剙纾归柡宥庡幖閽�?喖鏌涢妷顔煎闁告瑥锕ラ妵鍕冀閵娧屾�?�闂佺ǹ�?�搁敃�?�堝蓟閿熺姴绀�?梻鍫熺〒娴犳挳姊洪幖鐐测偓鏍垝瀹€鍕垫晩闊洦绋掗崕搴�?亜閿曗偓缁辨闂傚倷鐒﹂惇褰掑礉瀹€鈧埀顒佸�?閸撴瑧鍙呴梺鍝勭Р閸斿瞼娆㈤悙鐑�?�叆闁绘洖鍊�?�?氾拷
        if (strcmp(from_ip, ips) != 0) {
            zlog_info(zct, "NowPingip:%s Fromip:%s NowPingip is not same to Fromip,so ping wrong!", ips, from_ip);
            close(sockfd);
            iRet = 1;
            break;
        }

        iph = (struct ip *)recvpacket;
        icmp = (struct icmp *)(recvpacket + (iph->ip_hl << 2));

        zlog_info(zct, "ip:%s,icmp->icmp_type:%d,icmp->icmp_id:%d\n", ips, icmp->icmp_type, icmp->icmp_id);
        // 闂傚倷绀侀幉锛�?暜閸�?剙纾归柡宥庡幖閽�?喖鏌涢�?�陇鎶梟g闂傚倷鐒﹂幃�?曞磿閹惰棄纾绘繛鎴旀嚍閸�?剙钃熼柕澶堝劤椤﹂亶姊洪崨濠佺繁闁搞劑浜堕幃楣冩焼瀹ュ棛鍘藉┑鈽嗗灠閻忔繈�?￠幇鐗堢厓鐟滄粓宕滈妸鈺佺闁跨噦鎷�?
        if (icmp->icmp_type == ICMP_ECHOREPLY && icmp->icmp_id == pid) // ICMP_ECHOREPLY闂傚倷鐒﹂幃�?曞磿閹惰棄纾婚柣鎰棘閻旂ǹ绶為悗锝庡亜閸斿懘姊洪�?鍕�?闁�?�﹤�?烽獮妤呮晸閿燂拷
        {
            // 濠电姵�?�栭崰妤冩崲閹邦喖绶ゅù鐘�?儐閸�?鏌涢幘鍙�?�樂闁绘帒锕娲敆閳ь剛绮旈鈧畷鎴﹀箻鐠�?尙鍔﹀銈嗗笒鐎氼剛绮堥崟顖涚厱婵犻潧�?楅顏堟煕鎼�?垺绀�?柡宀�?到�?�即骞�?鐑嗕紦
            zlog_info(zct, "icmp succecss .............  \n");
            break;
        } else if (cnt < 3) {
            // 闂傚倷绀侀幉锟犳偄椤掑倻涓嶉柟杈剧畱閸ㄥ倹銇�?弽銊х煂缁�?崘鍋愰幉姝岀疀濞戞瑥浠�?梺鐓�?潟閸婃銇欓幎鑺ョ叆闁绘洖鍊�?�?氾拷
            cnt++;
            continue;
        } else {
            close(sockfd);
            iRet = -1;
            break;
        }
    }
    close(sockfd);
    return iRet;
}

int get_netlink_status(const char *if_name) {
    int skfd;
    struct ifreq ifr;
    struct ethtool_value edata;
    edata.cmd = ETHTOOL_GLINK;
    edata.data = 0;
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name) - 1);
    ifr.ifr_data = (char *)&edata;
    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) == 0) return -1;
    if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1) {
        zlog_error(zct, "ioctl failed, if_name:%s", if_name);
        close(skfd);
        return -1;
    }
    close(skfd);
    return edata.data;
}

// 闂備浇�?�х换鎰崲閹邦儵娑樷槈濞嗘劖鐝峰┑掳鍊曢幊搴ｂ偓姘槹閵囧�?�骞掗崱妞惧闁荤喐�?嶆刊钘�?�枖閺囥垹鐒�?い鎺嶈兌閳洘銇�?妸銉уⅵ�?�ゃ垺鐗楅幏鍛村捶椤撴稒鐏冮梻浣告啞閻熴儵藝椤栫儐鏁侀柡鍥ュ灪閻撴洟鏌熼悜�?虹仸妞ゃ儲鐟╅幃褰掑箛椤斿吋鐏堥悗娈�?櫘閸�?棝鍩�?椤掍胶鈯曢拑杈ㄧ箾閸繂顣崇紒杈ㄦ尰閹峰懐绮欏▎鍙ョ�?闂備焦鎮堕崝宥呯暆閹间�?�绠氶柛鎰靛枛缁�?瀣亜閹板�?�鍒伴柍褜鍓欓…宄邦潖閾忚瀚氱憸搴ｂ偓姘炬�?
std::vector<int> splitVersion(const std::string &version) {
    std::vector<int> parts;
    std::stringstream ss(version);
    std::string part;

    // 闂傚倷鑳堕崕鐢�?�磻閹捐绀夐幖娣妼绾惧鏌ㄥ┑鍡橆棡濠�?�垰鐡ㄧ换婵囩�?�閹傚闂佽崵�?甸崝妤呭窗閺�?�?殾婵ǹ娉涢獮銏＄箾閹寸偟鎳愰柛�?�焽缁辨挻鎷呯拠鈩冾吅闁荤姳绶ょ徊�?ｉ幇�?�芥斀閻庯綆浜為ˇ�?�︽⒑缁洖澧叉い銊ユ嚇钘熼�?鍥ㄧ⊕閻撶喐淇婇妶鍌�?壕闂佺粯顨呴敃銈夋晝閵忊�?愁嚤闁哄鍨归悡鎴︽⒑鐠恒劌娅愰柟鍑ゆ�??
    while (std::getline(ss, part, '.')) {
        parts.push_back(std::stoi(part)); // 闂備浇�?�х换鎰崲閹邦儵娑�?�旈崨�?�炵�?柟鍏肩暘閸斿瞼�?堥崼銉︾厵缂備焦锚缁楁岸鏌涙繝鍕毈闁哄矉缍佹俊鎼佸Ψ閵�?�喕绱旈梻浣呵圭�?涒晠骞愰崘鑼�?�婵ǹ娉涢獮銏℃叏濮楀棗骞橀柕鍫櫍�?婅�?�娑甸崪浣告異濠电姭鎳囬崑鎾绘煟閻樺啿濮夐柛鐘崇�?椤曪綁顢曢妶鍌氫壕婵炴垶顏伴幋婵冩灁闁跨噦鎷�?
    }

    return parts;
}

// 濠电姵�?�栭崳�?�滃緤閹灛娑欐媴閻戞﹩鍋ㄥ┑鐘绘涧濞层劑鍩㈤弮�?熺厪闁割偅绻傞顓㈡煕閵堝拋鍎旈柡宀�?到铻�?柍�?�鍓熼幃褎绻濋崒锕佲偓鍨归崗鍏肩稇闁活厽顨婇弻銊╂偆閸屾稑顏�
int compareVersions(const std::string &version1, const std::string &version2) {
    std::vector<int> v1 = splitVersion(version1);
    std::vector<int> v2 = splitVersion(version2);

    // 闂傚倷鑳堕幊鎾绘倶濮樿泛纾块柟鎯版閺勩儳鈧厜鍋撻柛鏇ㄥ亜閻濇﹢姊洪柅鐐茶�?��?�у瓨鎱ㄦ繝鍌涜�?�闁圭懓瀚版俊鎼佹晜閻愵剚�?�忛梻鍌欒兌缁垶銆�?崨瀛樺亱濠电姴鍋婇懓鍨归崗鍏肩稇闁活厽顨婇弻锝�?��?�閿濆棭�?�?梺鍛婃煟閸庣敻�??诲☉銏犵闁瑰鍎愬Λ锕傛⒑閸濆�??顥″瀛樻倐�?�炲棝�??崼鐔告闂佽法鍣﹂幏锟�
    size_t maxLength = std::max(v1.size(), v2.size());

    for (size_t i = 0; i < maxLength; ++i) {
        int num1 = i < v1.size() ? v1[i] : 0; // 婵犵數濮烽。浠�?焵椤掆偓閸熷潡鍩�?椤掆偓缂嶅﹪骞冨Ο璇茬窞闁归偊鍓濋幗鏇㈡⒑閸︻厼顣兼繝銏★耿瀹曟繈濡烽埡鍌滃幈闂佸湱鍎ら崹鍫曀夊▎鎴犵＜婵°倐鍋撴い锕備憾閸┾偓妞ゆ帊鑳堕埊鏇㈡煥濮橆厾绡€闁逞屽墴椤㈡�?�宕奸悢鍛婄彨闁诲�?�鍘滈崑鎾绘煕閹邦喖浜剧紓�?�咃攻缁绘盯骞�??悙瀛樺創闂佺懓鍤栭幏锟�?0
        int num2 = i < v2.size() ? v2[i] : 0;

        if (num1 > num2) return 1;  // version1 婵犵數濮伴崹褰掓偉閵忋倕纾兼繝濠傛椤�?�? version2
        if (num1 < num2) return -1; // version1 闂備浇�?�х换鎰崲閹邦喗宕查悗锝庡墲婵娊鏌ㄩ悤鍌涘�? version2
    }

    return 0; // 闂傚倷鑳剁划顖炪�?�?崨瀛樺亱濠电姴鍋婇懓鍨归崗鍏肩稇闁活厽顨呴—鍐偓锝庝簻椤掋垻绱掓担鍦弨闁哄�?绋戦～婵�?倷椤掆偓椤忥�?
}

void Binary_Bit(unsigned char *p_data, unsigned char position, int flag) {
    //婵犵數鍋涢悺銊у垝瀹€鍕剹濞达絿鍎ゅ畷鍙夋叏濡炶浜鹃悗瑙勬礃瀹€鎼佸箠濠婂牊鍋ㄩ梻鍫熺☉缁傚繐鈹戦悙鑸靛涧缂佽尙鏅划鏃堝醇閺囩喎浠鹃梺�?曞墲缁�??帡鍩涢弽顓熺厾闁归棿鐒﹀☉�?�鏌ｈ箛鏃戞疁闁哄�??鍊濆鍫曞�?�鎼粹剝顏熺紓鍌欑劍濡垿骞忛敓锟� position婵犵數鍋為崹�?曞�?�娴ｅ�?�娴�?柕濞у懐顦梺鍛婄⊕濞兼瑩�?告笟鈧弻銊╂偆閸屾稑�?��(婵犵數鍋涢顓熷垔閹绢喖绠柨鐕傛�??0 闂佽瀛╅鏍窗閹烘纾婚柟鐐灱閺�?鑺ャ亜閺囩偞顥為悗�?�炬�?)
    if (flag) {
        *p_data |= 0x01 << (position);
    } else {
        *p_data &= ~(0x01 << (position));
    }
}
std::string get_file_md5(const std::string& file_path) {
    // 使用 md5sum 命令计算文件的 MD5 值
    std::string command = "md5sum " + file_path + " | awk '{ print $1 }'";

    // 使用 popen 执行命令并获取输出
    std::array<char, 128> buffer;
    std::string result;
    std::shared_ptr<FILE> pipe(popen(command.c_str(), "r"), pclose);
    
    if (!pipe) {
        std::cerr << "Error: Unable to run md5sum command" << std::endl;
        return "";
    }

    // 从命令的输出流中读取数据
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
        result += buffer.data();
    }

    // 去除末尾的换行符
    result.erase(result.find_last_not_of("\n") + 1);

    return result;
}