#include "device_uhd_cpp.h"
// #include "UHD_Probe.h"
#include "DDCSampTable.h"
#include "FIRGenLowpass_no_ipp.h"
#include "device_uhd_struct.h"
#include <chrono>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace uhd;

#define addr_dev_ref_time 0x4200 // "参考时钟"  b:0101 GPS ; b:1010 外参考 ; b:1001 内参考
#define addr_dev_version 0x420c  // "设备版本"
#define addr_rx_data_sw 0x4210   //"数据接收开关"
#define addr_dev_led 0x421c
#define addr_rx_kd_fft_sw 0x4220           // fft 开关
#define addr_rx_kd_fft_len 0x4224          // fft 长度 1k,2k,4k,8k,16k,32k
#define addr_rx_kd_fft_type 0x4228         // fft 类型 0jxc,1hnc,2hmc,3blackman
#define addr_rx_kd_fft_preiod 0x422c       // fft 周期 1-1000 ms
#define addr_rx_kd_ddc_data_sw 0x4240      // 宽带数据开关
#define addr_rx_kd_ddc_ch 0x4264           // 宽带通道号
#define addr_rx_kd_ddc_fc 0x4270           //"过滤系数"
#define addr_rx_kd_ddc_ch_sw 0x4208        //"中频开关"  切换通道 接收模块 1:9002模块 0:30M模块
#define addr_rx_kd_kz_speed 0x4214         // 快照速度
#define addr_rx_ch0_30Mhz_cw 0x4278        // 接收30Mhz 控制字
#define addr_rx_ch1_30MHz_cw 0x427c        // 接收30Mhz 控制字
#define addr_rx_kd_ch0_ddc_sf 0x4244       //"采样率"
#define addr_rx_kd_ch0_ddc_bw 0x4248       //"带宽"
#define addr_rx_kd_ch0_ddc_cf_h16 0x424c   //"中心频率 高16"
#define addr_rx_kd_ch0_ddc_cf_l32 0x4250   //"中心频率 低32"
#define addr_rx_kd_ch0_ddc_df 0x4268       //"采样因子/抽取率因子"
#define addr_rx_kd_ch0_kz_sw 0x4230        // 快照开关
#define addr_rx_kd_ch0_kz_pack_size 0x4234 // 快照包大小
#define addr_rx_kd_ch1_ddc_sf 0x4254       //"采样率"
#define addr_rx_kd_ch1_ddc_bw 0x4258       //"带宽"
#define addr_rx_kd_ch1_ddc_cf_h16 0x425c   //"中心频率 高16"
#define addr_rx_kd_ch1_ddc_cf_l32 0x4260   //"中心频率 低32"
#define addr_rx_kd_ch1_ddc_df 0x426c       //"采样因子/抽取率因子"
#define addr_rx_kd_ch1_kz_sw 0x4238        // 快照开关
#define addr_rx_kd_ch1_kz_pack_size 0x423c // 快照包大小
#define addr_rx_zd_ch 0x4280               // 窄带通道号
#define addr_rx_zd_ddc_data_sw 0x4284      // 窄带数据开关
#define addr_rx_zd_df 0x4288               // 窄带抽取倍数
#define addr_rx_zd_bw 0x428c               // 窄带带宽
#define addr_rx_zd_cw 0x4290               // 窄带控制字
#define addr_rx_zd_fc 0x4294               // 窄带过滤系数
#define addr_rx_zd_sf 0x4298               // 窄带采样率
#define addr_tx_send_data_cw 0x42c0        // 发送总开关
#define addr_tx_send_ch_sw 0x42c4          // 发送通道选择
#define addr_tx_ch0_insert_rate 0x42c8     // 插值率
#define addr_tx_ch1_insert_rate 0x42cc     // 插值率
#define addr_tx_ch0_30MHz_cw 0x42d0        // 发送30Mhz 控制字
#define addr_tx_ch1_30MHz_cw 0x42d4        // 发送30Mhz 控制字
#define addr_tm_set_h 0x42e0               // 计时高位
#define addr_tm_set_l 0x42e4               // 计时低位
//-----------------------------------------------------------------------------------------
#define my_iio_rx_block_point_size_big (2112 * 512) // #define my_iio_block_point_size (2112*4)
#define my_iio_block_point_size_little (2112 * 512)
#define my_iio_tx_block_point_size (2112 * 512)
#define ach_sf_count_max_hz (15.36 * 1000 * 1000)
#define rx_kz_speed_hz (1.62 * 1000 * 1000)
// #define rx_net_speed_max (500*1024*1024)
#define ZDExtraMin 0  // 窄带抽取倍数的序号，最小
#define ZDExtraMax 12 // 窄带抽取倍数的序号，最大
#define kz_sum ((double)(491520000 / 2))
#define GHz (1000 * 1000 * 1000.0)
#define MHz (1000 * 1000.0)

