ThermalRelationshipTable PolicyServicesPlatformConfigurationData::getThermalRelationshipTable(void)
{
    throwIfNotWorkItemThread();

    UInt32 dataLength = 0;
    DptfMemory binaryData;
    binaryData.allocate(Constants::DefaultBufferSize, true);

    try
    {
        getEsifServices()->primitiveExecuteGet(
            esif_primitive_type::GET_THERMAL_RELATIONSHIP_TABLE,
            ESIF_DATA_BINARY,
            binaryData,
            binaryData.getSize(),
            &dataLength);
    }
    catch (buffer_too_small e)
    {
        binaryData.deallocate();
        binaryData.allocate(e.getNeededBufferSize(), true);
        getEsifServices()->primitiveExecuteGet(
            esif_primitive_type::GET_THERMAL_RELATIONSHIP_TABLE,
            ESIF_DATA_BINARY,
            binaryData,
            binaryData.getSize(),
            &dataLength);
    }

    ThermalRelationshipTable trt(BinaryParse::passiveTrtObject(dataLength, binaryData));

    binaryData.deallocate();

    return trt;
}
LpmTable PolicyServicesPlatformConfigurationData::getLpmTable(void)
{
    throwIfNotWorkItemThread();

    UInt32 dataLength = 0;
    DptfMemory binaryData;
    binaryData.allocate(Constants::DefaultBufferSize, true);
    LpmTable lpmTable(LpmConfigurationVersion::vInvalid, vector<LpmEntry>());

    try
    {
        getEsifServices()->primitiveExecuteGet(
            esif_primitive_type::GET_LPM_TABLE,
            ESIF_DATA_BINARY,
            binaryData,
            binaryData.getSize(),
            &dataLength
            );

        lpmTable = BinaryParse::lpmTableObject(dataLength, binaryData);
    }
    catch (buffer_too_small e)
    {
        binaryData.deallocate();
        binaryData.allocate(e.getNeededBufferSize(), true);
        getEsifServices()->primitiveExecuteGet(
            esif_primitive_type::GET_LPM_TABLE,
            ESIF_DATA_BINARY,
            binaryData,
            binaryData.getSize(),
            &dataLength
            );

        lpmTable = BinaryParse::lpmTableObject(dataLength, binaryData);
    }
    catch (...)
    {
        // TODO: This is still under discussion so leaving the v0 part commented.

        // We assume version:v0 if we come here.
        //lpmTable = LpmTable(LpmConfigurationVersion::v0, vector<LpmEntry>());
        lpmTable = LpmTable(LpmConfigurationVersion::v1, vector<LpmEntry>());
    }

    binaryData.deallocate();
    return (lpmTable);
}
UInt32 PolicyServicesPlatformConfigurationData::getLpmMode(void)
{
    throwIfNotWorkItemThread();

    return getEsifServices()->primitiveExecuteGetAsUInt32(
        esif_primitive_type::GET_CURRENT_LOW_POWER_MODE
        );
}
void PolicyServicesMessageLogging::writeMessageDebug(const DptfMessage& message)
{
    throwIfNotWorkItemThread();

    ManagerMessage updatedMessage = ManagerMessage(getDptfManager(), message);
    updatedMessage.setPolicyIndex(getPolicyIndex());

    getEsifServices()->writeMessageDebug(updatedMessage);
}
void PolicyServicesPlatformNotification::executeOsc(const Guid& guid, UInt32 oscCapabilities)
{
	Bool successful = false;

	struct esif_data_complex_osc osc;
	esif_ccb_memcpy(osc.guid, guid, Guid::GuidSize);
	osc.revision = 1;
	osc.count = 2;
	osc.status = 0;
	osc.capabilities = oscCapabilities;
	std::string failureMessage;

	try
	{
		getEsifServices()->primitiveExecuteSet(
			SET_OPERATING_SYSTEM_CAPABILITIES,
			ESIF_DATA_STRUCTURE,
			&osc,
			sizeof(esif_data_complex_osc),
			sizeof(esif_data_complex_osc));
		successful = true;
	}
	catch (std::exception& ex)
	{
		failureMessage = ex.what();
	}
	catch (...)
	{
		failureMessage = "Unknown error.";
	}

	if (osc.status & 0xE)
	{
		if (osc.status & 0x2)
		{
			throw dptf_exception("Platform supports _OSC but unable to process _OSC request.");
		}

		if (osc.status & 0x4)
		{
			throw dptf_exception("Platform failed _OSC Reason: Unrecognized UUID.");
		}

		if (osc.status & 0x8)
		{
			throw dptf_exception("Platform failed _OSC Reason: Unrecognized revision.");
		}
	}

	if (successful == false)
	{
		throw dptf_exception("Failure during execution of _OSC: " + failureMessage);
	}
}
void PolicyServicesPlatformPowerState::shutDown(const Temperature& currentTemperature,
        const Temperature& tripPointTemperature)
{
    throwIfNotWorkItemThread();

    esif_data_complex_shutdown shutdownData;
    shutdownData.temperature = currentTemperature;
    shutdownData.tripPointTemperature = tripPointTemperature;

    getEsifServices()->primitiveExecuteSet(SET_SYSTEM_SHUTDOWN, ESIF_DATA_STRUCTURE,
                                           &shutdownData, sizeof(esif_data_complex_shutdown), sizeof(esif_data_complex_shutdown));
}
void PolicyServicesPlatformConfigurationData::clearPlatformSettings(
    PlatformSettingType::Type platformSettingType)  
{
    throwIfNotWorkItemThread();

    switch (platformSettingType)
    {
        case PlatformSettingType::ConfigTdp:
        {
            getEsifServices()->primitiveExecuteSet(esif_primitive_type::SET_SYSTEM_CONFIGTDP_CLEAR_LEVELS, 
                esif_data_type::ESIF_DATA_VOID, nullptr, 0, 0);
            break;
        }
        default:
        {
            throw dptf_exception("Invalid platform setting type referenced in call to clear platform settings.");
        }
    }
}
void PolicyServicesPlatformConfigurationData::writePlatformSettingValue(
    PlatformSettingType::Type platformSettingType, UInt8 index, const std::string& stringValue)  
{
    throwIfNotWorkItemThread();

    switch (platformSettingType)
    {
        case PlatformSettingType::ConfigTdp:
        {
            getEsifServices()->primitiveExecuteSetAsString(esif_primitive_type::SET_SYSTEM_CONFIGTDP_LEVEL_NAME, 
                stringValue, Constants::Esif::NoParticipant, Constants::Esif::NoDomain, index);
            break;
        }
        default:
        {
            throw dptf_exception("Invalid platform setting type referenced in call to write platform setting value.");
        }
    }
}
void PolicyServicesPlatformPowerState::hibernate(void)
{
    throwIfNotWorkItemThread();
    getEsifServices()->primitiveExecuteSetAsUInt32(SET_SYSTEM_HIBERNATE, MagicToken);
}
void PolicyServicesPlatformPowerState::sleep(void)
{
    throwIfNotWorkItemThread();
    getEsifServices()->primitiveExecuteSetAsUInt32(SET_SYSTEM_SLEEP, MagicToken);
}
std::string PolicyServicesPlatformConfigurationData::readConfigurationString(const std::string& key)
{
    throwIfNotWorkItemThread();
    std::string value = getEsifServices()->readConfigurationString(key);
    return value;
}
void PolicyServicesPlatformConfigurationData::writeConfigurationUInt32(const std::string& key, UInt32 data)
{
    throwIfNotWorkItemThread();
    getEsifServices()->writeConfigurationUInt32(key, data);
}