#include <stdio.h>
#include <string.h>
#include <vector>
#include <fstream>
#include<chrono>
#include<vector>
#include<iostream>
#include "example.h"
#include "htra_api.h"
using namespace std;

#define IS_USB 1 //默认使用的是USB型设备，若使用的是网口型设备则将IS_USB定义为0。

typedef struct
{
	uint32_t TraceCount;
	uint32_t TracePoints;
	uint32_t CurrentTraceCount;
	vector<float> PowerSpec_dBmAve;

}Trace_Profile_TypeDef;

//函数声明
int TraceAvg_Open(void** Trace, uint32_t TraceCount, uint32_t TracePoints);					//配置迹线平均相关参数，包括平均次数、迹线点数。
void TraceAvg_Execute(void** Trace, const float PowerSpec_dBm[], float PowerSpecAve_dBm[]); //迹线平均处理。
void TraceAvg_Reset(void** Trace);                                                          //重置迹线平均。
void TraceAvg_Close(void** Trace);															//关闭迹线平均。

int SWP_TraceAverage()
{
	int Status = 0;       //函数的返回值。
	void* Device = NULL;  //当前设备的内存地址。
	void* Trace = NULL;   //当前迹线的内存地址。
	int DevNum = 0;       //指定设备号。

	BootProfile_TypeDef BootProfile; //启动配置结构体，包括物理接口、供电方式等。
	BootInfo_TypeDef BootInfo;       //启动信息结构体，包括设备信息、USB速率等。

	BootProfile.DevicePowerSupply = USBPortAndPowerPort; //使用USB数据端口及独立电源端口双供电。

#if IS_USB==1
	//配置USB接口。
	BootProfile.PhysicalInterface = USB;
#else 
	//配置ETH接口。
	BootProfile.PhysicalInterface = ETH;
	BootProfile.ETH_IPVersion = IPv4;
	BootProfile.ETH_RemotePort = 5000;
	BootProfile.ETH_ReadTimeOut = 5000;
	BootProfile.ETH_IPAddress[0] = 192;
	BootProfile.ETH_IPAddress[1] = 168;
	BootProfile.ETH_IPAddress[2] = 1;
	BootProfile.ETH_IPAddress[3] = 100;
#endif

	Status = Device_Open(&Device, DevNum, &BootProfile, &BootInfo); //打开设备。

	Device_Open_ErrorHandling(Status, &Device, DevNum, &BootProfile, &BootInfo); //当Status不为0时，根据Status的返回值进行相对应的错误处理

	SWP_Profile_TypeDef SWP_ProfileIn;  //SWP输入配置，包括起始频率、终止频率、RBW、参考电平等。
	SWP_Profile_TypeDef SWP_ProfileOut; //SWP输出配置。
	SWP_TraceInfo_TypeDef TraceInfo;    //当前配置下的迹线信息，包括迹线点数、跳频点数等。

	SWP_ProfileDeInit(&Device, &SWP_ProfileIn); //初始化SWP模式的相关参数。

	SWP_ProfileIn.StartFreq_Hz = 9e3;   //配置起始频率。
	SWP_ProfileIn.StopFreq_Hz = 6.35e9; //配置终止频率。
	SWP_ProfileIn.RBW_Hz = 300e3;       //配置RBW。

	Status = SWP_Configuration(&Device, &SWP_ProfileIn, &SWP_ProfileOut, &TraceInfo); //下发SWP模式的相关配置。

	SWP_Configuration_ErrorHandling(Status, &Device, DevNum, &BootProfile, &BootInfo, &SWP_ProfileIn, &SWP_ProfileOut, &TraceInfo); //当Status不为0时，根据Status的返回值进行相对应的错误处理。

	vector<double> Frequency(TraceInfo.FullsweepTracePoints);    //创建频率数组。
	vector<float> PowerSpec_dBm(TraceInfo.FullsweepTracePoints); //创建功率数组。
	int HopIndex = 0;                                            //当前跳频点索引。
	int FrameIndex = 0;                                          //当前帧索引。
	MeasAuxInfo_TypeDef MeasAuxInfo;                             //测量数据的辅助信息，包括：功率最大值索引、功率最大值、设备温度、经纬度、绝对时间戳等。
	
	uint32_t TraceCount = 100;                             //设置迹线平均次数
	uint32_t TracePoints = TraceInfo.FullsweepTracePoints; //设置迹线点数。

	TraceAvg_Open(&Trace, TraceCount, TracePoints);                 //打开迹线平均。
	vector<float> PowerSpecAve_dBm(TraceInfo.FullsweepTracePoints); //建立功率平均数组。

	//循环获取数据。
	while (1)
	{
		Status = SWP_GetFullSweep(&Device, Frequency.data(), PowerSpec_dBm.data(), &MeasAuxInfo);                                                   //获取迹线数据。

		if (Status == APIRETVAL_NoError)
		{
			// UserCode here
			/*

			例如：显示频谱 或 对频谱做其他处理等。

			*/
		}

		else //当Status不为0时，根据Status的返回值进行相对应的错误处理。
		{
			SWP_ErrorHandlingExceptOpenAndConfiguration(Status, &Device, DevNum, &BootProfile, &BootInfo, &SWP_ProfileIn, &SWP_ProfileOut, &TraceInfo);
		}

		TraceAvg_Execute(&Trace, PowerSpec_dBm.data(), PowerSpecAve_dBm.data());                                                                    //进行迹线平均。
	}

	Device_Close(&Device); //关闭设备。

	return 0;
}

int  TraceAvg_Open(void** Trace, uint32_t TraceCount, uint32_t TracePoints)
{
	*Trace = new Trace_Profile_TypeDef;
	Trace_Profile_TypeDef* pTrace = (Trace_Profile_TypeDef*)(*Trace);
	pTrace->TraceCount = TraceCount;
	pTrace->TracePoints = TracePoints;
	pTrace->PowerSpec_dBmAve.resize(pTrace->TracePoints);
	pTrace->CurrentTraceCount = 0;
	return 0;
}

void TraceAvg_Execute(void** Trace, const float PowerSpec_dBm[], float PowerSpecAve_dBm[])
{
	Trace_Profile_TypeDef* pTrace = (Trace_Profile_TypeDef*)(*Trace);

	if (pTrace->CurrentTraceCount < pTrace->TraceCount) {
		pTrace->CurrentTraceCount++;
	}

	if (pTrace->CurrentTraceCount > 1) {
		for (uint32_t i = 0; i < pTrace->TracePoints; i++)
		{
			PowerSpecAve_dBm[i] = ((pTrace->CurrentTraceCount - 1.0) / pTrace->CurrentTraceCount) * pTrace->PowerSpec_dBmAve[i] + (1.0 / pTrace->CurrentTraceCount) * PowerSpec_dBm[i];
			pTrace->PowerSpec_dBmAve[i] = PowerSpecAve_dBm[i];
		}
	}
	else {
		memcpy(PowerSpecAve_dBm, PowerSpec_dBm, sizeof(float) * pTrace->TracePoints);
		memcpy(pTrace->PowerSpec_dBmAve.data(), PowerSpec_dBm, sizeof(float) * pTrace->TracePoints);
	}
}

void TraceAvg_Reset(void** Trace)
{
	Trace_Profile_TypeDef* pTrace = (Trace_Profile_TypeDef*)(*Trace);
	pTrace->CurrentTraceCount = 0; // 重置当前跟踪计数。
}

void TraceAvg_Close(void** Trace)
{
	delete (Trace_Profile_TypeDef*)(*Trace);
}