static unsigned long long kd_sf_all = 0;
static unsigned long long sf_all = 0;
static unsigned long long tmp_block_size = 0;
static unsigned long long tmp_sf_all = 0;
typedef struct ThreadRecvParam
{
    int channel;
    void *pThis;
} ThreadRecvParam;
void addr_val_mix(int64_t addr, int64_t val, std::string &sstr)
{
    sstr.clear();
    char str[50];
    for (int i = 0; i < 50; ++i)
    {
        str[i] = 0;
    }
    sprintf(str, "%08x%08x", (unsigned int)addr, (unsigned int)val);
    sstr = str;
}
bool set_esun_rx_addr_val(iio_context *ctx, int64_t addr, int64_t val)
{
    if (ctx)
    {
        struct iio_device *phy;
        struct iio_channel *chan;
        phy = iio_context_find_device(ctx, "adrv9002-phy");
        chan = iio_device_find_channel(phy, "voltage0", false);

        // cout <<" addr = 0x"<<std::hex<<addr<<"val = "<<std::dec<<val<<endl;
        std::string str;
        addr_val_mix(addr, val, str);
        char vl[20];
        for (int i = 0; i < 20; ++i)
        {
            vl[i] = 0;
        }
        strcpy(vl, str.c_str());
        iio_channel_attr_write(chan, "esun_reg", vl);
        return true;
    }
    return false;
}
bool get_esun_rx_addr_val(iio_context *ctx, int64_t addr, int64_t &val)
{
    if (ctx)
    {
        struct iio_device *phy;
        struct iio_channel *chan;
        phy = iio_context_find_device(ctx, "adrv9002-phy");
        chan = iio_device_find_channel(phy, "voltage0", false);
        char str[20];
        memset(str, 0, 20);
        sprintf(str, "%x", addr);
        iio_channel_attr_write(chan, "esun_reg", str);
        iio_channel_attr_read(chan, "esun_reg", str, 20);
        val = atoi(str);
        return true;
    }
    return false;
}
static int stream_channels_get_enable(const struct iio_device *dev, struct iio_channel **chan, bool tx)
{
    int c;
    const char *const channels[] = {"voltage0_i", "voltage0_q", "voltage0", "voltage1"};
    for (c = 0; c < 2; c++)
    {
        const char *str = channels[tx * 2 + c];
        chan[c] = iio_device_find_channel(dev, str, tx);
        if (!chan[c])
        {
            return -ENODEV;
        }
        if (!iio_channel_is_enabled(chan[c]))
        {
            iio_channel_enable(chan[c]);
        }
    }
    return 0;
}
static int stream_channels_get_disenable(const struct iio_device *dev, struct iio_channel **chan, bool tx)
{
    int c;
    const char *const channels[] = {"voltage0_i", "voltage0_q", "voltage0", "voltage1"};
    for (c = 0; c < 2; c++)
    {
        const char *str = channels[tx * 2 + c];
        chan[c] = iio_device_find_channel(dev, str, tx);
        if (!chan[c])
        {
            return -ENODEV;
        }
        if (iio_channel_is_enabled(chan[c]))
        {
            iio_channel_disable(chan[c]);
        }
    }
    return 0;
}
uhd::device_addrs_t Device_UHD::findDevices()
{
    device_addrs_t dev_list;
    dev_list.clear();
    device_addr_t t;
    t.uri = "ip:172.22.0.2";
    this->bFindedDevice = true;
    dev_list.push_back(t);
    p_usrp.ctx_isopen = false;
    return dev_list;
}
bool Device_UHD::openDevice(uhd::device_addr_t addr)
{
    bool bRet = false;
    if (this->bFindedDevice)
    {
        try
        {
            this->devAddr = addr;
            uhd::usrp::multi_usrp::sptr tmp_URSP;
            tmp_URSP.ctx = iio_create_context_from_uri("ip:172.22.0.2");
            // tmp_URSP.ctx = iio_create_context_from_uri("ip:192.168.1.141");
            if (tmp_URSP.ctx != NULL)
            {
                p_usrp = tmp_URSP;
                p_usrp.ctx_isopen = true;
                bRet = true;
                spThread_Recv[0] = NULL;
                spThread_Recv[1] = NULL;
                // memset(&rxKDParam, 0, sizeof(rxKDParam));
                for (int i = 0; i < 2; i++)
                {
                    rxKDParam[i].KCH = i;
                    rxKDParam[i].CenterFreq = 0;
                    rxKDParam[i].BandWidth = 0;  /*getDevParam("RX" + i, UHD_ParamType::BandWidth);*/
                    rxKDParam[i].SampleFreq = 0; /* getDevParam("RX" + i, UHD_ParamType::SampleFreq);*/
                    for (int y = 0; y < ZDChMax; y++)
                    {
                        rxKDParam[i].ZDParam[y].KCH = i;
                        rxKDParam[i].ZDParam[y].ZCH = i * ZDChMax + y;
                    }
                    rxKDParam[i].gain = 0;
                    rxKDParam[i].Snapshot_Switch = false;
                    rxKDParam[i].Snapshot_tm_s = 0;
                    txKDParam[i].gain = -40;
                    led_val = 0;
                }
                kd_centerfreq_sw = 0;
                fftWin = UHD_FFTWin::blkmc;
                fftLen = UHD_FFTLen::_32768;
                fftPeriod = 10;
            }
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
            p_usrp.ctx_isopen = false;
            bRet = false;
        }
    }
    return bRet;
}
void Device_UHD::closeDevice()
{
    if (p_usrp.ctx != NULL)
    {
        stopDevRecv(0);
        stopDevRecv(1);
        stopDevSend(0);
        stopDevSend(1);
        // 释放前，需把所有引用都赋值NULL，方可释放
        // pTree = NULL; //
        iio_context_destroy(p_usrp.ctx);
        p_usrp.ctx = NULL; // 内部会自动释放指针
        p_usrp.ctx_isopen = false;
    }
}
bool Device_UHD::isDevOpened() const
{
    bool ret = p_usrp.ctx_isopen;
    return ret;
}
string GetUHDTree(const uhd::fs_path &path, uhd::property_tree::sptr tree)
{
    return "GetUHDTree\r\n";
}
string Device_UHD::getDevTree()
{
    return "getDevTree\r\n";
}
string Device_UHD::findDevInfos()
{
    string ret;
    char tmp[200];
    if (p_usrp.ctx != NULL)
    {
        try
        {
            { // 查询设备信息
                ret += "ip:172.22.0.2\r\n";
            }
            { // 查看设备数量、名称、时钟源
                snprintf(tmp, 200, "get_num_mboards:%d", 0);
                ret += string(tmp) + "\r\n";
                ret += "\r\n";
            }
            {
            }
            { // 查询接收通道参数
                // int num = (int)pUSRP->get_rx_num_channels();
                snprintf(tmp, 200, "get_rx_num_channels:%d", 2);
                ret += string(tmp) + "\r\n";
                for (int i = 0; i < 2; i++)
                {
                }
                ret += "\r\n";
            }
            { // 查询发射通道参数
                snprintf(tmp, 200, "get_tx_num_channels:%d", 2);
                ret += string(tmp) + "\r\n";
                for (int i = 0; i < 2; i++)
                {
                    { // 查询发射频率范围
                        snprintf(tmp, 200, "get_tx_freq_range(%d):%f~%f", i, 0, 6 * GHz);
                        ret += string(tmp) + "\r\n";
                    }
                }
                ret += "\r\n";
            }
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return "findDevInfos\r\n";
}
string Device_UHD::findDevInfos2()
{
    return "ok";
}
size_t Device_UHD::getDevRXChCount()
{
    size_t bRet = 0;
    try
    {
        if (p_usrp.ctx != NULL)
        {
            bRet = 2;
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
    return bRet;
}
size_t Device_UHD::getDevTXChCount()
{
    size_t bRet = 0;
    try
    {
        if (p_usrp.ctx != NULL)
        {
            bRet = 2;
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
    return bRet;
}
bool Device_UHD::setDevClockSource(string sourceStr)
{
    std::cout << sourceStr << std::endl;
    bool ret = true;
    try
    {
        if (p_usrp.ctx != NULL)
        {
            if (sourceStr.compare("gpsdo") == 0)
            {
                set_esun_rx_addr_val(p_usrp.ctx, addr_dev_ref_time, 5);
            }
            else if (sourceStr.compare("external") == 0)
            {
                set_esun_rx_addr_val(p_usrp.ctx, addr_dev_ref_time, 10);
            }
            else if (sourceStr.compare("internal") == 0)
            {
                set_esun_rx_addr_val(p_usrp.ctx, addr_dev_ref_time, 9);
            }
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
        ret = false;
    }
    return ret;
}
string Device_UHD::getDevClockSource()
{
    string ret = "internal";
    try
    {
        if (p_usrp.ctx != NULL)
        {
            int64_t val;
            get_esun_rx_addr_val(p_usrp.ctx, (int64_t)addr_dev_ref_time, val);
            if (val == 5)
            {
                ret = string("gpsdo");
            }
            else if (val == 9)
            {
                ret = string("internal");
            }
            else if (val == 10)
            {
                ret = string("external");
            }
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
    return ret;
}
bool Device_UHD::setDevInClock(double clockFreq)
{
    bool ret = true;
    return ret;
}
void Device_UHD::getDevInClockRange()
{
    try
    {
        if (p_usrp.ctx != NULL)
        {
            fParamMin = 10000000;
            fParamMax = 10000000;
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
}
double Device_UHD::getDevInClock()
{
    double ret = 0;
    try
    {
        if (p_usrp.ctx != NULL)
        {
            ret = 10000000;
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
    return ret;
}
bool Device_UHD::setDevParam(string chStr, UHD_ParamType paramType, double paramValue)
{
    cout << "chstr" << chStr << " paramType:" << (int)paramType << " paramValue" << paramValue << endl;
    bool ret = true;
    try
    {
        if (p_usrp.ctx != NULL)
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            bool bTX = chStr.find("TX") != string::npos;
            bool tmp_zd_switch = 0;

            //"频点", "带宽", "采样率", "增益", "校准电平"

            if (!bTX)
            {
                for (int i = 0; i < 8; ++i)
                {
                    tmp_zd_switch += rxKDParam[channel].ZDParam[i].bSwitch_ZDDC;
                }
                switch (paramType)
                {
                case UHD_ParamType::CenterFreq:
                    // if (tmp_zd_switch)
                    // {
                    //     return false;
                    // }
                    if (!bTX)
                    {
                        rxKDParam[channel].old_cf = rxKDParam[channel].CenterFreq;
                        rxKDParam[channel].CenterFreq = paramValue;
                        if (rxKDParam[channel].old_cf == 0)
                        {
                            rxKDParam[channel].old_cf = rxKDParam[channel].CenterFreq;
                        }
                    }
                    break;
                case UHD_ParamType::BandWidth:
                    // if (tmp_zd_switch)
                    // {
                    //     return false;
                    // }
                    if (!bTX)
                    {
                        rxKDParam[channel].old_bw = rxKDParam[channel].BandWidth;
                        rxKDParam[channel].BandWidth = paramValue;
                        if (rxKDParam[channel].old_bw == 0)
                        {
                            rxKDParam[channel].old_bw = rxKDParam[channel].BandWidth;
                        }
                    }
                    break;
                case UHD_ParamType::SampleFreq:
                    // if (tmp_zd_switch)
                    // {
                    //     return false;
                    // }
                    if (!bTX)
                    {
                        if (rxKDParam[channel].bSwitch_KDDC == true)
                        {
                            unsigned long long sfcnt = 0;
                            for (int j = 0; j < 2; ++j)
                            {
                                sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                                sfcnt += rxKDParam[j].bSwitch_KFFT * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                                sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                                for (int i = 0; i < 8; ++i)
                                {
                                    sfcnt += rxKDParam[j].ZDParam[i].SampleFreq * rxKDParam[j].ZDParam[i].bSwitch_ZDDC;
                                }
                            }
                            unsigned long long pre_cnt = sfcnt - rxKDParam[channel].SampleFreq + paramValue;
                            if (pre_cnt > ach_sf_count_max_hz + 1)
                            {
                                return false;
                            }
                            sf_all = pre_cnt;
                        }
                        rxKDParam[channel].old_sf = rxKDParam[channel].SampleFreq;
                        rxKDParam[channel].SampleFreq = paramValue;
                        if (rxKDParam[channel].old_sf == 0)
                        {
                            rxKDParam[channel].old_sf = rxKDParam[channel].SampleFreq;
                        }
                    }
                    break;
                case UHD_ParamType::Gain:
                    if (!bTX)
                    {

                        struct iio_device *phy;
                        struct iio_channel *chn = nullptr;
                        phy = iio_context_find_device(this->p_usrp.ctx, "adrv9002-phy");
                        if (channel == 0)
                        {
                            chn = iio_device_find_channel(phy, "voltage0", false);
                        }
                        else if (channel == 1)
                        {
                            chn = iio_device_find_channel(phy, "voltage1", false);
                        }
                        int retno = iio_channel_attr_write_double(chn, "hardwaregain", paramValue);
                        if (retno != 0)
                        {
                            ret = false;
                        }
                        else
                        {
                            ret = true;
                            rxKDParam[channel].gain = paramValue;
                        }
                    }
                    return false;
                    break;
                case UHD_ParamType::PowerRef:
                    break;
                case UHD_ParamType::SnapshotSwitch:
                    if (!bTX)
                    {
                        bool bSwitch = (bool)paramValue;
                        if (bSwitch == true && rxKDParam[channel].Snapshot_Switch == false)
                        {
                            unsigned long long sfcnt = 0;
                            for (int j = 0; j < 2; ++j)
                            {
                                sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                                sfcnt += rxKDParam[j].bSwitch_KFFT * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                                sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                                for (int i = 0; i < 8; ++i)
                                {
                                    sfcnt += rxKDParam[j].ZDParam[i].SampleFreq * rxKDParam[j].ZDParam[i].bSwitch_ZDDC;
                                }
                            }
                            unsigned long long pre_cnt = sfcnt + rx_kz_speed_hz;
                            if (pre_cnt > ach_sf_count_max_hz + 1)
                            {
                                return false;
                            }
                            sf_all = pre_cnt;
                        }
                        rxKDParam[channel].Snapshot_Switch = (bool)paramValue;
                        // 设置获取本来的宽带 通道开关 并置为0;
                        unsigned char uSwitch = 0;
                        if (bSwitch == true)
                        {
                            rxKDParam[channel].bSwitch_KDDC = false;
                            for (int i = 0; i < 2; i++)
                            {
                                if (rxKDParam[i].bSwitch_KDDC)
                                {
                                    uSwitch |= 0x01 << i;
                                }
                            }
                            set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_data_sw, 0);
                            set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_data_sw, uSwitch);
                        }
                        set_esun_rx_addr_val(p_usrp.ctx, channel == 0 ? addr_rx_kd_ch0_kz_sw : addr_rx_kd_ch1_kz_sw, 0);
                        set_esun_rx_addr_val(p_usrp.ctx, channel == 0 ? addr_rx_kd_ch0_kz_sw : addr_rx_kd_ch1_kz_sw, rxKDParam[channel].Snapshot_Switch);
                        return true;
                    }
                    return false;
                    break;
                case UHD_ParamType::Snapshot_tm_s: {
                    if (!bTX)
                    {
                        if (rxKDParam[channel].SampleFreq < 0)
                        {
                            return false;
                        }
                        int tmp_t_max = (int)(kz_sum / rxKDParam[channel].SampleFreq);
                        if (paramValue > tmp_t_max || paramValue < 0)
                        {
                            // paramValue = tmp_t_max;
                            rxKDParam[channel].Snapshot_tm_s = tmp_t_max;
                        }
                        else
                        {
                            rxKDParam[channel].Snapshot_tm_s = paramValue;
                        }
                    }
                }
                break;
                defualt:
                    break;
                }

                int kd_cur_indx = channel;
                double kddcsamp = rxKDParam[channel].SampleFreq;
                int ExtraPer = 0;
                unsigned long long CenterFreq = rxKDParam[channel].CenterFreq;
                long long BandWidth = rxKDParam[channel].BandWidth;
                unsigned long long kd_centerfreq_h16 = CenterFreq & 0xffff00000000;
                unsigned long long kd_centerfreq_l32 = CenterFreq & 0xffffffff;
                int t = rxKDParam[channel].Snapshot_tm_s;
                unsigned long long pack_size = ((unsigned int)((t * rxKDParam[channel].SampleFreq * 32.0) / (2048 * 8.0) / 16)) * 16;
                set_esun_rx_addr_val(p_usrp.ctx, channel == 0 ? addr_rx_kd_ch0_kz_pack_size : addr_rx_kd_ch1_kz_pack_size, pack_size);
                bool enable_6G_ch = 0;
                if (CenterFreq >= 30 * MHz && CenterFreq < 6 * GHz)
                {
                    enable_6G_ch = 1;
                }
                else if (CenterFreq < 30 * MHz && CenterFreq >= 0)
                {
                    enable_6G_ch = 0;
                }
                if (channel == 0)
                {
                    if (enable_6G_ch == 1)
                        kd_centerfreq_sw |= 0x01;
                    if (enable_6G_ch == 0)
                        kd_centerfreq_sw &= 0x02;
                }
                if (channel == 1)
                {
                    if (enable_6G_ch == 1)
                        kd_centerfreq_sw |= 0x02;
                    if (enable_6G_ch == 0)
                        kd_centerfreq_sw &= 0x01;
                }
                //  bool bSwitch = false;
                //  int kd_ddc_up = 0;
                int kd_FilterCoef[128] = {0};
                for (int i = KDDCSampIndxMin0; i <= KDDCSampIndxMax0; i++)
                {
                    double tmpssssf = (channel == 0 ?KDDCSampTab0[i][0]:KDDCSampTab1[i][0]);
                    if ( tmpssssf== kddcsamp)
                    {
                        ExtraPer = i;
                        break;
                    }
                }
                if (CenterFreq < 30 * MHz)
                {
                    int kd_30M_ctrword = (int)((double)(CenterFreq - 15000000.0) / (channel == 0 ? define_KDDCSampleMax0 : define_KDDCSampleMax1) * pow(2, 32));
                    if (kd_cur_indx == 0)
                    {
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_ch0_30Mhz_cw, kd_30M_ctrword);
                    }
                    if (kd_cur_indx == 1)
                    {
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_ch1_30MHz_cw, kd_30M_ctrword);
                    }
                }
                int kd_filterLen = SetFIRLpCoef2(kd_FilterCoef, 128, (double)BandWidth / kddcsamp, 18, 1.0);
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_ch_sw, kd_centerfreq_sw);
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_ch, kd_cur_indx);

                // if(rxKDParam[channel].old_bw != BandWidth || rxKDParam[channel].old_sf != kddcsamp)
                // {
                //     if (kd_filterLen > 0)
                //     {
                //         for (int i = 0; i < kd_filterLen; i++)
                //         {
                //             set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_fc, kd_FilterCoef[i]);
                //         }
                //     }
                // }
                if (!(rxKDParam[channel].old_cf != CenterFreq && rxKDParam[channel].old_bw == BandWidth && rxKDParam[channel].old_sf == kddcsamp))
                {
                    if (kd_filterLen > 0)
                    {
                        for (int i = 0; i < kd_filterLen; i++)
                        {
                            set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_fc, kd_FilterCoef[i]);
                        }
                    }
                }
                if (kd_cur_indx == 0)
                {
                    struct iio_channel *chn = nullptr;
                    struct iio_device *phy;
                    phy = iio_context_find_device(p_usrp.ctx, "adrv9002-phy");
                    chn = iio_device_find_channel(phy, "altvoltage0", true);
                    bool b1 = (CenterFreq >= (30 * MHz));
                    bool b2 = (CenterFreq < (6 * GHz));
                    if (b1 && b2)
                    {
                        iio_channel_attr_write_longlong(chn, "RX1_LO_frequency", CenterFreq);
                    }
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch0_ddc_df, ExtraPer);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch0_ddc_bw, BandWidth);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch0_ddc_sf, kddcsamp);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch0_ddc_cf_h16, kd_centerfreq_h16);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch0_ddc_cf_l32, kd_centerfreq_l32);
                }
                else if (kd_cur_indx == 1)
                {
                    struct iio_channel *chn = nullptr;
                    struct iio_device *phy;
                    phy = iio_context_find_device(p_usrp.ctx, "adrv9002-phy");
                    chn = iio_device_find_channel(phy, "altvoltage1", true);
                    if (CenterFreq >= 30 * MHz && CenterFreq < 6 * GHz)
                    {
                        iio_channel_attr_write_longlong(chn, "RX2_LO_frequency", CenterFreq);
                    }
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch1_ddc_df, ExtraPer);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch1_ddc_bw, BandWidth);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch1_ddc_sf, kddcsamp);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch1_ddc_cf_h16, kd_centerfreq_h16);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ch1_ddc_cf_l32, kd_centerfreq_l32);
                }

                struct iio_device *phy;
                struct iio_channel *chn = nullptr;
                phy = iio_context_find_device(this->p_usrp.ctx, "adrv9002-phy");
                if (channel == 0)
                {
                    chn = iio_device_find_channel(phy, "voltage0", false);
                }
                else if (channel == 1)
                {
                    chn = iio_device_find_channel(phy, "voltage1", false);
                }
                // int retno = iio_channel_attr_write_double(chn, "hardwaregain", this->rxKDParam[channel].gain);
                // if (retno!=0)
                // {
                //     ret = false;
                // }
                // else{
                //     ret = true;
                //     rxKDParam[channel].gain = paramValue;
                // }
            }

            if (bTX)
            {
                if (paramType == UHD_ParamType::Gain)
                {

                    struct iio_device *phy;
                    struct iio_channel *chn = nullptr;
                    phy = iio_context_find_device(this->p_usrp.ctx, "adrv9002-phy");
                    if (channel == 0)
                    {
                        chn = iio_device_find_channel(phy, "voltage0", true);
                    }
                    else if (channel == 1)
                    {
                        chn = iio_device_find_channel(phy, "voltage1", true);
                    }
                    int retno = iio_channel_attr_write_double(chn, "hardwaregain", paramValue);
                    if (retno != 0)
                    {
                        ret = false;
                    }
                    else
                    {
                        ret = true;
                        txKDParam[channel].gain = paramValue;
                    }
                }
            }
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
        ret = false;
    }
    return ret;
}
double Device_UHD::getDevParam(string chStr, UHD_ParamType paramType)
{
    double ret;
    try
    {
        if (p_usrp.ctx != NULL)
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            bool bTX = chStr.find("TX") != string::npos;
            //"频点", "带宽", "采样率", "增益", "校准电平"
            if (!bTX)
            {
                switch (paramType)
                {
                case UHD_ParamType::CenterFreq:
                    // ret = bTX ? p_usrp->get_tx_freq(channel) : pUSRP->get_rx_freq(channel);
                    if (!bTX)
                    {
                        ret = rxKDParam[channel].CenterFreq; //= ret;
                    }
                    break;
                case UHD_ParamType::BandWidth:
                    if (!bTX)
                    {
                        ret = rxKDParam[channel].BandWidth; //= ret;
                    }
                    break;
                case UHD_ParamType::SampleFreq:
                    if (!bTX)
                    {
                        ret = rxKDParam[channel].SampleFreq; // = ret;
                    }
                    break;
                case UHD_ParamType::Gain:
                    ret = rxKDParam[channel].gain;
                    break;
                case UHD_ParamType::PowerRef:
                    ret = 10000000;
                    break;
                case UHD_ParamType::SnapshotSwitch:
                    ret = rxKDParam[channel].Snapshot_Switch;
                    break;
                case UHD_ParamType::Snapshot_tm_s:
                    ret = rxKDParam[channel].Snapshot_tm_s;
                }
            }
            if (bTX)
            {
                if (paramType == UHD_ParamType::Gain)
                {
                    ret = txKDParam[channel].gain;
                }
            }
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
    return ret;
}
bool Device_UHD::setAllAntenna()
{
    bool ret = true;
    return ret;
}
void Device_UHD::getDevParamRange(string chStr, UHD_ParamType paramType, double &paramMin, double &paramMax)
{
    try
    {
        if (p_usrp.ctx != NULL)
        {
            // uhd::meta_range_t range;
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            bool bTX = chStr.find("TX") != string::npos;
            //"频点", "带宽", "采样率", "增益", "校准电平"
            switch (paramType)
            {
            case UHD_ParamType::CenterFreq:
                fParamMin = 0;
                fParamMax = 6 * GHz;
                break;
            case UHD_ParamType::BandWidth:
                fParamMin = 0;
                fParamMax = 40000000;
                break;
            case UHD_ParamType::SampleFreq:
                fParamMin = 0;
                fParamMax = (channel==0?define_KDDCSampleMax0:define_KDDCSampleMax1);
                break;
            case UHD_ParamType::Gain:
                if (!bTX)
                {
                    fParamMin = 0;
                    fParamMax = 34;
                }
                break;
            case UHD_ParamType::PowerRef:
                fParamMin = 0;
                fParamMax = 0;
                break;
            }
        }
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
}
double Device_UHD::getDevParamMin() const
{
    return fParamMin;
}
double Device_UHD::getDevParamMax() const
{
    return fParamMax;
}
bool Device_UHD::setDevDDCParam_Any(string chStr, unsigned int jcqOffset, unsigned int jcqData)
{
    bool ret = true;
    if (p_usrp.ctx != NULL)
    {
        try
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            set_esun_rx_addr_val(p_usrp.ctx, jcqOffset, jcqData);
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return ret;
}
bool Device_UHD::getDevDDCParam_Any(string chStr, unsigned int jcqOffset, unsigned int &jcqData)
{
    bool ret = true;
    if (p_usrp.ctx != NULL)
    {
        int64_t va;
        try
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            get_esun_rx_addr_val(p_usrp.ctx, jcqOffset, va);
            jcqData = va;
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return ret;
}
bool Device_UHD::setDevDataSwitch(string chStr, UHD_ParamType dataType, unsigned char ZDCh, bool bSwitch)
{
    cout << "chstr:" << chStr << " dataType:" << (int)dataType << " ZDCh:" << ZDCh << " bSwitch:" << bSwitch << endl;
    int xx = bSwitch == true ? 1 : -1;
    bool ret = true;
    if (p_usrp.ctx != NULL)
    {
        try
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            switch (dataType)
            {
            case KDDCSwitch: {
                if (bSwitch != rxKDParam[channel].bSwitch_KDDC)
                {
                    unsigned long long sfcnt = 0;
                    for (int j = 0; j < 2; ++j)
                    {
                        sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                        sfcnt += rxKDParam[j].bSwitch_KFFT * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                        sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                        for (int i = 0; i < 8; ++i)
                        {
                            sfcnt += rxKDParam[j].ZDParam[i].SampleFreq * rxKDParam[j].ZDParam[i].bSwitch_ZDDC;
                        }
                    }
                    unsigned long long pre_cnt = sfcnt + (xx * rxKDParam[channel].SampleFreq);
                    // if (pre_cnt > ach_sf_count_max_hz + 1)
                    // {
                    //     cout <<" error pre_cnt"<<pre_cnt<<endl;
                    //     return false;
                    // }
                    sf_all = pre_cnt;
                }
                // close zk
                if (bSwitch == true)
                {
                    rxKDParam[channel].Snapshot_Switch = false;
                    // set_esun_rx_addr_val(p_usrp.ctx, channel == 0 ? addr_rx_kd_ch0_kz_sw : addr_rx_kd_ch1_kz_sw, 0);
                    set_esun_rx_addr_val(p_usrp.ctx, channel == 0 ? addr_rx_kd_ch0_kz_sw : addr_rx_kd_ch1_kz_sw, false);
                    // rx_kd_ddc_sw |= (1 << channel);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_data_sw, 3);
                }
                else
                {
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ch, ZDCh);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ddc_data_sw, 0);
                    // rx_kd_ddc_sw &= ~(1 << channel);

                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_data_sw, 0);
                }
                // get old kdsw
                unsigned char uSwitch = 0;
                for (int i = 0; i < 2; i++)
                {
                    if (rxKDParam[i].bSwitch_KDDC)
                    {
                        uSwitch |= (0x01 << i);
                    }
                }
                // set kdsw
                if (bSwitch)
                {
                    uSwitch |= (1 << channel);
                }
                else
                {
                    uSwitch &= ~(1 << channel);
                }
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_data_sw, 0);
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_ddc_data_sw, 0);
                rxKDParam[channel].bSwitch_KDDC = bSwitch;
            }
            break;
            case KFFTSwitch: {
                if (bSwitch != rxKDParam[channel].bSwitch_KFFT)
                {
                    unsigned long long sfcnt = 0;
                    for (int j = 0; j < 2; ++j)
                    {
                        sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                        double t_fftlen = (double)fftLen;
                        sfcnt += rxKDParam[j].bSwitch_KFFT * (t_fftlen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                        sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                        for (int i = 0; i < 8; ++i)
                        {
                            sfcnt += rxKDParam[j].ZDParam[i].SampleFreq * rxKDParam[j].ZDParam[i].bSwitch_ZDDC;
                        }
                    }
                    unsigned long long pre_cnt = sfcnt + xx * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                    if (pre_cnt > ach_sf_count_max_hz + 1)
                    {
                        return false;
                    }
                    sf_all = pre_cnt;
                }
                unsigned char uSwitch = 0;
                for (int i = 0; i < 2; i++)
                {
                    if (rxKDParam[i].bSwitch_KFFT)
                    {
                        uSwitch |= 0x01 << i;
                    }
                }
                if (bSwitch)
                {
                    uSwitch |= (1 << channel);
                }
                else
                {
                    uSwitch &= ~(1 << channel);
                }
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_fft_sw, 0);
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_fft_sw, uSwitch);
                rxKDParam[channel].bSwitch_KFFT = bSwitch;
            }
            break;
            case ZDDCSwitch: {
                if (bSwitch != rxKDParam[channel].ZDParam[ZDCh % ZDChMax].bSwitch_ZDDC)
                {
                    unsigned long long sfcnt = 0;
                    for (int j = 0; j < 2; ++j)
                    {
                        sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                        sfcnt += rxKDParam[j].bSwitch_KFFT * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                        sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                        for (int i = 0; i < 8; ++i)
                        {
                            sfcnt += rxKDParam[j].ZDParam[i].SampleFreq * rxKDParam[j].ZDParam[i].bSwitch_ZDDC;
                        }
                    }
                    unsigned long long pre_cnt = sfcnt + xx * rxKDParam[channel].ZDParam[ZDCh % ZDChMax].SampleFreq;
                    // if (pre_cnt > ach_sf_count_max_hz + 1)
                    // {
                    //     return false;
                    // }
                    sf_all = pre_cnt;
                }
                if (ZDCh >= 0 && ZDCh <= ZDChMax * 2)
                {
                    rxKDParam[channel].ZDParam[ZDCh % ZDChMax].bSwitch_ZDDC = bSwitch;
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ch, ZDCh);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ddc_data_sw, 0);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ch, ZDCh);
                    set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ddc_data_sw, bSwitch);
                }
                else
                    ret = false;
            }
            break;
            default:
                ret = false;
                break;
            }
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return ret;
}
bool Device_UHD::getDevDataSwitch(string chStr, UHD_ParamType dataType, unsigned char ZDCh, bool &bSwitch)
{
    bool ret = true;
    if (p_usrp.ctx != NULL)
    {
        try
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            switch (dataType)
            {
            case KDDCSwitch: {
                bSwitch = rxKDParam[channel].bSwitch_KDDC;
            }
            break;
            case KFFTSwitch: {
                bSwitch = rxKDParam[channel].bSwitch_KFFT;
            }
            break;
            case ZDDCSwitch: {
                if (ZDCh >= 0 && ZDCh <= ZDChMax * 2)
                {
                    bSwitch = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].bSwitch_ZDDC;
                }
            }
            break;
            default:
                break;
            }
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return ret;
}
bool Device_UHD::setDevFFTParam(UHD_FFTWin fftWin, UHD_FFTLen fftLen, int fftPeriod_ms)
{
    double curfftlen = (double)fftLen;
    bool ret = false;
    if (p_usrp.ctx != NULL)
    {
        try
        {
            {
                unsigned long long d_fft_old = 0;
                unsigned long long d_fft_new = 0;
                unsigned long long sfcnt = 0;
                for (int j = 0; j < 2; ++j)
                {
                    double t_fft_len = (double)this->fftLen;
                    sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                    d_fft_old += rxKDParam[j].bSwitch_KFFT * ((double)this->fftLen / 1024 * 2112 * (1000 / (double)this->fftPeriod) / 4);
                    d_fft_new += rxKDParam[j].bSwitch_KFFT * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod_ms) / 4);
                    sfcnt += d_fft_old;
                    sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                    for (int i = 0; i < 8; ++i)
                    {
                        sfcnt += rxKDParam[j].ZDParam[j].SampleFreq * rxKDParam[j].ZDParam[j].bSwitch_ZDDC;
                    }
                }
                unsigned long long pre_cnt = sfcnt - d_fft_old + d_fft_new;
                if (pre_cnt > ach_sf_count_max_hz + 1)
                {
                    return -3;
                }
                sf_all = pre_cnt;
            }
            if (fftPeriod_ms >= 1 && fftPeriod_ms <= 1000)
            {
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_fft_type, fftWin);
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_fft_len, fftLen);
                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_kd_fft_preiod, fftPeriod_ms);
                this->fftWin = fftWin;
                this->fftLen = fftLen;
                this->fftPeriod = fftPeriod_ms;
                ret = true;
            }
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return ret;
}
bool Device_UHD::getDevFFTParam(UHD_FFTWin &fftWin, UHD_FFTLen &fftLen, int &fftPeriod_ms)
{
    bool ret = true;
    if (p_usrp.ctx != NULL)
    {
        fftWin = this->fftWin;
        fftLen = this->fftLen;
        fftPeriod_ms = this->fftPeriod;
    }
    return ret;
}
bool Device_UHD::setLedEnable(int led_num, bool bEnable)
{
    int mv_size = 0;
    if (led_num == 0)
    {
        mv_size = 1;
    }
    if (led_num == 1)
    {
        mv_size = 4;
    }
    if (led_num == 2)
    {
        mv_size = 3;
    }
    if (led_num == 3)
    {
        mv_size = 2;
    }
    if (led_num == 4)
    {
        mv_size = 0;
    }
    if (led_num == 5)
    {
        mv_size = 5;
    }
    if (p_usrp.ctx != NULL)
    {
        if (bEnable)
        {
            this->led_val = led_val | (1 << mv_size);
        }
        else
        {
            this->led_val &= ~(1 << mv_size);
        }
        set_esun_rx_addr_val(p_usrp.ctx, addr_dev_led, led_val);
        return true;
    }
    return false;
}
bool Device_UHD::getLedEnable(int led_num, bool &bEnable)
{
    if (p_usrp.ctx != NULL)
    {
        int mv_size = 0;
        if (led_num == 0)
        {
            mv_size = 1;
        }
        if (led_num == 1)
        {
            mv_size = 4;
        }
        if (led_num == 2)
        {
            mv_size = 3;
        }
        if (led_num == 3)
        {
            mv_size = 2;
        }
        if (led_num == 4)
        {
            mv_size = 0;
        }
        if (led_num == 5)
        {
            mv_size = 5;
        }
        int enable_val = led_val >> mv_size & 0x01;
        bEnable = enable_val;
        return true;
    }
    return false;
}
int Device_UHD::setDevZDParam(string chStr, unsigned char ZDCh, long long centerfreq, int bw, int sample)
{
    int ret = 0;
    if (p_usrp.ctx != NULL)
    {
        try
        {
            int channel = chStr.find("0") != string::npos ? 0 : 1;
            if (sample == 0)
            {
                rxKDParam[channel].ZDParam[ZDCh % ZDChMax].CenterFreq = 0;
                rxKDParam[channel].ZDParam[ZDCh % ZDChMax].BandWidth = 0;
                rxKDParam[channel].ZDParam[ZDCh % ZDChMax].SampleFreq = 0;
            }
            else
            {
                int kddcSam = rxKDParam[channel].SampleFreq;
                long long kddcCenter = rxKDParam[channel].CenterFreq;
                int kddcBW = rxKDParam[channel].BandWidth;
                int samIndex = ZDExtraMin;
                for (int i = ZDExtraMin; i <= ZDExtraMax; i++)
                {
                    if ((int)(kddcSam / pow(2, i + 0)) == sample)
                    {
                        samIndex = i;
                        break;
                    }
                }
                int samSum = 0;
                for (auto zd : rxKDParam[channel].ZDParam)
                {
                    samSum += zd.ZCH != ZDCh ? zd.SampleFreq : 0;
                }
                if (samIndex < ZDExtraMin || samSum + sample > ZDSamSum)
                {
                    ret = -3;
                }
                if (centerfreq < 0 || centerfreq < kddcCenter - kddcBW / 2 || centerfreq > kddcCenter + kddcBW / 2)
                {
                    ret = -1;
                }
                if (bw < (int)(kddcSam / pow(2, ZDExtraMax + 2) * 0.1) || bw > (int)(kddcSam / pow(2, ZDExtraMin + 2) * 0.8))
                {
                    ret = -2;
                }
                {
                    unsigned long long sfcnt = 0;
                    for (int j = 0; j < 2; ++j)
                    {
                        sfcnt += rxKDParam[j].SampleFreq * rxKDParam[j].bSwitch_KDDC;
                        sfcnt += rxKDParam[j].bSwitch_KFFT * ((double)fftLen / 1024 * 2112 * (1000 / (double)fftPeriod) / 4);
                        sfcnt += rxKDParam[j].Snapshot_Switch * rx_kz_speed_hz;
                        for (int i = 0; i < 8; ++i)
                        {
                            sfcnt += rxKDParam[j].ZDParam[i].SampleFreq * rxKDParam[j].ZDParam[i].bSwitch_ZDDC;
                        }
                    }
                    unsigned long long pre_cnt = sfcnt - rxKDParam[channel].ZDParam[ZDCh % ZDChMax].SampleFreq + sample;
                    if (pre_cnt > ach_sf_count_max_hz + 1)
                    {
                        return -3;
                    }
                    sf_all = pre_cnt;
                }
                if (ret == 0)
                {
                    int freqkey = (int)((double)(centerfreq - rxKDParam[channel].CenterFreq) / kddcSam * pow(2, 32));
                    long long old_cf = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].CenterFreq;
                    long long old_bw = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].BandWidth;
                    long long old_sf = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].SampleFreq;
                    rxKDParam[channel].ZDParam[ZDCh % ZDChMax].CenterFreq = centerfreq;
                    rxKDParam[channel].ZDParam[ZDCh % ZDChMax].BandWidth = bw;
                    rxKDParam[channel].ZDParam[ZDCh % ZDChMax].SampleFreq = sample;
                    int zd_is_up = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].bSwitch_ZDDC;
                    {
                        int CH = ZDCh;
                        unsigned long long BandWidth = bw;
                        unsigned long long SampleFreq = sample;
                        unsigned long long CenterFreq = centerfreq;
                        int CtrWord = freqkey;
                        bool bSwitch = zd_is_up;
                        int chouqvlv_num = samIndex;
                        int chouqvlv = samIndex;
                        int zd_FilterCoef[128];
                        memset(zd_FilterCoef, 0, 128 * sizeof(int));
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ch, ZDCh);
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_df, chouqvlv);
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_bw, BandWidth);
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_cw, CtrWord);
                        if (!(old_cf != CenterFreq && old_bw == BandWidth && old_sf == sample))
                        {
                            int zd_filterLen = SetFIRLpCoef2(zd_FilterCoef, 128, (double)BandWidth / SampleFreq, 18, 1.0);
                            for (int i = 0; i < zd_filterLen; ++i)
                            {
                                set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_fc, zd_FilterCoef[i]);
                            }
                        }
                        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_sf, SampleFreq);
                        // set_esun_rx_addr_val(p_usrp.ctx, addr_rx_zd_ch, ZDCh);
                    }
                    ret = 0;
                }
            }
        }
        catch (std::exception ex2)
        {
            std::cout << ex2.what() << std::endl;
        }
    }
    return ret;
}
bool Device_UHD::getDevZDParam(string chStr, unsigned char ZDCh, long long &centerfreq, int &bw, int &sample)
{
    bool ret = true;
    try
    {
        int channel = chStr.find("0") != string::npos ? 0 : 1;
        centerfreq = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].CenterFreq;
        bw = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].BandWidth;
        sample = rxKDParam[channel].ZDParam[ZDCh % ZDChMax].SampleFreq;
    }
    catch (std::exception ex2)
    {
        std::cout << ex2.what() << std::endl;
    }
    return ret;
}
void Device_UHD::getDevZDCenterRange(string chStr, long long &min, long long &max)
{
    int channel = chStr.find("0") != string::npos ? 0 : 1;
    min = rxKDParam[channel].CenterFreq - rxKDParam[channel].BandWidth / 2;
    min = std::max(min, 0LL);
    max = rxKDParam[channel].CenterFreq + rxKDParam[channel].BandWidth / 2;
}
void Device_UHD::getDevZDBandWidthRange(string chStr, int &min, int &max)
{
    int channel = chStr.find("0") != string::npos ? 0 : 1;
    min = rxKDParam[channel].SampleFreq / pow(2, ZDExtraMax + 2) * 0.1;
    max = rxKDParam[channel].SampleFreq / pow(2, ZDExtraMin + 2) * 0.8;
}
vector<int> Device_UHD::getDevZDSampleFreqRange(string chStr)
{
    vector<int> vecSam;
    int channel = chStr.find("0") != string::npos ? 0 : 1;
    for (int i = ZDExtraMax; i >= ZDExtraMin; i--)
    {
        double exSam = rxKDParam[channel].SampleFreq / pow(2, i + 2);
        if (exSam > ZDSamSum)
        {
            continue;
        }
        vecSam.push_back(exSam);
    }
    return vecSam;
}
bool old_need_sw;
void ThreadRecv_Func(ThreadRecvParam recvParam)
{
    Device_UHD *pThis = (Device_UHD *)recvParam.pThis;
    int channel = recvParam.channel;
    if (pThis != NULL && pThis->p_usrp.ctx != NULL)
    {
        try
        {
            std::chrono::steady_clock::time_point befTime = std::chrono::steady_clock::now();
            long long iRecvedLen = 0;
            struct iio_device *phy;
            struct iio_channel *chan;
            phy = iio_context_find_device(pThis->p_usrp.ctx, "adrv9002-phy");
            if (pThis->p_usrp.ctx)
            {
                if (channel == 0)
                {
                    chan = iio_device_find_channel(phy, "voltage0", false);
                    iio_channel_attr_write(chan, "ensm_mode", "rf_enabled");

                    pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx-lpc");
                    stream_channels_get_disenable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
                    chan = iio_device_find_channel(phy, "voltage0", true);
                    iio_channel_attr_write(chan, "ensm_mode", "primed");

                    pThis->p_usrp.iio_rx_arr[channel].rx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-rx-lpc");
                    stream_channels_get_enable(pThis->p_usrp.iio_rx_arr[channel].rx_dev, pThis->p_usrp.iio_rx_arr[channel].rx_chan, false);
                    tmp_block_size = my_iio_rx_block_point_size_big;
                    pThis->p_usrp.iio_rx_arr[channel].rx_buf = iio_device_create_buffer(pThis->p_usrp.iio_rx_arr[channel].rx_dev, my_iio_rx_block_point_size_big, false);
                }
                if (channel == 1)
                {
                    chan = iio_device_find_channel(phy, "voltage1", false);
                    iio_channel_attr_write(chan, "ensm_mode", "rf_enabled");

                    pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx2-lpc");
                    stream_channels_get_disenable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
                    chan = iio_device_find_channel(phy, "voltage1", true);
                    iio_channel_attr_write(chan, "ensm_mode", "primed");
                    pThis->p_usrp.iio_rx_arr[channel].rx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-rx2-lpc");
                    stream_channels_get_enable(pThis->p_usrp.iio_rx_arr[channel].rx_dev, pThis->p_usrp.iio_rx_arr[channel].rx_chan, false);
                    tmp_block_size = my_iio_rx_block_point_size_big;
                    pThis->p_usrp.iio_rx_arr[channel].rx_buf = iio_device_create_buffer(pThis->p_usrp.iio_rx_arr[channel].rx_dev, my_iio_rx_block_point_size_big, false);
                }
                // int ttret =  iio_buffer_set_blocking_mode( pThis->p_usrp.iio_rx_arr[channel].rx_buf,false);
                // int b =0;
            }
            void *buff_ptrs;
            while (pThis->bThread_Recv[channel])
            {
                tmp_sf_all = sf_all;
                int nrxbytes = iio_buffer_refill(pThis->p_usrp.iio_rx_arr[channel].rx_buf);
                int a = 0;
                buff_ptrs = iio_buffer_start(pThis->p_usrp.iio_rx_arr[channel].rx_buf);
                size_t recvSize = nrxbytes; // num_rx_samps * iPointSize * iChCount;
                if (recvSize > 0 && nrxbytes <= tmp_block_size * 4)
                {
                    // cout <<" have data"<<endl;
                    iRecvedLen += recvSize;
                    bool bCheckHead = pThis->ischeck_head;
                    if (bCheckHead)
                    {
                        int &iRecvBufSize = pThis->iRecvBufSize[channel];  // 缓存总大小
                        int &iRecvBufPosi = pThis->iRecvBufPosi[channel];  // 缓存当前大小
                        char *pDataBuf = (char *)pThis->pRecvBuf[channel]; // 缓存数据指针
                        int length = recvSize;                             // 网络接收数据大小
                        int lengthPosi = 0;                                // 网络接收数据已处理大小
                        char *pData = (char *)buff_ptrs;                   // 网络数据指针
                        char *pCheckData = NULL;                           // 检测包头的数据指针
                        int posi = 0;
                        if (iRecvBufPosi > 0)
                        {
                            int needSize = iRecvBufSize - iRecvBufPosi; // 还需要补充数据量
                            needSize = needSize > length ? length : needSize;
                            lengthPosi = needSize;
                            memcpy((char *)pDataBuf + iRecvBufPosi, pData, needSize);
                            iRecvBufPosi = needSize + iRecvBufPosi; // 当前缓存中数据长度
                            pCheckData = pDataBuf;
                        }
                        else
                        {
                            iRecvBufPosi = length;
                            pCheckData = pData;
                        }
                        // 111
                        while (pThis->bThread_Recv[channel] && posi < iRecvBufPosi)
                        {
                            if (posi + 4 < iRecvBufPosi)
                            {
                                if (((unsigned int *)(pCheckData + posi))[0] == 0xf628f6f6)
                                {
                                    int packLen = (int)2112;
                                    if (posi + packLen <= iRecvBufPosi)
                                    {
                                        if (pThis->callBackData != NULL)
                                        {
                                            pThis->callBackData(channel, pCheckData + posi, packLen);
                                            if (*((char *)pCheckData + posi + 12) == 16)
                                            {
                                                char gps_info[60] = {0};
                                                strncpy(gps_info, pCheckData + posi + 64, 28);
                                                pThis->gps_info = gps_info;
                                                std::reverse(pThis->gps_info.begin(), pThis->gps_info.end());
                                            }
                                        }
                                        posi += packLen;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    posi += 1;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        // 如果有剩余数据
                        if (posi < iRecvBufPosi)
                        {
                            memcpy(pDataBuf, pCheckData + posi, iRecvBufPosi - posi);
                            iRecvBufPosi = iRecvBufPosi - posi;
                        }
                        else
                        {
                            iRecvBufPosi = 0;
                        }
                        if (pCheckData != pData)
                        {
                            if (length - lengthPosi < 2112)
                            {
                                memcpy(pDataBuf + iRecvBufPosi, pData + lengthPosi, length - lengthPosi);
                                iRecvBufPosi += length - lengthPosi;
                            }
                            else
                            {
                                // 111
                                posi = lengthPosi - iRecvBufPosi;
                                pCheckData = pData;
                                while (pThis->bThread_Recv[channel] && posi < length)
                                {
                                    if (posi + 4 < length)
                                    {
                                        if (((unsigned int *)(pCheckData + posi))[0] == 0xf628f6f6)
                                        {
                                            int packLen = (int)2112;
                                            if (posi + packLen <= length)
                                            {
                                                if (pThis->callBackData != NULL)
                                                {
                                                    pThis->callBackData(channel, pCheckData + posi, packLen);
                                                    if (*((char *)pCheckData + posi + 12) == 16)
                                                    {
                                                        char gps_info[60] = {0};
                                                        strncpy(gps_info, pCheckData + posi + 64, 28);
                                                        pThis->gps_info = gps_info;
                                                        std::reverse(pThis->gps_info.begin(), pThis->gps_info.end());
                                                    }
                                                }
                                                posi += packLen;
                                            }
                                            else
                                            {
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            posi += 1;
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                // 如果有剩余数据
                                if (posi < length)
                                {
                                    memcpy(pDataBuf, pCheckData + posi, length - posi);
                                    iRecvBufPosi = length - posi;
                                }
                                else
                                {
                                    iRecvBufPosi = 0;
                                }
                                // 111
                            }
                        }
                    }
                    else
                    {
                        pThis->callBackData(channel, buff_ptrs, (int)recvSize);
                        if (*((char *)buff_ptrs + 12) == 16)
                        {
                            char gps_info[60] = {0};
                            strncpy(gps_info, (char *)buff_ptrs + 64, 28);
                            pThis->gps_info = gps_info;
                            std::reverse(pThis->gps_info.begin(), pThis->gps_info.end());
                        }
                    }
                }

                bool need_big = false;
                for (int i = 0; i < 2; ++i)
                {
                    if (pThis->rxKDParam[i].bSwitch_KDDC == true)
                    {
                        need_big = true;
                    }
                    for (int j = 0; j < 8; ++j)
                    {
                        if (pThis->rxKDParam[i].ZDParam[j].bSwitch_ZDDC == true)
                        {
                            need_big = true;
                        }
                    }
                }
                if (need_big == true && need_big != old_need_sw)
                {
                    iio_buffer_destroy(pThis->p_usrp.iio_rx_arr[channel].rx_buf);
                    pThis->p_usrp.iio_rx_arr[channel].rx_buf = iio_device_create_buffer(pThis->p_usrp.iio_rx_arr[channel].rx_dev, my_iio_rx_block_point_size_big, false);
                    old_need_sw = need_big;
                }
                if (need_big == false && need_big != old_need_sw)
                {
                    iio_buffer_destroy(pThis->p_usrp.iio_rx_arr[channel].rx_buf);
                    pThis->p_usrp.iio_rx_arr[channel].rx_buf = iio_device_create_buffer(pThis->p_usrp.iio_rx_arr[channel].rx_dev, my_iio_rx_block_point_size_big, false);
                    old_need_sw = need_big;
                }
                std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
                auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(curTime - befTime);
                if (dur_ms.count() > 1000)
                {
                    pThis->fRecvSpeed[channel] = (double)iRecvedLen / dur_ms.count() * 1000;
                    iRecvedLen = 0;
                    befTime = curTime;
                }
            }
            if (channel == 0)
            {
                chan = iio_device_find_channel(phy, "voltage0", false);
                iio_channel_attr_write(chan, "ensm_mode", "primed");
                pThis->p_usrp.iio_rx_arr[channel].rx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-rx-lpc");
                stream_channels_get_disenable(pThis->p_usrp.iio_rx_arr[channel].rx_dev, pThis->p_usrp.iio_rx_arr[channel].rx_chan, false);
                iio_buffer_destroy(pThis->p_usrp.iio_rx_arr[channel].rx_buf);
            }
            if (channel == 1)
            {
                chan = iio_device_find_channel(phy, "voltage1", false);
                iio_channel_attr_write(chan, "ensm_mode", "primed");
                pThis->p_usrp.iio_rx_arr[channel].rx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-rx2-lpc");
                stream_channels_get_disenable(pThis->p_usrp.iio_rx_arr[channel].rx_dev, pThis->p_usrp.iio_rx_arr[channel].rx_chan, false);
                iio_buffer_destroy(pThis->p_usrp.iio_rx_arr[channel].rx_buf);
            }
        }
        catch (std::exception ex)
        {
            std::cout << ex.what() << std::endl;
        }
    }
}
double Device_UHD::getDevRecvSpeed(int channel) const
{
    return fRecvSpeed[channel];
}
bool Device_UHD::isDevRecving(int channel) const
{
    return bThread_Recv[channel];
}
void Device_UHD::startDevRecv(int channel)
{
    if (spThread_Recv[channel] != NULL)
    {
        bThread_Recv[channel] = false;
        spThread_Recv[channel]->join();
        spThread_Recv[channel] = NULL;
        if (pRecvBuf[channel] != NULL)
        {
            free(pRecvBuf[channel]);
            pRecvBuf[channel] = NULL;
        }
    }
    else
    {
        iRecvBufSize[channel] = 2112 * 2;
        iRecvBufPosi[channel] = 0;
        pRecvBuf[channel] = malloc(iRecvBufSize[channel]);
        bThread_Recv[channel] = true;
        ThreadRecvParam recvParam;
        recvParam.channel = channel;
        recvParam.pThis = this;
        // rx_kd_ddc_sw |= (1 << channel);
        // set_esun_rx_addr_val(p_usrp.ctx, addr_rx_data_sw, rx_kd_ddc_sw);

        send_all_sw &= ~(1 << channel);
        set_esun_rx_addr_val(p_usrp.ctx, addr_tx_send_data_cw, send_all_sw);

        long long tmll = time(0);

        set_esun_rx_addr_val(p_usrp.ctx, addr_tm_set_l, tmll & 0xffffffff);
        set_esun_rx_addr_val(p_usrp.ctx, addr_tm_set_h, tmll >> 32);

        spThread_Recv[channel] = std::make_shared<std::thread>(ThreadRecv_Func, recvParam);
    }
}
void Device_UHD::stopDevRecv(int channel)
{
    if (spThread_Recv[channel] != NULL)
    {
        bThread_Recv[channel] = false;
        spThread_Recv[channel]->join();
        spThread_Recv[channel] = NULL;
    }
}
double Device_UHD::getDevSendSpeed(int channel) const
{
    return fSendSpeed[channel];
}
bool Device_UHD::isDevSending(int channel) const
{
    return bThread_Send[channel];
}
void ThreadSend_Func(Device_UHD *pThis, unsigned long long send_cf, unsigned long long data_sf, int channel, char *filename, bool bWhile)
{
    if (pThis != NULL && pThis->p_usrp.ctx_isopen)
    {
        std::chrono::steady_clock::time_point befTime = std::chrono::steady_clock::now();
        long long iSendedLen0 = 0;
        long long iSendedLen1 = 0;
        char *pdata0;
        char *pdata1;
        struct iio_device *phy;
        struct iio_channel *chan0;
        struct iio_channel *chan1;
        phy = iio_context_find_device(pThis->p_usrp.ctx, "adrv9002-phy");
        // 定义缓冲区
        char buffer0[1024];
        char buffer1[1024];
        std::vector<char> content0;
        std::vector<char> content1;
        size_t read_len0 = 0;
        size_t read_len1 = 0;
        // set_esun_rx_addr_val(p_usrp.ctx, addr_dev_ref_time, 5);
        int insert_num = 0;
        int cw_30Mhz = 0;
        cw_30Mhz = ((double)send_cf / ((double)122880000) * pow(2, 32));
        for (int i = 0; i <= 10; i++)
        {
            if (((int)define_KDDCSampleMax0 / pow(2, i)) == data_sf)
            {
                insert_num = i;
                break;
            }
        }
        if (channel == 0)
        {
            pThis->send_all_sw |= (1 << channel);
        }
        if (channel == 1)
        {
            pThis->send_all_sw |= (1 << channel);
        }
        if (send_cf > 30 * MHz && send_cf < 6 * GHz)
        {
            pThis->send_chan_sw &= ~(1 << channel);
        }
        if (send_cf <= 30 * MHz && send_cf > 0)
        {
            pThis->send_chan_sw |= (1 << channel);
        }
        int ch_cw = pThis->send_chan_sw;
        if (pThis->p_usrp.ctx)
        {

            // pThis->rxKDParam[channel].bSwitch_KDDC = false;
            // pThis->rxKDParam[channel].bSwitch_KFFT = false;
            // for(int i = 0; i <8;++i)
            // {
            //     pThis->rxKDParam[0].ZDParam[i].bSwitch_ZDDC = false;

            // }

            // int kz_val = 0;
            // for(int i = 0; i <2;++i)
            // {
            //     if(pThis->rxKDParam[i].Snapshot_Switch == true)
            //     {

            //         kz_val |=1<<i;
            //     }
            // }
            // pThis->rxKDParam[i].Snapshot_Switch

            // kz_val &=~(1<<channel);
            // set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_rx_kd_ddc_data_sw, 0);

            // set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_rx_kd_ddc_data_sw, 0);

            if (send_cf > 30 * MHz && send_cf < 6 * GHz)
            {
                if (channel == 0)
                {

                    pThis->p_usrp.iio_rx_arr[channel].rx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-rx-lpc");
                    stream_channels_get_disenable(pThis->p_usrp.iio_rx_arr[channel].rx_dev, pThis->p_usrp.iio_rx_arr[channel].rx_chan, false);

                    chan0 = iio_device_find_channel(phy, "voltage0", false);
                    iio_channel_attr_write(chan0, "ensm_mode", "primed");

                    chan0 = iio_device_find_channel(phy, "voltage0", true);
                    iio_channel_attr_write(chan0, "ensm_mode", "rf_enabled");
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_ch0_insert_rate, insert_num);
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_ch_sw, ch_cw);
                    chan0 = iio_device_find_channel(phy, "altvoltage2", true);
                    iio_channel_attr_write_longlong(chan0, "TX1_LO_frequency", send_cf);
                    pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx-lpc");
                    stream_channels_get_enable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
                    pThis->p_usrp.iio_tx_arr[channel].tx_buf = iio_device_create_buffer(pThis->p_usrp.iio_tx_arr[channel].tx_dev, my_iio_tx_block_point_size, false);
                }
                if (channel == 1)
                {

                    pThis->p_usrp.iio_rx_arr[channel].rx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-rx2-lpc");
                    stream_channels_get_disenable(pThis->p_usrp.iio_rx_arr[channel].rx_dev, pThis->p_usrp.iio_rx_arr[channel].rx_chan, false);

                    chan1 = iio_device_find_channel(phy, "voltage1", false);
                    iio_channel_attr_write(chan1, "ensm_mode", "primed");

                    chan1 = iio_device_find_channel(phy, "voltage1", true);
                    iio_channel_attr_write(chan1, "ensm_mode", "rf_enabled");
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_ch1_insert_rate, insert_num);
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_ch_sw, ch_cw);
                    chan1 = iio_device_find_channel(phy, "altvoltage3", true);
                    iio_channel_attr_write_longlong(chan1, "TX2_LO_frequency", send_cf);
                    pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx2-lpc");
                    stream_channels_get_enable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
                    // pThis->p_usrp.iio_tx_arr[channel].tx_chan[1] = iio_device_find_channel(pThis->p_usrp.iio_tx_arr[channel].tx_dev, "voltage0", true);
                    // if (!iio_channel_is_enabled(pThis->p_usrp.iio_tx_arr[channel].tx_chan[1]))
                    // {
                    //     iio_channel_enable(pThis->p_usrp.iio_tx_arr[channel].tx_chan[1]);
                    // }
                    pThis->p_usrp.iio_tx_arr[channel].tx_buf = iio_device_create_buffer(pThis->p_usrp.iio_tx_arr[channel].tx_dev, my_iio_tx_block_point_size, false);
                }
            }
            else if (send_cf <= 30 * MHz && send_cf > 0)
            {
                if (channel == 0)
                {
                    chan0 = iio_device_find_channel(phy, "voltage0", true);
                    iio_channel_attr_write(chan0, "ensm_mode", "primed");
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_ch0_insert_rate, insert_num);
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_ch0_30MHz_cw, cw_30Mhz);
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_ch_sw, ch_cw);
                    pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx-lpc");
                    stream_channels_get_enable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
                    pThis->p_usrp.iio_tx_arr[channel].tx_buf = iio_device_create_buffer(pThis->p_usrp.iio_tx_arr[channel].tx_dev, my_iio_tx_block_point_size, false);
                }
                if (channel == 1)
                {
                    chan1 = iio_device_find_channel(phy, "voltage1", true);
                    iio_channel_attr_write(chan1, "ensm_mode", "primed");
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_ch1_insert_rate, insert_num);
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_ch1_30MHz_cw, cw_30Mhz);
                    set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_ch_sw, ch_cw);
                    pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx2-lpc");
                    stream_channels_get_enable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
                    // pThis->p_usrp.iio_tx_arr[channel].tx_chan[1] = iio_device_find_channel(pThis->p_usrp.iio_tx_arr[channel].tx_dev, "voltage0", true);
                    // if (!iio_channel_is_enabled(pThis->p_usrp.iio_tx_arr[channel].tx_chan[1]))
                    // {
                    //     iio_channel_enable(pThis->p_usrp.iio_tx_arr[channel].tx_chan[1]);
                    // }
                    pThis->p_usrp.iio_tx_arr[channel].tx_buf = iio_device_create_buffer(pThis->p_usrp.iio_tx_arr[channel].tx_dev, my_iio_tx_block_point_size, false);
                }
            }
        }

        if (channel == 0)
        {
            std::ifstream file(filename, std::ios::binary);
            if (!file.is_open())
            {
                std::cerr << "无法打开文件" << std::endl;
                return; // 返回错误代码
            }
            // 逐块读取文件内容
            while (file.read(buffer0, sizeof(buffer0)))
            {
                std::streamsize bytesRead = file.gcount(); // 获取实际读取的字节数
                content0.insert(content0.end(), buffer0, buffer0 + bytesRead);
            }
            // 处理最后一块可能不足1024字节的情况
            if (file)
            {
                std::streamsize bytesRead = file.gcount();
                content0.insert(content0.end(), buffer0, buffer0 + bytesRead);
            }
            // 关闭文件
            file.close();
        }
        if (channel == 1)
        {
            std::ifstream file(filename, std::ios::binary);
            if (!file.is_open())
            {
                std::cerr << "无法打开文件" << std::endl;
                return; // 返回错误代码
            }
            // 逐块读取文件内容
            while (file.read(buffer1, sizeof(buffer1)))
            {
                std::streamsize bytesRead = file.gcount(); // 获取实际读取的字节数
                content1.insert(content1.end(), buffer1, buffer1 + bytesRead);
            }
            // 处理最后一块可能不足1024字节的情况
            if (file)
            {
                std::streamsize bytesRead = file.gcount();
                content1.insert(content1.end(), buffer1, buffer1 + bytesRead);
            }
            // 关闭文件
            file.close();
        }
        set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_data_cw, pThis->send_all_sw);
        while (pThis->bThread_Send[channel])
        {
            if (channel == 0)
            {
                size_t num_tx = iio_buffer_push(pThis->p_usrp.iio_tx_arr[channel].tx_buf);
                if (num_tx <= 0 || num_tx > my_iio_tx_block_point_size * 4)
                {
                    continue;
                }
                pdata0 = (char *)iio_buffer_start(pThis->p_usrp.iio_tx_arr[channel].tx_buf);
                if (!pdata0)
                {
                    continue;
                }
                if (content0.size() < num_tx)
                {
                    break;
                }
                if (content0.size() - read_len0 < num_tx)
                {
                    if (bWhile == true)
                    {
                        // read_len0 = 0;

                        // 多余数据
                        unsigned long long dysj = content0.size() - read_len0;
                        // 需要切割的头部数据
                        unsigned long long need_cut_size = num_tx - dysj;

                        ::memcpy(pdata0, content0.data() + read_len0, dysj);
                        ::memcpy(pdata0 + dysj, content0.data(), need_cut_size);

                        read_len0 = need_cut_size;
                        iSendedLen0 += num_tx;
                        std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
                        auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(curTime - befTime);
                        if (dur_ms.count() > 1000)
                        {
                            pThis->fSendSpeed[channel] = (double)iSendedLen0 / dur_ms.count() * 1000;
                            iSendedLen0 = 0;
                            befTime = curTime;
                        }

                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                ::memcpy(pdata0, content0.data() + read_len0, num_tx);
                read_len0 += num_tx;
                iSendedLen0 += num_tx;
                std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
                auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(curTime - befTime);
                if (dur_ms.count() > 1000)
                {
                    pThis->fSendSpeed[channel] = (double)iSendedLen0 / dur_ms.count() * 1000;
                    iSendedLen0 = 0;
                    befTime = curTime;
                }
            }
            if (channel == 1)
            {
                size_t num_tx = iio_buffer_push(pThis->p_usrp.iio_tx_arr[channel].tx_buf);
                if (num_tx <= 0 || num_tx > my_iio_tx_block_point_size * 4)
                {
                    continue;
                }
                pdata1 = (char *)iio_buffer_start(pThis->p_usrp.iio_tx_arr[channel].tx_buf);
                if (!pdata1)
                {
                    continue;
                }
                if (content1.size() < num_tx)
                {
                    break;
                }
                if (content1.size() - read_len1 < num_tx)
                {
                    if (bWhile == true)
                    {
                        // read_len1 = 0;

                        // 多余数据
                        unsigned long long dysj = content1.size() - read_len1;
                        // 需要切割的头部数据
                        unsigned long long need_cut_size = num_tx - dysj;

                        ::memcpy(pdata1, content1.data() + read_len1, dysj);
                        ::memcpy(pdata1 + dysj, content1.data(), need_cut_size);

                        read_len1 = need_cut_size;
                        iSendedLen1 += num_tx;
                        std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
                        auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(curTime - befTime);
                        if (dur_ms.count() > 1000)
                        {
                            pThis->fSendSpeed[channel] = (double)iSendedLen1 / dur_ms.count() * 1000;
                            iSendedLen1 = 0;
                            befTime = curTime;
                        }

                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                ::memcpy(pdata1, content1.data() + read_len1, num_tx);
                read_len1 += num_tx;
                iSendedLen1 += num_tx;
                std::chrono::steady_clock::time_point curTime = std::chrono::steady_clock::now();
                auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(curTime - befTime);
                if (dur_ms.count() > 1000)
                {
                    pThis->fSendSpeed[channel] = (double)iSendedLen1 / dur_ms.count() * 1000;
                    iSendedLen1 = 0;
                    befTime = curTime;
                }
            }
        }

        //---------------------------------------------

        pThis->send_chan_sw &= ~(1 << channel);
        set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_ch_sw, ch_cw);

        pThis->send_all_sw &= ~(1 << channel);

        set_esun_rx_addr_val(pThis->p_usrp.ctx, addr_tx_send_data_cw, pThis->send_all_sw);
        if (channel == 0)
        {
            pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx-lpc");
            stream_channels_get_disenable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
            chan0 = iio_device_find_channel(phy, "voltage0", true);
            iio_channel_attr_write(chan0, "ensm_mode", "primed");
        }
        if (channel == 1)
        {
            pThis->p_usrp.iio_tx_arr[channel].tx_dev = iio_context_find_device(pThis->p_usrp.ctx, "axi-adrv9002-tx2-lpc");
            stream_channels_get_disenable(pThis->p_usrp.iio_tx_arr[channel].tx_dev, pThis->p_usrp.iio_tx_arr[channel].tx_chan, true);
            chan0 = iio_device_find_channel(phy, "voltage1", true);
            iio_channel_attr_write(chan0, "ensm_mode", "primed");
        }

        iio_buffer_destroy(pThis->p_usrp.iio_tx_arr[channel].tx_buf);
    }
}
void Device_UHD::startDevSend(int channel, unsigned long long send_cf, unsigned long long data_sf, char *filename, bool bwhile)
{
    if (spThread_Send[channel] != NULL)
    {
        bThread_Send[channel] = false;
        spThread_Send[channel]->join();
        spThread_Send[channel] = NULL;
    }
    else
    {
        bThread_Send[channel] = true;
        rx_kd_ddc_sw &= ~(1 << channel);
        set_esun_rx_addr_val(p_usrp.ctx, addr_rx_data_sw, rx_kd_ddc_sw);
        spThread_Send[channel] = std::make_shared<std::thread>(ThreadSend_Func, this, send_cf, data_sf, channel, filename, bwhile);
    }
}
void Device_UHD::stopDevSend(int channel)
{
    if (spThread_Send[channel] != NULL)
    {
        bThread_Send[channel] = false;
        spThread_Send[channel]->join();
        spThread_Send[channel] = NULL;
    }
}
string Device_UHD::getGPSInfo()
{

    return this->gps_info;
}
