/*---------------------------------------------------------------------------*/
//       Author : Minkyu Kim
//          Web : http://naraeon.net/
//                https://github.com/ebangin127/cdi7nvme
//      License : The MIT License
/*---------------------------------------------------------------------------*/

#include "StdAfx.h"
#include "nvmeinterpreter.h"

void AddToATASmartBuf(SMART_ATTRIBUTE_LIST* ATASmartBuf, INT IdxInBuf, SMART_ATTRIBUTE AttrToAdd)
{
	(*ATASmartBuf)[IdxInBuf] = AttrToAdd;
}

SMART_ATTRIBUTE SeperateCriticalWarningFrom(UCHAR* NVMeSmartBuf)
{
	SMART_ATTRIBUTE attr = {};
	attr.Id = 1;
	attr.RawValue[0] = NVMeSmartBuf[0];
	return attr;
}

SMART_ATTRIBUTE SeperateTemperatureFrom(UCHAR* NVMeSmartBuf)
{
	const int TemperatureStart = 1;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 2;
	attr.RawValue[0] = NVMeSmartBuf[TemperatureStart];
	attr.RawValue[1] = NVMeSmartBuf[TemperatureStart + 1];
	return attr;
}

SMART_ATTRIBUTE SeperateAvailableSpareFrom(UCHAR* NVMeSmartBuf)
{
	const int AvailableSpareStart = 3;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 3;
	attr.RawValue[0] = NVMeSmartBuf[AvailableSpareStart];
	return attr;
}

SMART_ATTRIBUTE SeperateAvailableSpareThresholdFrom(UCHAR* NVMeSmartBuf)
{
	const int AvailableSpareThresholdStart = 4;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 4;
	attr.RawValue[0] = NVMeSmartBuf[AvailableSpareThresholdStart];
	return attr;
}

SMART_ATTRIBUTE SeperatePercentageUsedFrom(UCHAR* NVMeSmartBuf)
{
	const int PercentageUsedStart = 5;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 5;
	attr.RawValue[0] = NVMeSmartBuf[PercentageUsedStart];
	return attr;
}

SMART_ATTRIBUTE SeperateDataUnitsReadFrom(UCHAR* NVMeSmartBuf)
{
	const int DataUnitsReadStart = 32;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 6;
	memcpy(attr.RawValue, &NVMeSmartBuf[DataUnitsReadStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateDataUnitsWrittenFrom(UCHAR* NVMeSmartBuf)
{
	const int DataUnitsWrittenStart = 48;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 7;
	memcpy(attr.RawValue, &NVMeSmartBuf[DataUnitsWrittenStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateHostReadCommandsFrom(UCHAR* NVMeSmartBuf)
{
	const int ReadStart = 64;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 8;
	memcpy(attr.RawValue, &NVMeSmartBuf[ReadStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateHostWriteCommandsFrom(UCHAR* NVMeSmartBuf)
{
	const int WriteStart = 80;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 9;
	memcpy(attr.RawValue, &NVMeSmartBuf[WriteStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateControllerBusyTimeFrom(UCHAR* NVMeSmartBuf)
{
	const int BusyTimeStart = 96;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 10;
	memcpy(attr.RawValue, &NVMeSmartBuf[BusyTimeStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperatePowerCyclesFrom(UCHAR* NVMeSmartBuf)
{
	const int PowerCycleStart = 112;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 11;
	memcpy(attr.RawValue, &NVMeSmartBuf[PowerCycleStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperatePowerOnHoursFrom(UCHAR* NVMeSmartBuf)
{
	const int PowerOnHoursStart = 128;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 12;
	memcpy(attr.RawValue, &NVMeSmartBuf[PowerOnHoursStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateUnsafeShutdownsFrom(UCHAR* NVMeSmartBuf)
{
	const int UnsafeShutdownsStart = 144;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 13;
	memcpy(attr.RawValue, &NVMeSmartBuf[UnsafeShutdownsStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateMediaErrorsFrom(UCHAR* NVMeSmartBuf)
{
	const int MediaErrorsStart = 160;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 14;
	memcpy(attr.RawValue, &NVMeSmartBuf[MediaErrorsStart], sizeof(attr.RawValue));
	return attr;
}

SMART_ATTRIBUTE SeperateNumberOfErrorsFrom(UCHAR* NVMeSmartBuf)
{
	const int NumberOfErrorsStart = 176;
	SMART_ATTRIBUTE attr = {};
	attr.Id = 15;
	memcpy(attr.RawValue, &NVMeSmartBuf[NumberOfErrorsStart], sizeof(attr.RawValue));
	return attr;
}

void NVMeSmartToATASmart(UCHAR* NVMeSmartBuf, void* ATASmartBufUncasted)
{
	SMART_ATTRIBUTE_LIST* ATASmartBuf = (SMART_ATTRIBUTE_LIST*) ATASmartBufUncasted;
	int IdxInBuf = 0;
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateCriticalWarningFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateTemperatureFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateAvailableSpareFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateAvailableSpareThresholdFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperatePercentageUsedFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateDataUnitsReadFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateDataUnitsWrittenFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateHostReadCommandsFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateHostWriteCommandsFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateControllerBusyTimeFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperatePowerCyclesFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperatePowerOnHoursFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateUnsafeShutdownsFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateMediaErrorsFrom(NVMeSmartBuf));
	AddToATASmartBuf(ATASmartBuf, IdxInBuf++, SeperateNumberOfErrorsFrom(NVMeSmartBuf));
}