#include "stdafx.h"
#include "EpdBase.h"
#define DiscoveryTimeslotPeriod 100
#define DiscoveryExpirationPeriod  6000
#define RxRetryCount 5
#define TxRetryCount 5
#pragma unmanaged

EpdBase::Epd2U::Epd2U(int comport)
{
	port = comport;
	CommsInitialized = 0;
	if (port == 0) return;
	SetAutoCommit(0);
	Error = 123;
	//SetTimeouts(port, 20, 1000, 1000);
}
WORD EpdBase::Epd2U::WriteConfig()
{
	if (port == 0) return 1;
	return WriteDisplayConfig(00,2,40,10, 2,displayConfig, 56);
}
DWORD EpdBase::Epd2U::StartCom()
{
	DWORD rv;
	ErrorReason = 0;
	int mx = 10;
	if (port == 0) {
		CommsInitialized = 1;
		return 1;
	}
	if (CommsInitialized==0)
		do {
			InitRv = InitComms(port, 9600, 8, 0, 0);
			//System::Diagnostics::Trace::WriteLine(System::String::Format("InitCOms RV={0} Port={1}", InitRv, port));

			if (InitRv == 0) {
				rv= GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
				//System::Diagnostics::Trace::WriteLine(System::String::Format("InitCOms ErrorReason={0} ErrorData={1} Port={2}", ErrorReason, ErrorData, port));
				Sleep(300); DeinitComms(port);
			}
			else {
				SetRetryCounts(RxRetryCount, TxRetryCount);
				//SetDiscoveryTimeslotCount(port, 2);
				SetDiscoveryTimeslotPeriod(port, DiscoveryTimeslotPeriod);
				SetDiscoveryExpirationPeriod(port, DiscoveryExpirationPeriod);
			}
		} while (InitRv == 0 && mx > 0);
	
	CommsInitialized = InitRv;
	return ErrorReason;
}
EpdBase::Epd2U::~Epd2U()
{
	if (port>0) DeinitComms(port);
	CommsInitialized = 0;
}
int EpdBase::Epd2U::StartDiscover()
{
	//WORD rv;
	//System::Diagnostics::Trace::WriteLine("StartDiscover");
	Error = 0;

	//SetDiscoveryTimeslotCount(port, 2);
	//SetDiscoveryTimeslotPeriod(port, DiscoveryTimeslotPeriod);
	//SetDiscoveryExpirationPeriod(port, DiscoveryExpirationPeriod);
	
	//rv =SetRetryCounts(RxRetryCount, TxRetryCount);
	
	if (port == 0) {
		DeviceCount = 1;
		DeviceIDs[0] = 768;
		return 1;
	}

	FlushDiscoveryCache(port);
	FlushBuffers(port);
	int tries = 25; DeviceCount = 0; DiscRV = 1;
	while (tries-- > 0 && DeviceCount == 0 )
	{
		//memset(DeviceIDs, 0, sizeof(DeviceIDs));
		DiscRV = Discover(port, DeviceIDs, MaxDevices, &DeviceCount);
		//System::Diagnostics::Trace::WriteLine(System::String::Format("Discover try: {0} RV={1}", tries, DiscRV));
		if (DiscRV ==0 ) {
			Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
			//System::Diagnostics::Trace::WriteLine(System::String::Format("StartDiscover Error Connect Reason: {0} ErrorData {1}", ErrorReason, ErrorData));
		}
	}
	//System::Diagnostics::Trace::WriteLine(System::String::Format("Discover DeviceCount = {0}", DeviceCount));
	return DiscRV;
}
void EpdBase::Epd2U::Open(DWORD DeviceID)
{
	CurrentDeviceID = DeviceID;
	if (port > 0) {
		ConRV = Connect(DeviceID);
		if (ConRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
		else {
			OpenRV = OpenDevice(port, CurrentDeviceID);
			if (OpenRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
		}
	}
	else { OpenRV = ConRV = 1; }
}
void EpdBase::Epd2U::Close()
{
	if (port>0)	CloseDevice();
	//DeinitComms(port);	CommsInitialized = 0;
}
void EpdBase::Epd2U::DecodeFunctionFlags()
{
	EpdType = (FunctionFlags & 0x1F00) >> 8;
}
void EpdBase::Epd2U::DecodeStatus()
{
	DetectorsOn = (OperatingStatus & 1) != 0;
	EPDIssued  = (OperatingStatus & 4) != 0;
	EPDLocked = (OperatingStatus & 0x10)!=0;
	EPDTesting = (OperatingStatus & 0x20) != 0;
	EPDProcSec = (OperatingStatus & 0x40) != 0;
	EPDFaulty = (OperatingStatus & 0x80) != 0;

	EPDNewFault = (ErrorStatus & 1) != 0;
	EPDComFault = (ErrorStatus & 2) != 0;
	EPDCalFault = (ErrorStatus & 4) != 0;
	EPDDetFault = (ErrorStatus & 8) != 0;
	EPDEprFault = (ErrorStatus & 0x10) != 0;
	EPDTrhFault = (ErrorStatus & 0x20) != 0;
	EPDOthFault = (ErrorStatus & 0x80) != 0;

	AlarmDoseHP101G = (AlarmStatus & 1) != 0;
	AlarmDoseHP102G = (AlarmStatus & 2) != 0;
	AlarmDoseHP07N = (AlarmStatus & 4) != 0;
	AlarmRateHP101G = (AlarmStatus & 8) != 0;;
	AlarmRateHP102G = (AlarmStatus & 0x10) != 0;
	AlarmRateHP07N = (AlarmStatus & 0x20) != 0;

	//OtherAlarm
	OtherAlarmRateHp101G = (OtherAlarms & 1) != 0;
	OtherAlarmRateHp102G = (OtherAlarms & 2) != 0;
	OtherAlarmRateHp07N = (OtherAlarms & 4) != 0;
	OtherAlarmReturn = (OtherAlarms & 8) != 0;
	OtherAlarmBatLow =  (OtherAlarms & 0x10) != 0;
	OtherAlarmCarrier = (OtherAlarms & 0x20) != 0;
	OtherAlarmBatVolt = (OtherAlarms & 0x40) != 0;

}
WORD EpdBase::Epd2U::ReadStatus()
{
	Error = 0; ReadStatusRV = 0;
	memset(WearerID, 0, WearerIDLength + 1);
	memset(WearerName, 0, WearerNameLength + 1);

	IssueCount = OperatingStatus = ErrorStatus = AlarmStatus = OtherAlarms = EEPROMBadSectors = 0;
	RealTime = EpdClock = OffTime = EpdID = 0;
	ErrorSource = ErrorReason = ErrorData = 0;
	HardVersion = SoftVersion = FunctionFlags = 0;

	if (port == 0) {
		EpdID = 4567;
		EpdType = 0;
		FunctionFlags = 0x000;
		return 1;
	}

	CommitRV = ReadEpdStatus(&EpdClock, &RealTime, &IssueCount, &OffTime, &OperatingStatus, &ErrorStatus, &AlarmStatus, &OtherAlarms, &EEPROMBadSectors);
	if (port == 0) {
		EpdClock = 123; ErrorStatus = 0;
	};
	if (CommitRV == 1) CommitRV = Commit();
	if (CommitRV == 1) CommitRV = ReadEpdID(
		&EpdID,
		&HardVersion,
		&SoftVersion,
		&FunctionFlags);
	if (CommitRV == 1) CommitRV = Commit();
	if (CommitRV == 0) {
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
		ReadStatusRV = ErrorReason;
		return 0;
	}
	else {
		if (CurrentDeviceID == 0) CurrentDeviceID = EpdID;
		time_t t = RealTime;
		TimeFunctions::UnixTimeToSystemTime(t, &tRealTime);
		DecodeStatus();
		DecodeFunctionFlags();
	}

	if (CommitRV == 1 && EPDIssued == 1)
	{
		CommitRV = ReadWearer(
			WearerID,
			WearerIDLength,
			WearerName,
			WearerNameLength);
		if (CommitRV == 1) CommitRV = Commit();
		if (CommitRV == 0) {
			Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
			ReadStatusRV = ErrorReason;
			return 0;
		}
		else {
			for (int i = 0; i < WearerIDLength; i++)
				if (WearerID[i] == 0xb) WearerID[i] = '0'; else  WearerID[i] |= 0x30;
		}
	}
	return CommitRV;
}
WORD EpdBase::Epd2U::EPDReadExtraStatus()
{
	if (port == 0) return 1;

	byBatADC = bySupplyADC = 0;
	/*CommitRV = ReadA2ConfigStatus(
		&byBatADC,
		&bySupplyADC,
		&byStatus3,
		&byStatus4);
	if (CommitRV == 1) CommitRV = Commit();*/

	if (CommitRV == 1) CommitRV = ReadCounts(&D1, &D2, &D3, &D4, &CountsClock);
	if (CommitRV == 1) CommitRV = Commit();
	if (CommitRV == 1) CommitRV = ReadBaseCounts(&BaseD1, &BaseD2, &BaseD3, &BaseD4, &BaseCountsClock);
	if (CommitRV == 1) CommitRV = Commit();
	if (CommitRV == 0) 
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	return CommitRV;
}
WORD EpdBase::Epd2U::EPDReadConfig()
{
	if (port == 0) return 1;

	ReadConfigRV = ReadConfig(
		&CountDownTime,
		&ReturnTime,
		&ChirpRate,
		&TeleBaudSetting,
		&SelfTestInterval,
		&BatteryLoadTestInt,
		&GeneralControl,
		&CommsTimeout,
		&InhibitTimeout,
		&MinTxInterval,
		&MaxTxIntervals,
		&RandomiseWindow,
		&DoseIncThresh);
	if (ReadConfigRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	return CommitRV;
}
WORD EpdBase::Epd2U::TurnOff()
{
	if (port == 0) return 1;

	OffRV = EpdOff();
	if (OffRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	EndSessionRV = EndSession(AlarmCtrl,10);
	if (EndSessionRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);

	else {
		CommitRV = Commit();
		if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	}
	return CommitRV;
}
WORD EpdBase::Epd2U::TurnOn()
{
	if (port == 0) return 1;
	//OnRV = EpdOn();
	//if (OnRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	
	EndSessionRV = EndSession(AlarmCtrl, 10);
	if (EndSessionRV == 0) {
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
		return 0;
	}

	/*
	CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);*/
	
	return 0;
}
WORD EpdBase::Epd2U::WriteCal()
{
	if (port == 0) return 1;

	if (K6 > 2000)
	{	CommitRV = 0; 
		return 0;
	}
	Password = 9;
	//((BYTE *)&Password)[0] = 9;
	
	CommitRV = MFRLogin(Password);
	if (CommitRV == 1) CommitRV = Commit();
	
	if (CommitRV == 1) CommitRV = MFRWriteCalFactors(K1, K2, K3, K4, K5, K6);
	if (CommitRV == 1) CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	return CommitRV;
}
WORD EpdBase::Epd2U::ReadTresHolds()
{
	if (port == 0) {
		Hp10THDose1 = Hp10THDose2 = Hp10THDose2 = 123;
		Hp10Rate1On = Hp10Rate2On = Hp07RateOn = Hp10Rate1Off = Hp10Rate2Off = Hp07RateOff = 124;
		return 1;
	}
	Hp10THDose1 = Hp10THDose2 = Hp07THDose = 0;
	ReadDoseTresholdRV = ReadAlarmDoseThresholds(&Hp10THDose1, &Hp10THDose2, &Hp10THDose2);
	CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	ReadAlarmRateThresholdsRV = ReadAlarmRateThresholds(
		&Hp10Rate1On, 
		&Hp10Rate2On,
		&Hp07RateOn,
		&Hp10Rate1Off, 
		&Hp10Rate2Off,
		&Hp07RateOff);
	ReadCalibrationDataRV = ReadCalibrationData(
		&K1,
		&K2,
		&K3,
		&K4,
		&K5,
		&K6,
		&SG,
		&BC,
		&FB,
		&HG);
	CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	return CommitRV;
}
WORD EpdBase::Epd2U::ReadDoses()
{
	if (port == 0) {
		Hp10Dose = Hp07Dose = Hp10Total = Hp07Total = Knocks = Resets = QualityData = 21;
		Hp10Peak = Hp07Peak = Hp10Time = Hp07Time = 1000;
		ErrorSource = ErrorReason = ErrorData = 0;
		K1 = 1; K2 = 2; K3 = 3; K4 = 4; K5 = 5;  K6 = 6;
		SG = 7; BC = 8; FB = 9; HG = 10;
		return 1;
	}
	ReadDosesQualityRV = ReadPeaksRV = CommitRV = 0;
	ReadDosesQualityRV = ReadDosesQuality(
			&Hp10Dose, 
			&Hp07Dose,
			&Hp10Total, 
			&Hp07Total,
			&Knocks, 
			&Resets,
			&QualityData);

	if (ReadDosesQualityRV == 0) {
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
		return 0;
	}

	ReadPeaksRV = ReadPeaks(
		&Hp10Peak,
		&Hp07Peak,
		&Hp10Time,
		&Hp07Time);
	if (ReadPeaksRV == 0) {
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
		return 0;
	}

	CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);

	ReadCalibrationData(
		&K1,
		&K2,
		&K3,
		&K4,
		&K5,
		&K6,
		&SG,
		&BC,
		&FB,
		&HG);
	CommitRV = Commit();
	if (CommitRV == 0) Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData);
	return CommitRV;
}
WORD EpdBase::Epd2U::PrepareForIssue() 
{
	if (port == 0) return 1;
	CommitRV = WriteConfig();
	if (CommitRV) CommitRV = Commit();
	if (CommitRV) CommitRV = ClearDose();
	if (CommitRV) CommitRV = ClearTotalDose();
	if (CommitRV) CommitRV = ClearPeakRates();
	if (CommitRV) CommitRV = Commit();
	return CommitRV;
}
WORD EpdBase::Epd2U::DeIssue()
{
	ClearDoseRV = ClearTotalDoseRV = ClearPeakRatesRV = DeIssueEpdRV = 0;
	if (port == 0) return 1;
	if (CommitRV) CommitRV = ClearDose();
	if (CommitRV) CommitRV = ClearTotalDose();
	if (CommitRV) CommitRV = ClearPeakRates();
	if (CommitRV) CommitRV = Commit();
	if (CommitRV) CommitRV = ClearFaultFlags();
	if (CommitRV) CommitRV = ClearLatchedAlarms();//Hp10Rate1; Hp10Rate2; Hp07Rate; ReturnForRead
	if (CommitRV) CommitRV = Commit();
	CommitRV = ClearFailFlag();
	if (CommitRV) CommitRV = DeIssueEpd();
	if (CommitRV) CommitRV = Commit();
	if (CommitRV && DetectorsOn) {
		CommitRV = EpdOff();  
		CommitRV= Commit(); 
		Sleep(1000);// Versie < .. Commit & Sleep
	}
	
	if (CommitRV) { EndSession(EndSessionControl, 12); Commit(); }// Continuous high tone for 1.2 seconds
	else
	{
		FlushBuffers(port);
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData); EndSession(0x5E, 40); return 0;
	}
	Close();
	return CommitRV;
}
WORD EpdBase::Epd2U::Issue()
{
	IssueEpdRV = WriteAlarmDoseThresholdsRV = WriteAlarmRateThresholdsRV = WriteWearerNameRV = OnRV = CommitRV = 0;
	if (port == 0) return 1;
	WORD OKRV = SetFailFlag(); // all actions have been completed
	if (OKRV) OKRV = Commit();

	if (OKRV) OKRV = WriteAlarmDoseThresholds(Hp10THDose1, Hp10THDose2, Hp07THDose);
	if (OKRV) OKRV = WriteAlarmRateThresholds(Hp10Rate1On, Hp10Rate2On, Hp07RateOn, Hp10Rate1Off, Hp10Rate2Off, Hp07RateOff);
	if (OKRV) OKRV = Commit();
	if (OKRV) OKRV = IssueEpd(WearerID, WearerIDLength);
	if (OKRV) OKRV = Commit();
	if (OKRV) OKRV = WriteWearerName(WearerName,(WORD)strlen((char *)WearerName));
	if (OKRV) OKRV = Commit();
	if (OKRV) OKRV = BaseLineCounts();
	if (OKRV == 0) 
	{
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData); 
	}
	ClearFailFlag(); // all actions have been completed
	Commit();

	if (!DetectorsOn) {
		OKRV = EpdOn(); OKRV=Commit(); Sleep(1500);
	}
	
	if (OKRV) {
		
		EndSession(EndSessionControl, 12);  
		Commit();
	} // Continuous high tone for 1.2 seconds
	else 
	{ 
		FlushBuffers(port);
		Error = GetErrorDetails(&ErrorSource, &ErrorReason, &ErrorData); 
		EndSession(0x5E, 40); 
	}

	Close();
	//DeinitComms(port);

	return OKRV;
}