591 lines
27 KiB
C#

//----------------------------------------------------------------------------
//
// Copyright (c) Intel Corporation, 2011 - 2012 All Rights Reserved.
//
// File: PowerPackageApi.cs
//
// Contents: Api code for Intel(R) Active Management Technology
// (Intel® AMT) PowerPackage Sample.
//
// Notes: This sample demonstrates how to how to use various commands of
// the PowerPackage service.
//
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using Utils;
using Intel.Management.Wsman;
using Common.Utils;
namespace PowerPackage
{
public class PowerPackageApi : Connection.Connection_setup
{
#region PRIVATE_DATA_MEMBERS
/// <summary>
/// Indicate whether G3 support is on or off
/// </summary>
private enum ON_OFF_FLAG
{
ON,
OFF
};
/// <summary>
/// The current power state of the Intel AMT system. Also needed for querying allowed
/// power transitions.
/// </summary>
public enum PowerState
{
/// <summary>
/// Power state could not be determined, perhaps due to network error.
/// </summary>
Unknown = 0,
/// <summary>
/// The system is powered on (S0).
/// </summary>
On,
/// <summary>
/// Alias for On.
/// </summary>
S0 = On,
/// <summary>
/// The system is in standby mode (S3).
/// </summary>
StandBy,
/// <summary>
/// Alias for standby.
/// </summary>
S3 = StandBy,
/// <summary>
/// The system is in hibernate mode (S4).
/// </summary>
Hibernate,
/// <summary>
/// Alias for Hibernate.
/// </summary>
S4 = Hibernate,
/// <summary>
/// The system is powered off (S5).
/// </summary>
Off,
/// <summary>
/// Alias for Off.
/// </summary>
S5 = Off,
/// <summary>
/// Error value.
/// </summary>
Unexpected
}
/* /// <summary>
/// Index power state table to indicate the various power states
/// </summary>
private static PowerState[] table =
{
PowerState.Unknown, // <-- real unknown; rest are defensive coding
PowerState.Unexpected, // Other,
PowerState.On, // regular on
PowerState.On, // LightSleep,
PowerState.StandBy, // DeepSleep,
PowerState.Unexpected, // not supported in code
PowerState.Unexpected, // HardOff,
PowerState.Hibernate,
PowerState.Off,
PowerState.Unexpected, // HardPowerCycle,
PowerState.Unexpected, // MasterBusReset,
PowerState.Unexpected, // DiagnosticInterrupt,
};
*/
// const that identify the given CLI arguments
private const uint OnInS0_Only = 1;
private const uint OnInSx_AC = 2;
/// <summary>
/// Power schema in S0 only, mobile and desktop.
/// </summary>
private const string POWER_PACKAGE_MOBILE_ON_S0 = "djmXEQtWUEOIcJgS85G1YA==";
private const string POWER_PACKAGE_DESKTOP_ON_S0 = "lE+DEvsQT9yWjh4jKwyQZQ==";
/// <summary>
///Power schema in Sx, mobile and desktop.
/// </summary>
private const string POWER_PACKAGE_DESKTOP_ON_S0_SX_5 = "cyJzRiPcQy+pihPTeYLYVQ==";
private const string POWER_PACKAGE_MOBILE_ON_S0_SX_5 = "MIAN7gnAeEOvKHhootu+Og==";
private const string POWER_PACKAGE_DESKTOP_ON_S0_SX_3 = "coarrJa0SOKbnpt9+Rx/1A==";
private const string POWER_PACKAGE_MOBILE_ON_S0_SX_3 = "Uw4I22wP2Uiy0olY0/EVbg==";
/// <summary>
/// Power schema in Sx when G3 support is On.
/// </summary>
private const string POWER_PACKAGE_DISABLE_WAKE_AFTER_POWER_LOSS_7 = "1gvj7QTFLEa3ctGAGO4vxA==";
private const string POWER_PACKAGE_DISABLE_WAKE_AFTER_POWER_LOSS_6 = "xRmkum5vjU2yJ1F/fkWV2w==";
private Dictionary<string, uint> _priorityMapS0;
private Dictionary<string, uint> _priorityMapSxOnAfterPowerLossPreferWlan;
private Dictionary<string, uint> _priorityMapSxOnAfterPowerLossDisableWlan;
private Dictionary<string, uint> _priorityMapSxOffAfterPowerLossPreferWlan;
private Dictionary<string, uint> _priorityMapSxOffAfterPowerLossDisableWlan;
// This collection will apply to Intel AMT 4.0 and >= 6.0.
private Dictionary<string, uint> _priorityMapSxGeneral;
// User parameters
private static CmdLineArguments Params = new CmdLineArguments();
#endregion PRIVATE_DATA_MEMBERS
#region CONSTRUCTORS
/// <summary>
/// Constructor.
/// </summary>
/// <param name="wsmanClient">IWSManClient, the wsmanClient object</param>
/// Inheriting Connection details from Connection_setup class.
// Convert password to secure string to comply with wsman dll which supports passwords in SecureString
// format only.
public PowerPackageApi(string ip, string username, string pwd, bool krb, MpsManager proxy, bool acceptSelfSignedCertificate = false)
: base(ip, username, pwd.ConvertToSecureString(), krb, proxy, acceptSelfSignedCertificate)
{
InitPriorityMap();
}
public PowerPackageApi(string ip, string username, string pwd, string secure, bool krb, MpsManager proxy, bool acceptSelfSignedCertificate = false)
: base(ip, username, pwd.ConvertToSecureString(), secure, krb, proxy, acceptSelfSignedCertificate)
{
InitPriorityMap();
}
#endregion CONSTRUCTORS
#region PRIVATE_FUNCTIONS
/// <summary>
/// Initialize the power package priority map
/// according to recommended settings.
/// </summary>
private void InitPriorityMap()
{
_priorityMapS0 = new Dictionary<string, uint>();
_priorityMapSxOnAfterPowerLossPreferWlan = new Dictionary<string, uint>();
_priorityMapSxOnAfterPowerLossDisableWlan = new Dictionary<string, uint>();
_priorityMapSxOffAfterPowerLossPreferWlan = new Dictionary<string, uint>();
_priorityMapSxOffAfterPowerLossDisableWlan = new Dictionary<string, uint>();
_priorityMapSxGeneral = new Dictionary<string, uint>();
// power packages available for S0
_priorityMapS0.Add(POWER_PACKAGE_MOBILE_ON_S0, 1);
_priorityMapS0.Add(POWER_PACKAGE_DESKTOP_ON_S0, 2);
// sorted power package for Sx based on priority (4.0 and >= 6.0)
_priorityMapSxGeneral.Add(POWER_PACKAGE_DESKTOP_ON_S0_SX_5, 1);
_priorityMapSxGeneral.Add(POWER_PACKAGE_MOBILE_ON_S0_SX_5, 2);
_priorityMapSxGeneral.Add(POWER_PACKAGE_DESKTOP_ON_S0_SX_3, 3);
_priorityMapSxGeneral.Add(POWER_PACKAGE_MOBILE_ON_S0_SX_3, 4);
// sorted power package for Sx based on priority (POWER_LOSS=ON, PreferWake)
_priorityMapSxOnAfterPowerLossPreferWlan.Add(POWER_PACKAGE_DESKTOP_ON_S0_SX_5, 1);
_priorityMapSxOnAfterPowerLossPreferWlan.Add(POWER_PACKAGE_DESKTOP_ON_S0_SX_3, 2);
// sorted power package for Sx based on priority (POWER_LOSS=ON, DisableWake)
_priorityMapSxOnAfterPowerLossDisableWlan.Add(POWER_PACKAGE_DESKTOP_ON_S0_SX_3, 1);
// sorted power package for Sx based on priority (POWER_LOSS=OFF, PreferWake)
_priorityMapSxOffAfterPowerLossPreferWlan.Add(POWER_PACKAGE_DISABLE_WAKE_AFTER_POWER_LOSS_7, 1);
_priorityMapSxOffAfterPowerLossPreferWlan.Add(POWER_PACKAGE_DISABLE_WAKE_AFTER_POWER_LOSS_6, 2);
// sorted power package for Sx based on priority (POWER_LOSS=OFF, Disable)
_priorityMapSxOffAfterPowerLossDisableWlan.Add(POWER_PACKAGE_DISABLE_WAKE_AFTER_POWER_LOSS_6, 2);
}
///<summary>
///Get System Power State
///</summary>
///<param name="state"> out param contains the current power state.</param>
public PowerState GetSystemPowerState()
{
IManagedReference computerSystemRef = wsmanClient.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='ManagedSystem'");
IManagedReference associatedPowerManagementRef = wsmanClient.NewReference("CIM_AssociatedPowerManagementService");
associatedPowerManagementRef.AddSelector("UserOfService", computerSystemRef);
foreach (IWsmanItem associatedPowerMgmtItem in associatedPowerManagementRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
//for each instance,check if it is associated to the CIM_powerManagmentService instance.
if (associatedPowerMgmtItem.Object.GetProperty("ServiceProvided").IsA("CIM_PowerManagementService"))
{
IWsmanItem associatedPowerMgmtInstance = associatedPowerMgmtItem;
PowerState powerState = (PowerState)Enum.Parse(typeof(PowerState), (associatedPowerMgmtInstance.Object.GetProperty("PowerState").ToString()));
return powerState;
}
}
return 0;
}
/// <summary>
/// This function will enumerate the AMT_SystemPowerScheme in order to get the available power schemas
/// and then it will try to set the power package based on the params given.
/// For example:
/// Giving priorityMap of Sx will try to set power package 5
/// if it is available, otherwise it will try to set power package 3.
///
/// Giving priorityMap of G3 Support will try to set power package 7
/// if it is available, otherwise it will try to set power package 6 if available.
/// </summary>
/// <param name="priorityMap">dictionary which contains the potential power packages</param>
private void SetPPBasedOnPriority(Dictionary<string, uint> priorityMap)
{
// Sorted list which will contain power packages
// that exist to the remote machine, sorted according
// to the recommended priority
SortedList<uint, IManagedReference> existingScheme = new SortedList<uint, IManagedReference>();
// Traversing the AMT_SystemPowerScheme instances using the Intel AMT instance as EPR.
IManagedReference computerSystemRef = wsmanClient.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='Intel(r) AMT'");
IManagedReference elementSettingsDataRef = wsmanClient.NewReference("CIM_ElementSettingData");
elementSettingsDataRef.AddSelector("ManagedElement", computerSystemRef);
//Traverse to the CIM_ElementSettingData instances that are connected to CIM_ComputerSystem.
foreach (IWsmanItem elementSettingDataItem in elementSettingsDataRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
//For each instance, check if it is associated to the AMT_SystemPowerScheme instance.
if (elementSettingDataItem.Object.GetProperty("SettingData").IsA("AMT_SystemPowerScheme"))
{
//Get the AMT_systemPowerScheme object using its EPR.
IManagedInstance systemPowerSchemeInstance = elementSettingDataItem.Object.GetProperty("SettingData").Ref.Get();
IWsmanItem schemeGUID = systemPowerSchemeInstance.GetProperty("SchemeGUID");
if (priorityMap.ContainsKey(schemeGUID.ToString()))
{
existingScheme.Add(priorityMap[schemeGUID.ToString()], elementSettingDataItem.Object.GetProperty("SettingData").Ref);
}
}
}
// TODO: Ask Nati - how exactly to implement..!
bool succeeded = false;
foreach (KeyValuePair<uint, IManagedReference> item in existingScheme)
{
try
{
IManagedReference computerSystemRef1 = wsmanClient.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='Intel(r) AMT'");
IManagedReference elementSettingDataRef = wsmanClient.NewReference("CIM_ElementSettingData");
elementSettingDataRef.AddSelector("ManagedElement", computerSystemRef1);
//Traverse to the CIM_ElementSettingData instances that are connected to CIM_ComputerSystem.
foreach (IWsmanItem elementSettingDataItem in elementSettingDataRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
//For each instance, check if it is associated to the AMT_SystemPowerScheme instance.
if (elementSettingDataItem.Object.GetProperty("SettingData").IsA("AMT_SystemPowerScheme"))
{
// Get the AMT_systemPowerScheme object using its EPR.
IManagedReference systemPowerSchemeRef = elementSettingDataItem.Object.GetProperty("SettingData").Ref;
IManagedInstance systemPowerSchemeInstance = systemPowerSchemeRef.Get();
IManagedInstance inputObject = systemPowerSchemeRef.CreateMethodInput("SetPowerScheme");
IManagedInstance outputObject = systemPowerSchemeRef.InvokeMethod(inputObject);
IWsmanItem returnValue = outputObject.GetProperty("ReturnValue");
if (returnValue.ToString().CompareTo("0") == 0)
{
Console.WriteLine("Instance ID: {0}", systemPowerSchemeInstance.GetProperty("InstanceID").ToString());
Console.WriteLine("Description: {0}", systemPowerSchemeInstance.GetProperty("Description").ToString());
Console.WriteLine("GUID: {0}\n", systemPowerSchemeInstance.GetProperty("SchemeGUID").ToString());
succeeded = true;
break;
}
}
}
}
catch (Exception e)
{
Params.catchType(e, e.Message);
}
if (!succeeded)
{
Console.WriteLine("Failed to set power package\n");
}
}
}
/// <summary>
/// Based on afterPowerLoss and wakeOn params, sets the relevant set of power packages to try
/// </summary>
/// <param name="afterPowerLoss">On - load machine after power loss to S0; Off - after power loss machine will not be reachable</param>
/// <param name="wakeOn">prefer wake on power package</param>
/// <returns>set of power packages sorted according to the priority</returns>
private Dictionary<string, uint> SetPriorityMapSx(ON_OFF_FLAG afterPowerLoss, ON_OFF_FLAG wakeOn)
{
Dictionary<string, uint> v;
if (afterPowerLoss == ON_OFF_FLAG.ON)
{
if (wakeOn == ON_OFF_FLAG.ON)
{
v = _priorityMapSxOnAfterPowerLossPreferWlan;
}
else
{
v = _priorityMapSxOnAfterPowerLossDisableWlan;
}
}
else
{
if (wakeOn == ON_OFF_FLAG.ON)
{
v = _priorityMapSxOffAfterPowerLossPreferWlan;
}
else
{
v = _priorityMapSxOffAfterPowerLossDisableWlan;
}
}
return v;
}
/// <summary>
/// Set power package On in S0.
/// </summary>
private void SetPPOnInS0()
{
Console.WriteLine("---------------Set Power Package S0--------------");
SetPPBasedOnPriority(_priorityMapS0);
}
/// <summary>
/// Ask the user if there is a need to continue the flow of changing the power schema.
/// </summary>
/// <returns>yes = continue the flow, no = exit the flow</returns>
private string continueFlow()
{
string chosenOption = string.Empty;
do
{
Console.WriteLine("Are you sure you want to continue[yes, no]?");
chosenOption = Console.ReadLine();
if (chosenOption == string.Empty)
chosenOption = "no";
else
chosenOption = chosenOption.ToLower();
if (chosenOption.Equals("yes") || chosenOption.Equals("no"))
break;
} while (true);
return chosenOption;
}
#endregion
#region PUBLIC_FUNCTION
/// <summary>
/// Defines the minimum time value, in minutes, that
/// Intel AMT will be operable after waking up from a
/// sleep power state. This timer value will be reloaded
/// whenever Intel AMT is servicing requests. Note: this
/// setting may not be applicable under some power package
/// definitions
/// </summary>
/// <param name="value">the actual idleWakeTimeout value</param>
public void setIdleWakeTimeout(uint value)
{
Console.WriteLine("---------------Set Idle Wake Timeout--------------");
// Traversing the AMT_GeneralSettings instance using the Intel AMT as a reference.
IManagedReference generalSettingsRef = wsmanClient.NewReference("SELECT * FROM AMT_GeneralSettings WHERE InstanceID='Intel(r) AMT: General Settings'");
IManagedInstance generalSettingsInstance = generalSettingsRef.Get();
generalSettingsInstance.SetProperty("IdleWakeTimeout", value.ToString()); // Value can range from 1 to 65535);
generalSettingsRef.Put(generalSettingsInstance);
Console.WriteLine("Idle wake timeout was set successfully");
}
/// <summary>
/// Enumerate the current power packages
/// </summary>
public void enumerate()
{
Console.WriteLine("---------------Enumerate Power Packages--------------");
IManagedReference computerSystemRef = wsmanClient.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='Intel(r) AMT'");
IManagedReference elementSettingDataRef = wsmanClient.NewReference("CIM_ElementSettingData");
elementSettingDataRef.AddSelector("ManagedElement", computerSystemRef);
//Traverse to the CIM_ElementSettingData instances that are connected to CIM_ComputerSystem.
foreach (IWsmanItem elementSettingDataItem in elementSettingDataRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
//For each instance, check if it is associated to the AMT_SystemPowerScheme instance.
if (elementSettingDataItem.Object.GetProperty("SettingData").IsA("AMT_SystemPowerScheme"))
{
// Get the AMT_systemPowerScheme object using its EPR.
IManagedInstance systemPowerSchemeInstance = elementSettingDataItem.Object.GetProperty("SettingData").Ref.Get();
IWsmanItem schemeGUID = systemPowerSchemeInstance.GetProperty("SchemeGUID");
IWsmanItem instanceID = systemPowerSchemeInstance.GetProperty("InstanceID");
IWsmanItem description = systemPowerSchemeInstance.GetProperty("Description");
Console.WriteLine("Instance ID: {0}", instanceID.ToString());
Console.WriteLine("GUID: {0}", schemeGUID.ToString());
Console.WriteLine("Description: {0}\n", description.ToString());
}
}
}
/// <summary>
/// Return the minimum time value, in minutes, that
/// Intel AMT will be operable after waking up from a
/// sleep power state. This timer value will be reloaded
/// whenever Intel AMT is servicing requests. Note: this
/// setting may not be applicable under some power package
/// definitions
/// </summary>
public IWsmanItem getIdleWakeTimeout()
{
Console.WriteLine("---------------Get Idle Wake Timeout--------------");
// Traversing the AMT_GeneralSettings instance using the Intel AMT as a reference.
IManagedReference generalSettingsRef = wsmanClient.NewReference("SELECT * FROM AMT_GeneralSettings WHERE InstanceID='Intel(r) AMT: General Settings'");
IManagedInstance generalSettingsInstance = generalSettingsRef.Get();
IWsmanItem IdleWakeTimeout = generalSettingsInstance.GetProperty("IdleWakeTimeout");
Console.WriteLine("Idle wake timeout: {0} minutes", IdleWakeTimeout.ToString());
return IdleWakeTimeout;
}
/// <summary>
/// The function will try to set the power package which
/// corresponds to the given schema GUID.
/// </summary>
/// <param name="guid">Power package GUID</param>
public void setPowerPackageBasedOnGuid(string schemaGuid)
{
Console.WriteLine("---------------Set Power Package Based on GUID--------------");
bool found = false;
IManagedReference computerSystemRef = wsmanClient.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='Intel(r) AMT'");
IManagedReference elementSettingDataRef = wsmanClient.NewReference("CIM_ElementSettingData");
elementSettingDataRef.AddSelector("ManagedElement", computerSystemRef);
//Traverse to the CIM_ElementSettingData instances that are connected to CIM_ComputerSystem.
foreach (IWsmanItem elementSettingDataItem in elementSettingDataRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
//For each instance, check if it is associated to the AMT_SystemPowerScheme instance.
if (elementSettingDataItem.Object.GetProperty("SettingData").IsA("AMT_SystemPowerScheme"))
{
// Get the AMT_systemPowerScheme object using its EPR.
IManagedInstance systemPowerSchemeInstance = elementSettingDataItem.Object.GetProperty("SettingData").Ref.Get();
IWsmanItem schemeGUID = systemPowerSchemeInstance.GetProperty("SchemeGUID");
if (schemeGUID.ToString().CompareTo(schemaGuid) == 0)
{
//set the power scheme....
IManagedReference systemPowerSchemeRef = elementSettingDataItem.Object.GetProperty("SettingData").Ref;
IManagedInstance inputObject = systemPowerSchemeRef.CreateMethodInput("SetPowerScheme");
IManagedInstance outputObject = systemPowerSchemeRef.InvokeMethod(inputObject);
IWsmanItem returnValue = outputObject.GetProperty("ReturnValue");
if (returnValue.ToString().CompareTo("0") == 0)
{
//print the details of the power scheme
Console.WriteLine("Instance ID: {0}", systemPowerSchemeInstance.GetProperty("InstanceID").ToString());
Console.WriteLine("Description: {0}\n", systemPowerSchemeInstance.GetProperty("Description").ToString());
Console.WriteLine("GUID: {0}", schemeGUID.ToString());
found = true;
break;
}
}
}
}
if (!found)
{
Console.WriteLine("Error occurred in function setPowerPackageBasedOnGuid.");
throw new WsmanException("The given GUID has no corresponding Power Package.");
}
}
/// <summary>
/// Find the current active power schema using enumerate with filter.
/// Note:
/// It is possible to iterate all the instances of CIM_ElementSettingData
/// and to check each one of them if it is connected to CIM_ComputerSystem
/// and to AMT_SystemPowerScheme and then check if the IsCurrent field
/// of the CIM_ElementSettingData is equal to 1. Doing it this way might
/// be easier but less efficient since there might be a lot of
/// CIM_ElementSettingData instances.
/// </summary>
public IManagedInstance getActivePowerSchema()
{
Console.WriteLine("---------------Get Current Active Power Package --------------");
//Not required to check for the firmware version as in the old Sample.
IManagedReference computerSystemRef = wsmanClient.NewReference("SELECT * FROM CIM_ComputerSystem WHERE Name='Intel(r) AMT'");
IManagedReference elementSettingDataRef = wsmanClient.NewReference("CIM_ElementSettingData");
elementSettingDataRef.AddSelector("ManagedElement", computerSystemRef);
//Traverse to the CIM_ElementSettingData instances that are connected to CIM_ComputerSystem.
foreach (IWsmanItem elementSettingDataItem in elementSettingDataRef.Enumerate("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter", null))
{
IWsmanItem isCurrent = elementSettingDataItem.Object.GetProperty("IsCurrent");
if (isCurrent.ToString() == "0" || isCurrent.ToString() == "2")
{
continue;
}
if (isCurrent.ToString() == "1")
{
//For each instance, check if it is associated to the AMT_SystemPowerScheme instance.
if (elementSettingDataItem.Object.GetProperty("SettingData").IsA("AMT_SystemPowerScheme"))
{
// Get the AMT_systemPowerScheme object using its EPR.
IManagedInstance systemPowerSchemeInstance = elementSettingDataItem.Object.GetProperty("SettingData").Ref.Get();
IWsmanItem schemeGUID = systemPowerSchemeInstance.GetProperty("SchemeGUID");
IWsmanItem instanceID = systemPowerSchemeInstance.GetProperty("InstanceID");
IWsmanItem description = systemPowerSchemeInstance.GetProperty("Description");
Console.WriteLine("Instance ID: {0}", instanceID.ToString());
Console.WriteLine("GUID: {0}", schemeGUID.ToString());
Console.WriteLine("Description: {0}", description.ToString());
return systemPowerSchemeInstance;
}
}
}
return null;
// else{}
}
#endregion PUBLIC_FUNCTION
}
}