1620 lines
73 KiB
C#
1620 lines
73 KiB
C#
//----------------------------------------------------------------------------
|
||
//
|
||
// Copyright © 2009-2014, Intel Corporation. All rights reserved.
|
||
//
|
||
// File: LogicLayer.cs
|
||
//
|
||
//----------------------------------------------------------------------------
|
||
|
||
using System;
|
||
using UCT.Forms;
|
||
using UCT.Utils;
|
||
using System.Text;
|
||
using System.Timers;
|
||
using System.Windows.Forms;
|
||
using System.Collections.Generic;
|
||
using System.Threading;
|
||
|
||
namespace UCT
|
||
{
|
||
/// <summary>
|
||
/// The main class - hold the logic behind the operations
|
||
/// </summary>
|
||
public class LogicLayer : IUserConsentFlow, IDisposable
|
||
{
|
||
#region - Dictionaries -
|
||
|
||
// OptInService Functions Statuses
|
||
Dictionary<uint, string> StatusCodes = new Dictionary<uint, string>()
|
||
{
|
||
{0, "Success"},
|
||
{1, "Internal error"},
|
||
{2, "Invalid state"},
|
||
{3, "Operation is blocked"},
|
||
{2066, "Invalid credentials"}
|
||
};
|
||
|
||
// Power state change return values
|
||
Dictionary<uint, string> PowerStatusCode = new Dictionary<uint, string>()
|
||
{
|
||
{0, "succuess"},
|
||
{1, "Operation is not supported"},
|
||
{2, "Unknown or unspecified error"},
|
||
{3, "Operation cannot be completed within timeout period"},
|
||
{4, "Operation failed"},
|
||
{5, "Invalid parameter"},
|
||
{6, "In use"},
|
||
{4099, "Invalid power transition"},
|
||
{4096, "Reserved"}
|
||
};
|
||
|
||
#endregion
|
||
|
||
#region - Consts -
|
||
|
||
// Hold the time (in minutes) required for detecting if sprite is supported
|
||
private const int SPRITE_SUPPORTED_TIMEOUT = 15;
|
||
|
||
#endregion
|
||
|
||
#region - Private Members -
|
||
|
||
// The GUI instance
|
||
private UserInterface _UI;
|
||
|
||
// The target system instance
|
||
private TargetSystem _targetSystem;
|
||
|
||
// Indicates if 15 seconds has elapsed when establishing if sprite is supported.
|
||
private bool _timeHadElapsed = false;
|
||
|
||
// Indicate if Sprite is suppported on the remote system
|
||
private bool _spriteIsSupported = false;
|
||
|
||
// Indicates if power operation was successful
|
||
private bool _powerOperationSucceed = false;
|
||
|
||
// Indicates if the previous optInState was 'in-session'.
|
||
private bool _isLastStateInSession;
|
||
|
||
// Reflects the result of the graceful shutdown
|
||
private bool _gracfulResult = false;
|
||
|
||
// Indicate whether the user cancel the progress bar
|
||
private bool _userCancel;
|
||
|
||
// Holds the optInState after connection was established.
|
||
// This is used for the code timer settings.
|
||
private int _firstStateUpdateAfterConnect = 0;
|
||
|
||
// Indicate whether the opt in state was changed
|
||
private bool _statusChanged = false;
|
||
|
||
// Indicate whether to reboot after shutdown or just log off
|
||
private bool _rebootAfterShutdown;
|
||
|
||
// Power operations timers
|
||
private System.Timers.Timer _timer, _timerBoot, _timerGraceful;
|
||
int _spriteCounter = 0, _bootCounter = 0;
|
||
|
||
// Hold the system power state
|
||
private PowerState _powerState;
|
||
|
||
#endregion
|
||
|
||
#region - Timer Events -
|
||
|
||
/// <summary>
|
||
/// Timer that running when executing graceful shutdown
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
void timerGraceful_Elapsed(object sender, ElapsedEventArgs e)
|
||
{
|
||
_timerGraceful.Enabled = false;
|
||
|
||
if (_rebootAfterShutdown)
|
||
{
|
||
WriteLog(LogLevel.BASIC, string.Format(Properties.Resources.EXECUTE_GRACEFUL_RESET_MESSAGE, Configuration.BasicSettings.GetInstance().AmtHost), LogInteraction.Information);
|
||
}
|
||
else
|
||
{
|
||
WriteLog(LogLevel.BASIC, string.Format(Properties.Resources.EXECUTE_GRACEFUL_SHUTDOWN_MESSAGE, Configuration.BasicSettings.GetInstance().AmtHost), LogInteraction.Information);
|
||
}
|
||
if (_targetSystem.PerfomGracefulShutDown(_rebootAfterShutdown))
|
||
{
|
||
_gracfulResult = true;
|
||
_UI.stopProgress = true;
|
||
_timerGraceful.Stop();
|
||
_timerGraceful.Close();
|
||
}
|
||
else
|
||
{
|
||
_UI.stopProgress = true;
|
||
_gracfulResult = false;
|
||
_timerGraceful.Stop();
|
||
_timerGraceful.Close();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Timer that running when detecting if sprite is supported
|
||
/// </summary>
|
||
/// <param name="source"></param>
|
||
/// <param name="e"></param>
|
||
private void OnShortTimedEvent(object source, ElapsedEventArgs e)
|
||
{
|
||
if (_spriteCounter < SPRITE_SUPPORTED_TIMEOUT)
|
||
{
|
||
_spriteCounter++;
|
||
OptInState state = _targetSystem.GetOptInState();
|
||
if (state == OptInState.Displayed)
|
||
{
|
||
WriteLog(LogLevel.DETAILED, string.Format(Properties.Resources.GETTING_OPT_IN_STATE_MESSAGE, state.ToString()), LogInteraction.FWOperation);
|
||
// Disable the timers
|
||
_spriteIsSupported = true;
|
||
_UI.stopProgress = true;
|
||
_timer.Stop();
|
||
_timer.Close();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_timeHadElapsed = true;
|
||
_UI.stopProgress = true;
|
||
_timer.Stop();
|
||
_timer.Close();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Timer that running when performing AMT reboot
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
void timerBoot_Elapsed(object sender, ElapsedEventArgs e)
|
||
{
|
||
_bootCounter++;
|
||
// Check if time had elapsed, or state was changed to the desired one.
|
||
if ((_bootCounter >= SPRITE_SUPPORTED_TIMEOUT) || (_targetSystem.GetPowerState() == _powerState))
|
||
{
|
||
_UI.stopProgress = true;
|
||
_timerBoot.Stop();
|
||
_timerBoot.Close();
|
||
}
|
||
}
|
||
|
||
public uint GetOptInTimeOut()
|
||
{
|
||
return _targetSystem.UctOperation.GetOptInTimeout();
|
||
}
|
||
|
||
public bool CheckOptInTimeoutSupport()
|
||
{
|
||
return (_targetSystem.UctOperation.CheckOptInTimeoutSupport());
|
||
}
|
||
|
||
public bool Check3DisplaysSupport()
|
||
{
|
||
return (_targetSystem.UctOperation.CheckThirdScreenSupport());
|
||
}
|
||
|
||
public bool CheckLinkProtectionSupport()
|
||
{
|
||
return (_targetSystem.WirelessOperation.CheckLinkProtectionSupport());
|
||
}
|
||
public void SetOptInTimeOut(uint time)
|
||
{
|
||
try
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Settings the Opt-In timeout to: " + time + "seconds",
|
||
LogInteraction.UserOperation, "Setting the Opt-In timeout to: " + time + " seconds");
|
||
_targetSystem.SetOptInTimeout(time);
|
||
_UI.DisplayStatusBar("Opt-In timeout was set successfully");
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the Opt-In timeout");
|
||
_UI.DisplayMessage("Set Opt-In timeout failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the Opt-In timeout");
|
||
_UI.DisplayMessage("Set Opt-In timeout failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Constructors and Design pattern methods -
|
||
|
||
/// <summary>
|
||
/// Constructor
|
||
/// </summary>
|
||
public LogicLayer()
|
||
{
|
||
_timer = new System.Timers.Timer();
|
||
_timerBoot = new System.Timers.Timer();
|
||
_timerGraceful = new System.Timers.Timer();
|
||
_timerBoot.Elapsed += new ElapsedEventHandler(timerBoot_Elapsed);
|
||
_timerGraceful.Elapsed += new ElapsedEventHandler(timerGraceful_Elapsed);
|
||
_timer.Elapsed += new ElapsedEventHandler(OnShortTimedEvent);
|
||
_timerBoot.Interval = 1000;
|
||
_timer.Interval = 1000; // Set the Interval to 1 second
|
||
_isLastStateInSession = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Register the GUI layer
|
||
/// </summary>
|
||
/// <param name="ui"></param>
|
||
public void RegisterUI(UserInterface ui)
|
||
{
|
||
_UI = ui;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Register the target system layer
|
||
/// </summary>
|
||
/// <param name="trs"></param>
|
||
public void RegisterTargetSystem(TargetSystem trs)
|
||
{
|
||
_targetSystem = trs;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Methods -
|
||
|
||
#region - Main Methods Flow -
|
||
|
||
/// <summary>
|
||
/// Canceling user consent
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public void CancelConsent()
|
||
{
|
||
try
|
||
{
|
||
// Writing relevant messages to log and status bar
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.CANCELING_USER_CONSENT_LOG_MESSAGE,
|
||
LogInteraction.UserOperation, Properties.Resources.CANCELING_USER_CONSENT_STATUS_BAR_MESSAGE);
|
||
|
||
// Check if cancel is allowed: i.e. if there is no Redirection of KVM open session.
|
||
OptInState oiState = _targetSystem.GetOptInState();
|
||
if (oiState == OptInState.InSession)
|
||
{
|
||
_UI.DisplayMessage(Properties.Resources.CANCEL_USER_CONSENT_IN_SESSION_MESSAGE, Properties.Resources.CANCEL_USER_CONSENT_PROGRESS_BAR_MESSAGE, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.CANCEL_USER_CONSNET_IN_SESSION_ERROR_MESSAGE,
|
||
LogInteraction.Error, "Cancel opertion failed");
|
||
return;
|
||
}
|
||
if (oiState == OptInState.NotStarted)
|
||
{
|
||
UpdateGUIMessages(LogLevel.DETAILED, "Invoking cancel consent is not required since the User Consent state is already 'NotStarted'",
|
||
LogInteraction.Information, "Cancel opertion completed successfully");
|
||
return;
|
||
}
|
||
CancelUserConsentProcess();
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
_UI.changeMouse(Cursors.Default);
|
||
_UI.DisplayMessage(string.Format(Properties.Resources.OPERATION_FAILED_ERROR_MESSAGE, ex.Message), Properties.Resources.OPERATION_FAILED, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, Properties.Resources.CANCEL_USER_CONSENT_FAILURE);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_UI.changeMouse(Cursors.Default);
|
||
_UI.DisplayMessage(ex.Message, Properties.Resources.OPERATION_FAILED, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, Properties.Resources.CANCEL_USER_CONSENT_FAILURE);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Canceling the user consent (include just the FW call, without the state checking)
|
||
/// </summary>
|
||
private void CancelUserConsentProcess()
|
||
{
|
||
_UI.changeMouse(Cursors.WaitCursor);
|
||
// Performing the cancel operation
|
||
uint res = _targetSystem.CancelConsent();
|
||
_UI.changeMouse(Cursors.Default);
|
||
if (res != 0)
|
||
{
|
||
_UI.DisplayMessage("Cancel consent operation failed with error code: " + res + " - " + StatusCodes[res], Properties.Resources.CANCEL_USER_CONSENT_FAILURE, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.CANCEL_USER_CONSENT_FAILURE_ERROR_CODE, res),
|
||
LogInteraction.Error, "Cancel operation failed");
|
||
}
|
||
else
|
||
{
|
||
_UI.DisplayStatusBar("Cancel operation completed successfully");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Start user consent flow
|
||
/// </summary>
|
||
public void StartConsent()
|
||
{
|
||
try
|
||
{
|
||
_UI.changeMouse(Cursors.WaitCursor);
|
||
RunFullFlow();
|
||
_UI.changeMouse(Cursors.Default);
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
_UI.changeMouse(Cursors.Default);
|
||
_UI.DisplayMessage(string.Format(Properties.Resources.OPERATION_FAILED_ERROR_MESSAGE, ex.Message), Properties.Resources.OPERATION_FAILED, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, Properties.Resources.STARTING_CONSNET_FAILED);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_UI.changeMouse(Cursors.Default);
|
||
_UI.DisplayMessage(Properties.Resources.UNKNOWN_ERROR, Properties.Resources.OPERATION_FAILED, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, Properties.Resources.STARTING_CONSNET_FAILED);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Sent the OptIn code
|
||
/// </summary>
|
||
/// <param name="code"></param>
|
||
public void SendCode(uint code)
|
||
{
|
||
try
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Sending the optInCode",
|
||
LogInteraction.UserOperation, "Sending the consent code...");
|
||
uint res = _targetSystem.SendCode(code);
|
||
|
||
if (res != 0)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Send User Consent code failed with error code: " + res,
|
||
LogInteraction.FWOperation, "Send consent code operation failed");
|
||
_UI.DisplayMessage("Send Code operation failed with error code: " + res + ", " + StatusCodes[res], "Operation Failed", MessageType.ERROR);
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Code was sent successfully, consent was obtained",
|
||
LogInteraction.FWOperation, "Code was sent successfully, consent was obtained");
|
||
_UI.DisplayMessage("Code was submitted successfully, consent was obtained.\nOperations that require consent can be performed.", "", MessageType.INFO);
|
||
}
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to send the consent code");
|
||
_UI.DisplayMessage("Send consent code failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Failed to send the consent code");
|
||
_UI.DisplayMessage("Send consent code failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Boot Methods -
|
||
|
||
/// <summary>
|
||
/// This method try to reboot the system, first gracefully (via OS), if failed - try AMT shutdown
|
||
/// </summary>
|
||
private void RebootSystem(LinkInterface linkInterface)
|
||
{
|
||
// Perform graceful shutdown just if the user ask for
|
||
if (Properties.Settings.Default.USE_GRACFUL_SHUTDOWN_BEFORE_AMT_REBOOT)
|
||
{
|
||
if (!PerformGracefulShutdown())
|
||
return;
|
||
|
||
// If we are connected over wireless interface, we must set the link preference to
|
||
// ME before reboot the system (otherwise, connection will lost), but because that graceful shutdown
|
||
// is a WinAPI command in order this command to success the link must be 'Host'.
|
||
// So we first send the graceful shutdown command and then start the loop of SetLinkPrefernce
|
||
if (linkInterface == LinkInterface.Wireless)
|
||
_targetSystem.StartLinkPreferenceThread(true);
|
||
|
||
// If the graceful operation failed - ask user if to reboot with AMT.
|
||
if (!_gracfulResult)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.GRACEFUL_SHUTDOWN_FAILED,
|
||
LogInteraction.Error, "Graceful reboot operation failed");
|
||
if (_UI.DisplayMessage(Properties.Resources.GRACEFUL_SHUTDOWN_MESSAGE_BOX_MESSAGE,
|
||
Properties.Resources.OPERATION_FAILED, MessageType.QUESTION) == DialogResult.Yes)
|
||
{
|
||
// Perform AMT Shutdown
|
||
if (!PerformAMTShutDown(PowerState.MasterBusReset))
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
UpdateGUIMessages(LogLevel.DETAILED, "Graceful reboot operation completed successfully",
|
||
LogInteraction.FWOperation, "Graceful reboot operation completed successfully");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Reboot when interface is wireless required set link preference to ME before executing the operation.
|
||
if (linkInterface == LinkInterface.Wireless)
|
||
_targetSystem.StartLinkPreferenceThread(true);
|
||
|
||
// Perform AMT Shutdown
|
||
if (!PerformAMTShutDown(PowerState.MasterBusReset))
|
||
return;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Execute graceful shutdown on the target system
|
||
/// </summary>
|
||
/// <param name="hasCancel">Indicate if the progress bar has 'Cancel' option, this button is used for cancel
|
||
/// the consent flow (e.g. reset the opt in state to NotStarted)</param>
|
||
/// <returns>true - continue the flow, false - abort the flow</returns>
|
||
public bool PerformGracefulShutdown(bool hasCancel, bool hasSkip, bool hasReboot)
|
||
{
|
||
try
|
||
{
|
||
// Indicate whether we need reboot after or not.
|
||
_rebootAfterShutdown = hasReboot;
|
||
|
||
// Update status bar and log
|
||
if (hasReboot)
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.GRACEFUL_REBOOT_LOG_MESSAGE,
|
||
LogInteraction.UserOperation, Properties.Resources.GRACEFUL_REBOOT_STATUS_BAR_MESSAGE);
|
||
else
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.GRACEFUL_SHUTDOWN_LOG_MESSAGE,
|
||
LogInteraction.UserOperation, Properties.Resources.GRACEFUL_SHUTDOWN_STATUS_BAR_MESSAGE);
|
||
|
||
// Reset all the progress bar properties to their default values
|
||
_UI.stopProgress = _gracfulResult = false;
|
||
|
||
// Start the graceful shutdown timer
|
||
_timerGraceful.Start();
|
||
DialogResult dResult;
|
||
if (hasReboot)
|
||
dResult = _UI.RunProgressBar(Properties.Resources.GRACEFUL_REBOOT_PROGRESS_BAR,
|
||
Properties.Resources.GRACEFUL_REBOOT_HEADER, hasCancel, hasSkip);
|
||
else
|
||
dResult = _UI.RunProgressBar(Properties.Resources.GRACEFUL_SHUTDOWN_PROGRESS_BAR,
|
||
Properties.Resources.GRACEFUL_SHUTDOWN_HEADER, hasCancel, hasSkip);
|
||
if (dResult != DialogResult.Cancel)
|
||
{
|
||
_timerGraceful.Stop();
|
||
_timerGraceful.Enabled = false;
|
||
UpdateGUIMessages(LogLevel.BASIC, "Reboot operation was canceled by the user",
|
||
LogInteraction.UserOperation, "Power operation was aborted");
|
||
_UI.stopProgress = true;
|
||
|
||
// Choosing 'Cancel' in the progress bar will cancel the flow (Skip - for stop the flow at this point)
|
||
if (dResult == DialogResult.Ignore)
|
||
{
|
||
CancelUserConsentProcess();
|
||
return false;
|
||
}
|
||
_UI.RefreshScreen();
|
||
}
|
||
if (!_gracfulResult)
|
||
{
|
||
_UI.DisplayStatusBar(hasReboot ? "Graceful reset failed" : "Graceful shutdown failed");
|
||
}
|
||
else
|
||
{
|
||
// Indicate the grageful shutdown succeed
|
||
if (hasReboot)
|
||
UpdateGUIMessages(LogLevel.BASIC, "Graceful reset completed successfully", LogInteraction.Information, "Graceful reset completed successfully");
|
||
else
|
||
UpdateGUIMessages(LogLevel.BASIC, "Graceful shutdown completed successfully", LogInteraction.Information, "Graceful shutdown completed successfully");
|
||
}
|
||
return true;
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
if (hasReboot)
|
||
{
|
||
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Graceful reset failed");
|
||
_UI.DisplayMessage("Graceful reset failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
else
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Graceful shutdown failed");
|
||
_UI.DisplayMessage("Graceful shutdown failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
if (hasReboot)
|
||
{
|
||
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Graceful reset failed");
|
||
_UI.DisplayMessage("Graceful reset failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
else
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Graceful shutdown failed");
|
||
_UI.DisplayMessage("Graceful shutdown failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Execute AMT shutdown on the target system
|
||
/// </summary>
|
||
/// <param name="hasCancel">Indicate if the progress bar has 'Cancel' option, this button is used for cancel
|
||
/// the consent flow (e.g. reset the opt in state to NotStarted)</param>
|
||
/// <returns>true - continue the flow, false - abort the flow</returns>
|
||
public bool PerformAMTShutDown(PowerState state, bool hasCancel, bool hasSkip)
|
||
{
|
||
try
|
||
{
|
||
// Update status bar and log
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.PERFORMING_POWER_OPERATION_LOG, state.ToString()),
|
||
LogInteraction.UserOperation, Properties.Resources.PERFORMING_POWER_OPERATION_STATUS_BAR);
|
||
|
||
// Reset all parameters to default values
|
||
_powerOperationSucceed = false;
|
||
_bootCounter = 0;
|
||
_powerState = state;
|
||
|
||
DialogResult dResult = DialogResult.Cancel;
|
||
|
||
Thread _thread = new Thread(new ThreadStart(()=>{
|
||
UserInterface _UI1 = new UserInterface();
|
||
// Display a progress bar until power state is changed, or 15 seconds had elapsed.
|
||
_timerBoot.Start();
|
||
_UI1.stopProgress = false;
|
||
dResult = _UI1.RunProgressBar("Performing power operation on the remote system...",
|
||
"Power Operation in progress", false, false);
|
||
}));
|
||
//end
|
||
_thread.Start();
|
||
|
||
// Execute the power operation
|
||
WriteLog(LogLevel.DETAILED, "AMT_AssociatedPoweManagerService.ChnagePowerState was executed", LogInteraction.FWOperation);
|
||
uint res = _targetSystem.ChangePowerState(state);
|
||
_powerOperationSucceed = res == 0 ? true : false;
|
||
|
||
_thread.Abort();
|
||
|
||
|
||
if (dResult != DialogResult.Cancel)
|
||
{
|
||
_timerBoot.Stop();
|
||
_timerBoot.Enabled = false;
|
||
_UI.stopProgress = true;
|
||
UpdateGUIMessages(LogLevel.BASIC, "Power operation was canceled by the user",
|
||
LogInteraction.UserOperation, "Power operation was aborted");
|
||
// Choosing 'Cancel' in the progress bar will cancel the flow (Skip - for stop the flow at this point)
|
||
if (dResult == DialogResult.Ignore)
|
||
{
|
||
CancelUserConsentProcess();
|
||
return false;
|
||
}
|
||
}
|
||
// Check if power operation failed
|
||
if (_powerOperationSucceed)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Power Operation: " + state.ToString() + " completed successfully",
|
||
LogInteraction.FWOperation, "Power operation completed successfully");
|
||
}
|
||
else
|
||
{
|
||
_UI.DisplayMessage("Power Operation failed with error code: " + res + ", " +
|
||
(PowerStatusCode.ContainsKey(res) ? PowerStatusCode[res] : PowerStatusCode[2]),
|
||
"Power Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Graceful shutdown failed");
|
||
_UI.DisplayMessage("Power operation failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error, "Graceful shutdown failed");
|
||
_UI.DisplayMessage("Power operation failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
_UI.RefreshScreen();
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Utils Methods
|
||
|
||
/// <summary>
|
||
/// Change the connection address (used when changing the host name via the combo box)
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
internal bool ChangeConnectionAddress()
|
||
{
|
||
try
|
||
{
|
||
// Update log and status bar
|
||
UpdateGUIMessages(LogLevel.BASIC, "Connecting to: " + Configuration.GetInstance().Basic.AmtHost,
|
||
LogInteraction.UserOperation, "Connecting to the remote system...");
|
||
// Try to establish connection
|
||
if (Configuration.GetInstance().InitWSManClient() != UCT.ConnectionStatus.Connected)
|
||
return false;
|
||
if (CertificateUtils.ValidateCertificate())
|
||
{
|
||
SetDefaultValues();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
// Connection failed
|
||
catch (Exception e)
|
||
{
|
||
// Update log and status bar
|
||
UpdateGUIMessages(LogLevel.BASIC, "Exception was thrown: " + e.Message,
|
||
LogInteraction.Error, "Failed to connect to the remote system");
|
||
_targetSystem.StartPolling(false);
|
||
SetApplicationToUnknown();
|
||
_UI.DisplayMessage(e.Message, "Failed to connect to the remote system", MessageType.ERROR);
|
||
_UI.connectionState = ConnectionState.DISCONNECTED;
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.DISCONNECTED);
|
||
_UI.RefreshScreen();
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the application to its default values
|
||
/// </summary>
|
||
public void SetDefaultValues()
|
||
{
|
||
try
|
||
{
|
||
_targetSystem.SetDefaultOptInState();
|
||
_targetSystem.SetDefaultPowerState();
|
||
_isLastStateInSession = false;
|
||
_targetSystem.StartPolling(true);
|
||
_firstStateUpdateAfterConnect = 0;
|
||
UpdateGUIMessages(LogLevel.BASIC, "Successfully Connected to: " + Configuration.GetInstance().Basic.AmtHost,
|
||
LogInteraction.Connection, "Connected to the remote system");
|
||
_UI.connectionState = ConnectionState.CONNECTED;
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()),
|
||
LogInteraction.Error);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get the statistics tab information
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public Dictionary<string, string> GetStatisticsParams()
|
||
{
|
||
WriteLog(LogLevel.BASIC, "Getting connection parameters", LogInteraction.FWOperation);
|
||
return _targetSystem.GetConnectionParameters();
|
||
}
|
||
|
||
/// <summary>
|
||
/// Open the log file (in notepad)
|
||
/// </summary>
|
||
public void ViewLog()
|
||
{
|
||
try
|
||
{
|
||
LogManager.GetInstance().ViewLogFile();
|
||
|
||
}
|
||
catch (UCTException e)
|
||
{
|
||
_UI.DisplayMessage(e.Message, "Failed to open the Log", MessageType.ERROR);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Write a line to the log
|
||
/// </summary>
|
||
/// <param name="level"></param>
|
||
/// <param name="message"></param>
|
||
/// <param name="interaction"></param>
|
||
public void WriteLog(LogLevel level, string message, LogInteraction interaction)
|
||
{
|
||
try
|
||
{
|
||
// Adding the operation details to the log file
|
||
StringBuilder line = LogManager.WriteOperation(level, message, interaction);
|
||
|
||
if (line.ToString() != String.Empty)
|
||
{
|
||
// Adding the operation details to the log viewer
|
||
_UI.WriteToLog(line.ToString(), interaction);
|
||
}
|
||
}
|
||
catch (Exception) { }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Update the GUI - write the current operation to the log and status bar
|
||
/// </summary>
|
||
/// <param name="logLevel"></param>
|
||
/// <param name="logMessage"></param>
|
||
/// <param name="logInteraction"></param>
|
||
/// <param name="statusbarMessage"></param>
|
||
private void UpdateGUIMessages(LogLevel logLevel, string logMessage, LogInteraction logInteraction, string statusbarMessage)
|
||
{
|
||
WriteLog(logLevel, logMessage, logInteraction);
|
||
_UI.DisplayStatusBar(statusbarMessage);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check if meanwhile, the consent state changed to disconnect
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private bool EnsureRelevantState()
|
||
{
|
||
if (_targetSystem.GetOptInState() == OptInState.Displayed)
|
||
{
|
||
_UI.DisplayMessage("This operation is not necessary since the consent state already changed to display.\nOperation aborted", "Information", MessageType.INFO);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region - Polling Methods -
|
||
|
||
/// <summary>
|
||
/// This is the main function - once the opt in state property is changed, this method is called
|
||
/// </summary>
|
||
/// <param name="state"></param>
|
||
public void UpdateOptInState(OptInState state)
|
||
{
|
||
try
|
||
{
|
||
_UI.SetOptInState(state);
|
||
|
||
// The first state is not 'NotStarted' - the timer should be disable (Display warning?)
|
||
if (_firstStateUpdateAfterConnect++ == 0 && (state == OptInState.Received || state == OptInState.Displayed || state == OptInState.Requested))
|
||
{
|
||
// The first machine state is Display/Recieve/Requested
|
||
_UI.SetTimerState(TimerStatus.DISABLE);
|
||
_UI.ChangeTimerNote("The Timer cannot be set at this state");
|
||
}
|
||
else
|
||
{
|
||
switch (state)
|
||
{
|
||
case OptInState.Unknown:
|
||
{
|
||
_UI.SetTimerState(TimerStatus.DISABLE);
|
||
_UI.ChangeTimerNote(string.Empty);
|
||
break;
|
||
}
|
||
case OptInState.NotStarted:
|
||
{
|
||
_UI.SetTimerState(TimerStatus.DISABLE);
|
||
_UI.ChangeTimerNote("Timer is activated once the consent code is recieved");
|
||
break;
|
||
}
|
||
case OptInState.Requested:
|
||
{
|
||
_UI.ChangeTimerNote("Consent code expiration timeout started");
|
||
break;
|
||
}
|
||
case OptInState.Displayed:
|
||
{
|
||
_UI.ChangeTimerNote("Consent code expiration timeout started");
|
||
break;
|
||
}
|
||
case OptInState.InSession:
|
||
{
|
||
// Time is not running but its value is 15
|
||
_UI.SetTimerState(TimerStatus.FREEZE);
|
||
_UI.ChangeTimerNote("Timer is reset when a session is opened");
|
||
break;
|
||
}
|
||
case OptInState.Received:
|
||
{
|
||
// If the previous state was "InSession" - timer is start for the beginning
|
||
_UI.SetTimerState(TimerStatus.RUN);
|
||
_UI.ChangeTimerNote(string.Empty);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
switch (state)
|
||
{
|
||
case OptInState.Unknown:
|
||
SetApplicationToUnknown();
|
||
break;
|
||
case OptInState.InSession:
|
||
SetApplicationToInSession();
|
||
break;
|
||
case OptInState.NotStarted:
|
||
SetApplicationToNotStarted();
|
||
break;
|
||
case OptInState.Requested:
|
||
SetApplicationToRequested();
|
||
break;
|
||
case OptInState.Displayed:
|
||
SetApplicationToDisplayed();
|
||
break;
|
||
case OptInState.Received:
|
||
SetApplicationToRecieved();
|
||
break;
|
||
}
|
||
// Update this value to indicate if last state was in-session. this is used to setup the code timer.
|
||
_isLastStateInSession = (state == OptInState.InSession) ? true : false;
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
_UI.SetPowerState(PowerState.Unknown);
|
||
_UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR);
|
||
WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation);
|
||
_UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the tool to 'Unknown' state
|
||
/// </summary>
|
||
public void SetApplicationToUnknown()
|
||
{
|
||
if (!_statusChanged)
|
||
{
|
||
_UI.DisplayStatusBar("Not Connected");
|
||
WriteLog(LogLevel.BASIC, "Connection to: " + Configuration.BasicSettings.GetInstance().AmtHost + " was lost", LogInteraction.Error);
|
||
// Stop the polling properties
|
||
_targetSystem.StartPolling(false);
|
||
// Change statistics to 'Not - Available'
|
||
_UI.InitStatisticsTab(false);
|
||
// Changed the connection icon indication
|
||
_UI.ChangeConnectionIcon(false);
|
||
// Disable tab operations
|
||
_UI.InitOperationTab(false);
|
||
// Disable start / cancel buttons
|
||
_UI.ChangeMainButtonsStatus(false);
|
||
// Disable advance tab
|
||
_UI.InitAdvancedTab(false);
|
||
// Change the power state label
|
||
_UI.ChangePowerStateLabel(false);
|
||
// Stop the timer
|
||
_UI.SetTimerState(TimerStatus.DISABLE);
|
||
// Change the GUI to indicate disconnection
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.DISCONNECTED);
|
||
_UI.SetConnectioDetailsToUnknown(false);
|
||
_statusChanged = true;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the tool to 'Not Started' state
|
||
/// </summary>
|
||
private void SetApplicationToNotStarted()
|
||
{
|
||
WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Not Started'", LogInteraction.FWOperation);
|
||
// Enable the main button
|
||
_UI.SetStartCancelButtonState(true);
|
||
// Enable start / cancel buttons
|
||
_UI.ChangeMainButtonsStatus(true);
|
||
// Start the polling properties
|
||
_targetSystem.StartPolling(true);
|
||
// Update statistics
|
||
_UI.InitStatisticsTab(true);
|
||
// Changed the connection icon indication
|
||
_UI.ChangeConnectionIcon(true);
|
||
// Disable tab operations
|
||
_UI.InitOperationTab(false);
|
||
// Enable advance tab
|
||
_UI.InitAdvancedTab(true);
|
||
// Change the GUI controls to indicate connection
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED);
|
||
// Stop the link preference polling
|
||
_targetSystem.StartLinkPreferenceThread(false);
|
||
_statusChanged = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the tool to 'Displayed' state
|
||
/// </summary>
|
||
private void SetApplicationToDisplayed()
|
||
{
|
||
WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Requested'", LogInteraction.FWOperation);
|
||
// Start polling
|
||
_targetSystem.StartPolling(true);
|
||
// Set the main button to 'Cancel'
|
||
_UI.SetStartCancelButtonState(false);
|
||
// Update statistics
|
||
_UI.InitStatisticsTab(true);
|
||
// Init operation tab
|
||
_UI.InitOperationTab(true);
|
||
// Move the focus to the code control
|
||
_UI.MoveFocousToCodeFrame();
|
||
// Changed the connection icon indication
|
||
_UI.ChangeConnectionIcon(true);
|
||
// Enable start / cancel buttons
|
||
_UI.ChangeMainButtonsStatus(true);
|
||
// Enable advance tab
|
||
_UI.InitAdvancedTab(true);
|
||
// Change the GUI to indicate connection
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED);
|
||
_statusChanged = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the tool to 'Requested' state
|
||
/// </summary>
|
||
private void SetApplicationToRequested()
|
||
{
|
||
WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Requested'", LogInteraction.FWOperation);
|
||
// Start (continue...) the polling
|
||
_targetSystem.StartPolling(true);
|
||
// Change the main button to cancel
|
||
_UI.SetStartCancelButtonState(false);
|
||
// Update statistics
|
||
_UI.InitStatisticsTab(true);
|
||
// Changed the connection icon indication
|
||
_UI.ChangeConnectionIcon(true);
|
||
// Disable tab operations
|
||
_UI.InitOperationTab(false);
|
||
// Enable start / cancel buttons
|
||
_UI.ChangeMainButtonsStatus(true);
|
||
// Enable advance tab
|
||
_UI.InitAdvancedTab(true);
|
||
// Change the GUI to indiacte connection
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED);
|
||
_statusChanged = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the tool to 'Recieved' state
|
||
/// </summary>
|
||
private void SetApplicationToRecieved()
|
||
{
|
||
WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'Received'", LogInteraction.FWOperation);
|
||
// Start the polling
|
||
_targetSystem.StartPolling(true);
|
||
// Set the main button to cancel
|
||
_UI.SetStartCancelButtonState(false);
|
||
// Update statistics
|
||
_UI.InitStatisticsTab(true);
|
||
// Changed the connection icon indication
|
||
_UI.ChangeConnectionIcon(true);
|
||
// Disable tab operations
|
||
_UI.ChangeSendCodeStatus(false);
|
||
// Enable start / cancel buttons
|
||
_UI.ChangeMainButtonsStatus(true);
|
||
// Enable advanced tab
|
||
_UI.InitAdvancedTab(true);
|
||
// Change the GUI to indicate connection
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED);
|
||
_statusChanged = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the tool to 'In Session' state
|
||
/// </summary>
|
||
private void SetApplicationToInSession()
|
||
{
|
||
WriteLog(LogLevel.DETAILED, "OptInState was Changed to 'In-Session'", LogInteraction.FWOperation);
|
||
// Start (continue...) the polling
|
||
_targetSystem.StartPolling(true);
|
||
// Set the main button to enable
|
||
_UI.SetStartCancelButtonState(false);
|
||
// Update statistics
|
||
_UI.InitStatisticsTab(true);
|
||
// Changed the connection icon indication
|
||
_UI.ChangeConnectionIcon(true);
|
||
// Disable tab operation - BUT NOT THE CLOCK
|
||
_UI.ChangeSendCodeStatus(false);
|
||
// Enable start / cancel buttons
|
||
_UI.ChangeMainButtonsStatus(true);
|
||
// Enable advance tab
|
||
_UI.InitAdvancedTab(true);
|
||
// Change the GUI to indicate connection
|
||
_UI.ChangeGuiToDisconnect(ConnectionState.CONNECTED);
|
||
_statusChanged = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Update the power state label
|
||
/// </summary>
|
||
/// <param name="ps"></param>
|
||
public void UpdatePowerState(PowerState ps)
|
||
{
|
||
try
|
||
{
|
||
_UI.SetPowerState(ps);
|
||
// Update the power state combo-box
|
||
_UI.FillOperationOptions(ps);
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
_UI.SetPowerState(PowerState.Unknown);
|
||
_UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR);
|
||
WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_UI.SetPowerState(PowerState.Unknown);
|
||
_UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR);
|
||
WriteLog(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite.ToString()), LogInteraction.FWOperation);
|
||
}
|
||
}
|
||
public OptInState CheckOptInState()
|
||
{
|
||
return _targetSystem.GetOptInState();
|
||
}
|
||
#endregion
|
||
|
||
#region - Target system method -
|
||
|
||
#region - Wireless Methods -
|
||
|
||
/// <summary>
|
||
/// Set the link preference
|
||
/// </summary>
|
||
/// <param name="link"></param>
|
||
/// <param name="timeout"></param>
|
||
internal void SetLinkPreference(LinkControl link, uint timeout)
|
||
{
|
||
try
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format("Setting the link preference to: {0} {1}", link,
|
||
(link == LinkControl.ME) ? " for " + timeout + " seconds" : string.Empty),
|
||
LogInteraction.UserOperation, "Setting the link preference to " + link + "...");
|
||
uint res = _targetSystem.SetLinkPreference(link, timeout);
|
||
if (res != 0)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "SetLinkPreference failed with error code: " + res,
|
||
LogInteraction.Error, "Failed to set the link preference");
|
||
}
|
||
else
|
||
{
|
||
_UI.DisplayStatusBar("Link preference was set successfully");
|
||
_targetSystem.WirelessOperation.GetWirelessLinkState(this);
|
||
}
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
_UI.DisplayMessage("Setting the link preference failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the link preference");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_UI.DisplayMessage(String.Format(Properties.Resources.EXCEPTION_WAS_THROWN, ex.Message), "Operation Failed", MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the link preference");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Update the wireless details (link control, lan id ect.)
|
||
/// </summary>
|
||
/// <param name="linkControl"></param>
|
||
/// <param name="linkPreference"></param>
|
||
internal void UpdateWirelessDetails(LinkControl linkControl, LinkControl linkPreference)
|
||
{
|
||
try
|
||
{
|
||
_UI.SetWirelessDetails(linkControl, linkPreference);
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
_UI.SetPowerState(PowerState.Unknown);
|
||
_UI.DisplayMessage(ex.Message, "Operation Failed", MessageType.ERROR);
|
||
WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_UI.SetPowerState(PowerState.Unknown);
|
||
WriteLog(LogLevel.DETAILED, String.Format(Properties.Resources.EXCEPTION_WAS_THROWN, ex.Message),
|
||
LogInteraction.Error);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// Set the default screens
|
||
/// </summary>
|
||
/// <param name="screen"></param>
|
||
public void ChangeDefaultScreen(DefaultScreen screen)
|
||
{
|
||
try
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Settings the default monitor to: " + Utilities.GetEnumDescription(screen),
|
||
LogInteraction.UserOperation, "Setting the default screen to: " + Utilities.GetEnumDescription(screen));
|
||
_targetSystem.SetDefaultMonitor(screen);
|
||
_UI.DisplayStatusBar("Default screen was set successfully");
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the default screen");
|
||
_UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the default screen");
|
||
_UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Switch screens
|
||
/// </summary>
|
||
public void SetDefaultMonitor()
|
||
{
|
||
try
|
||
{
|
||
_targetSystem.SetDefaultMonitor();
|
||
_UI.DisplayStatusBar("Set default monitor completed successfully");
|
||
|
||
}
|
||
catch (UCTException ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the default monitor");
|
||
_UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, String.Format(Properties.Resources.EXCEPTION_OCCURED_ERROR_CODE, ex.Message, ex.TargetSite),
|
||
LogInteraction.Error, "Failed to set the default monitor");
|
||
_UI.DisplayMessage("Set default monitor failed with exception: " + ex.Message, "Operation Failed", MessageType.ERROR);
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region IUserConsentFlow Members
|
||
|
||
public bool CheckIfConsentIsRequired()
|
||
{
|
||
if (_targetSystem.GetOptInPolicy() == OptInPolicy.NONE)
|
||
{
|
||
_UI.DisplayMessage(Properties.Resources.USER_CONSENT_NOT_REQUIRED, Properties.Resources.OPERATION_FAILED, MessageType.INFO);
|
||
UpdateGUIMessages(LogLevel.DETAILED, Properties.Resources.USER_CONSNET_LOG_NOT_REQUIRED,
|
||
LogInteraction.Information, "Consent is not required for any operation");
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public bool CheckIfConsentAlreadyObtain()
|
||
{
|
||
// Get the User Consent state
|
||
OptInState state = _targetSystem.GetOptInState();
|
||
|
||
// If state is In-Session - indicate the user and exit the flow
|
||
if (state == OptInState.InSession)
|
||
{
|
||
_UI.DisplayMessage(Properties.Resources.USER_CONSENT_OPEN_SESSION, Properties.Resources.OPERATION_FAILED, MessageType.INFO);
|
||
UpdateGUIMessages(LogLevel.DETAILED, "Consent was already obtained - a KVM or Redirection session is open",
|
||
LogInteraction.Information, "Consent was already obtained");
|
||
return true;
|
||
}
|
||
// If state is Recieved - indicate the user that consent was already obtained and exit the flow
|
||
if (state == OptInState.Received)
|
||
{
|
||
_UI.DisplayMessage(Properties.Resources.USER_CONSENT_ALREADY_OBTAINED, Properties.Resources.OPERATION_FAILED, MessageType.INFO);
|
||
UpdateGUIMessages(LogLevel.DETAILED, Properties.Resources.USER_CONSENT_ALREADY_OBTAINED_LOG,
|
||
LogInteraction.Information, "Consent was already obtained");
|
||
return true;
|
||
}
|
||
// Any other state (except "Not Started") - reset the flow using cancel operation
|
||
if (state != OptInState.NotStarted)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Reseting the User Consent state in order to start the consent process",
|
||
LogInteraction.Information, Properties.Resources.RESETING_USER_CONSENT);
|
||
// Cancel the consent flow
|
||
uint result = _targetSystem.CancelConsent();
|
||
if (result != 0)
|
||
{
|
||
UpdateGUIMessages(LogLevel.DETAILED, string.Format(Properties.Resources.CANCEL_USER_CONSENT_FAILURE_ERROR_CODE, result),
|
||
LogInteraction.Error, "Failed to reset the consent state");
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public void PerformSxFlow()
|
||
{
|
||
if (!StartUserConsentProcess())
|
||
return;
|
||
|
||
// Ask the user if he want the tool to reboot the system
|
||
if (_UI.DisplayMessage("The target system is in Sx power state.\nA boot is needed in order to display the consent form.\nWould you like to boot the system?",
|
||
Properties.Resources.BOOTING_SYSTEM_MESSAGE, MessageType.QUESTION) == DialogResult.Yes)
|
||
{
|
||
_UI.RefreshScreen();
|
||
|
||
// Check if meanwhile the state changed to display
|
||
if (!EnsureRelevantState())
|
||
return;
|
||
|
||
_UI.RefreshScreen();
|
||
|
||
// Perform power operation (graceful and force)
|
||
PerformAMTShutDown(PowerState.On);
|
||
}
|
||
else
|
||
{
|
||
//Check if meanwhile the machine state changed to 'Display' (= the user woke up the machine)
|
||
if (_targetSystem.GetOptInState() != OptInState.Displayed)
|
||
{
|
||
_UI.DisplayMessage("In order to complete the consent process, please turn-on the target system.\nYou can ask the user to perform it localy, or use the advanced tab operations to perform it remotely. ", "Information Message", MessageType.INFO);
|
||
UpdateGUIMessages(LogLevel.DETAILED, "Power operation was aborted",
|
||
LogInteraction.UserOperation, "Power operation was aborted.");
|
||
}
|
||
}
|
||
}
|
||
|
||
public bool StartUserConsentProcess()
|
||
{
|
||
// Start the consent process
|
||
uint result = _targetSystem.StartConsent();
|
||
if (result != 0)
|
||
{
|
||
_UI.DisplayMessage("Start consent operation failed with error code: " + result + " - " + StatusCodes[result], Properties.Resources.STARTING_CONSNET_FAILED, MessageType.ERROR);
|
||
UpdateGUIMessages(LogLevel.BASIC, string.Format(Properties.Resources.STARTING_USER_CONSENT_FAILED_ERROR_CODE, result.ToString()),
|
||
LogInteraction.Error, "Start consent operation failed");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public void DetectingIfSpriteIsSupported()
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.DETECTING_SPRITE_LOG_MESSAGE,
|
||
LogInteraction.FWOperation, Properties.Resources.DETECTING_SPRITE_MESSAGE + "...");
|
||
_timer.Start();
|
||
|
||
_UI.stopProgress = false;
|
||
_UI.RefreshScreen();
|
||
|
||
// Detecting if sprite is supported, that may take up to 15 seconds.
|
||
// A timer is set to indicate this time had elapsed.
|
||
DialogResult dialogResult = _UI.RunProgressBar(Properties.Resources.DETECTING_SPRITE_MESSAGE + " (may take up to 15 sec.)",
|
||
Properties.Resources.DETECTING_SPRITE_MESSAGE, true, false);
|
||
|
||
if (dialogResult != DialogResult.Cancel)
|
||
{
|
||
_timer.Stop();
|
||
_UI.stopProgress = _timer.Enabled = false;
|
||
|
||
_UI.RefreshScreen();
|
||
// If user choose 'Skip' or 'cancel' at the Sprite detection progress bar - just stop the detection
|
||
// the button of 'Skip' removed , so the 'cancel' behave as the 'skip'
|
||
if (dialogResult == DialogResult.Abort || dialogResult == DialogResult.Ignore)
|
||
{
|
||
_userCancel = true;
|
||
UpdateGUIMessages(LogLevel.DETAILED, "Detection if sprite is supported was caceled", LogInteraction.UserOperation, "Detection if sprite is supported was caceled");
|
||
return;
|
||
}
|
||
}
|
||
if (!_timeHadElapsed)
|
||
_userCancel = true;
|
||
|
||
_UI.RefreshScreen();
|
||
while ((!_timeHadElapsed) && (!_spriteIsSupported) && (!_userCancel)) ;
|
||
}
|
||
|
||
public void ExecuteWirelessFlow()
|
||
{
|
||
// Check if AMT's wireless link is passive.
|
||
// If true returned - indicate that control link = ME, just perform reboot
|
||
if (!_targetSystem.CheckAMTWirelessLink())
|
||
{
|
||
// Get the wireless profiles state
|
||
WirelessProfilesState wirelessState = _targetSystem.GetWirelessProfilesState();
|
||
|
||
// Wireless profiles does not exist - indicate the user and stop the flow
|
||
if (wirelessState == WirelessProfilesState.None)
|
||
{
|
||
if (_UI.DisplayWarningMessage("The target system does not have wireless profiles, flow cannot be executed.", "Wireless Flow Aborted", MessageBoxButtons.OK) == DialogResult.OK)
|
||
{
|
||
_UI.RefreshScreen();
|
||
CancelUserConsentProcess();
|
||
}
|
||
UpdateGUIMessages(LogLevel.BASIC, "No wireless profile defined, Wireless flow aborted", LogInteraction.Error, "Wireless flow aborted");
|
||
return;
|
||
}
|
||
// Check if there is SSID match between AMT's profiles and host profile
|
||
if (!_targetSystem.CheckConnectionBetweenProfiles())
|
||
{
|
||
// The target system include only IT profiles, flow cannot be executed
|
||
if (wirelessState == WirelessProfilesState.ITProfiles)
|
||
{
|
||
_UI.DisplayWarningMessage("The target system does not have user profiles defined, flow cannot be executed.", "Wireless Flow Aborted", MessageBoxButtons.OK);
|
||
UpdateGUIMessages(LogLevel.BASIC, "No wireless profile defined, Wireless flow aborted", LogInteraction.Error, "Wireless flow aborted");
|
||
return;
|
||
}
|
||
// No match between profiles - indicate the user about the risk
|
||
if (_UI.DisplayMessage("LANID doesn't match SSID and only user profiles exist, hence the flow may fail.\nDo you wish to continue?", "Wireless Flow",
|
||
MessageType.QUESTION) == DialogResult.No)
|
||
{
|
||
// User don't want to continue the flow - abort
|
||
UpdateGUIMessages(LogLevel.BASIC, "Wireless profile does not match, Wireless flow aborted", LogInteraction.Error, "Wireless flow aborted");
|
||
|
||
// Cancel the flow
|
||
CancelUserConsentProcess();
|
||
return;
|
||
}
|
||
}
|
||
DialogResult dResult;
|
||
uint protectionLevel = _targetSystem.GetLinkProtectionLevel();
|
||
if (protectionLevel == 0) // Override
|
||
{
|
||
if ((dResult = _UI.DisplayWarningMessage("The Intel AMT system must be rebooted to display a user consent code.\n" +
|
||
"To remain connected via a wireless connection during reboot,\n" +
|
||
"link protection must be restored " +
|
||
"\nSelect one of the following options:\n" +
|
||
"Yes – Restore the link protection and reboot the system.\n" +
|
||
"No – Restore the link protection and do NOT reboot the system.\n" +
|
||
"Cancel – Cancel the user consent process (make no changes).", "Wireless Flow Notification",
|
||
MessageBoxButtons.YesNoCancel)) == DialogResult.Cancel)
|
||
{
|
||
_UI.RefreshScreen();
|
||
|
||
// User choose to cancel the flow - exits the flow at this point, not setting the link preference and not boot
|
||
UpdateGUIMessages(LogLevel.BASIC, "Consent flow was canceled by the user", LogInteraction.UserOperation, "Consent flow was canceled");
|
||
CancelUserConsentProcess();
|
||
return;
|
||
}
|
||
// Check if meanwhile the state changed to display
|
||
if (!EnsureRelevantState())
|
||
return;
|
||
|
||
_targetSystem.RestoreLinkProtection();
|
||
// No- indicates the user don't want to reboot the system,
|
||
// so we just restored the link protection (for the case the user will use the discrete operation to reboot)
|
||
if (dResult == DialogResult.No)
|
||
{
|
||
return;
|
||
}
|
||
else // Reboot the syetem
|
||
{
|
||
RebootSystem(LinkInterface.Wireless);
|
||
}
|
||
}
|
||
else // None
|
||
{
|
||
// Notify the user about the link preference
|
||
if ((dResult = _UI.DisplayWarningMessage("The Intel AMT system must be rebooted to display a user consent code.\n" +
|
||
"To remain connected via a wireless connection during reboot,\n" +
|
||
"control of network connections on the system must be passed to the Intel AMT Manageability Engine " +
|
||
"(by changing the 'Link Preference' of the Intel AMT system to 'ME').\n" +
|
||
"\nSelect one of the following options:\n" +
|
||
"Yes – Set the link preference to ME and reboot the system.\n" +
|
||
"No – Set the link preference to ME and do NOT reboot the system.\n" +
|
||
"Cancel – Cancel the user consent process (make no changes).", "Wireless Flow Notification",
|
||
MessageBoxButtons.YesNoCancel)) == DialogResult.Cancel)
|
||
{
|
||
_UI.RefreshScreen();
|
||
|
||
// User choose to cancel the flow - exits the flow at this point, not setting the link preference and not boot
|
||
UpdateGUIMessages(LogLevel.BASIC, "Consent flow was canceled by the user", LogInteraction.UserOperation, "Consent flow was canceled");
|
||
CancelUserConsentProcess();
|
||
return;
|
||
}
|
||
// Check if meanwhile the state changed to display
|
||
if (!EnsureRelevantState())
|
||
return;
|
||
|
||
// No indicates the user don't want to reboot the system,
|
||
// so we just set the link preference (for the case the user will use the discrete operation to reboot)
|
||
if (dResult == DialogResult.No)
|
||
{
|
||
_targetSystem.StartLinkPreferenceThread(true);
|
||
return;
|
||
}
|
||
RebootSystem(LinkInterface.Wireless);
|
||
}
|
||
}
|
||
else // Reboot the syetem
|
||
{
|
||
if (_UI.DisplayMessage(Properties.Resources.SPRITE_NOT_AVAILIBLE_MESSAGE_BOX_MESSAGE,
|
||
Properties.Resources.QUESTION_HEADER, MessageType.QUESTION) == DialogResult.Yes)
|
||
{
|
||
// Check if meanwhile the state changed to display
|
||
if (!EnsureRelevantState())
|
||
return;
|
||
|
||
RebootSystem(LinkInterface.Wireless);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void ExecuteNonSpriteFlow()
|
||
{
|
||
// Check the system power state - because it needs to be s0 for this flow to continue.
|
||
if (_targetSystem.GetPowerState() != PowerState.On)
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.POWER_ON_MESSAGE,
|
||
LogInteraction.Information, Properties.Resources.POWER_ON_MESSAGE);
|
||
|
||
_UI.RefreshScreen();
|
||
|
||
if (_UI.DisplayMessage(Properties.Resources.POWER_ON_MESSAGE_BOX_MESSAGE +
|
||
"\n\nNote that if you choose 'No', in order to complete the consent process, you have to boot the target system." +
|
||
"\nYou can ask the user to perform it localy, or use the advanced tab operations to perform it remotely.",
|
||
Properties.Resources.BOOTING_SYSTEM_MESSAGE, MessageType.QUESTION) == DialogResult.Yes)
|
||
{
|
||
// Check if meanwhile the state changed to display
|
||
if (!EnsureRelevantState())
|
||
return;
|
||
|
||
// Power on the system
|
||
PerformAMTShutDown(PowerState.On);
|
||
}
|
||
}
|
||
// System is on and needs to be re-booted
|
||
else
|
||
{
|
||
// First try graceful shutdown - via OS, if failed try AMT reboot.
|
||
if (_UI.DisplayMessage(Properties.Resources.SPRITE_NOT_AVAILIBLE_MESSAGE_BOX_MESSAGE,
|
||
Properties.Resources.QUESTION_HEADER, MessageType.QUESTION) == DialogResult.Yes)
|
||
{
|
||
// Check if meanwhile the state changed to display
|
||
if (!EnsureRelevantState())
|
||
return;
|
||
|
||
RebootSystem(LinkInterface.Wired);
|
||
}
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.MEBx_USER_CONSENT_MESSAGE,
|
||
LogInteraction.Information, Properties.Resources.MEBx_USER_CONSENT_MESSAGE);
|
||
|
||
}
|
||
}
|
||
|
||
public void RunFullFlow()
|
||
{
|
||
bool wasSxFlow = false;
|
||
// Reseting all arguments to default
|
||
_timeHadElapsed = _spriteIsSupported = _userCancel = false;
|
||
_spriteCounter = 0;
|
||
|
||
// Update log and status bar
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.STARTING_USER_CONSENT_LOG_MESSAGE,
|
||
LogInteraction.UserOperation, Properties.Resources.STARTING_USER_CONSENT_PROGRESS_BAR_MESSAGE);
|
||
|
||
// 1) Check if consent is required
|
||
if (!CheckIfConsentIsRequired())
|
||
return;
|
||
|
||
// 2) Check if consent was already obtained
|
||
if (CheckIfConsentAlreadyObtain())
|
||
return;
|
||
|
||
// 3) Check the system power state
|
||
if (_targetSystem.GetPowerState() != PowerState.On)
|
||
{
|
||
PerformSxFlow();
|
||
wasSxFlow = true;
|
||
}
|
||
|
||
// 4) Start the consent process
|
||
if(!wasSxFlow)
|
||
if (!StartUserConsentProcess())
|
||
return;
|
||
|
||
// 5) Detecting if sprite is supported
|
||
DetectingIfSpriteIsSupported();
|
||
|
||
if (_userCancel == true)
|
||
{
|
||
if (_targetSystem.GetOptInState() == OptInState.Displayed)
|
||
{
|
||
UpdateGUIMessages(LogLevel.DETAILED, Properties.Resources.ASK_OPTIN_CODE_MESSAGE,
|
||
LogInteraction.Information, Properties.Resources.ASK_OPTIN_CODE_MESSAGE);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 6) Check if sprite is not supported - if so, executing the non-sprite flow:
|
||
// A reboot is needed to display form from MEbx.
|
||
// But before, there is a need to check the connection interface, if the connection is over wireless
|
||
// a SetLinkPreference command must be sent in order to for keep the connection.
|
||
// For the case that the user press "Skip" but the state already changed to display,
|
||
// we asking here again what the OptIn state is.
|
||
if (_targetSystem.GetOptInState() != OptInState.Displayed)
|
||
{
|
||
if (_spriteIsSupported == false)
|
||
{
|
||
// Check if the connection is over wireless and the FW version is earlier than 8.1 (in later versions, the ling preference is automaticly taken care of)
|
||
if (Configuration.InterfaceSettings.GetInstance().LinkInterface == LinkInterface.Wireless && !CheckLinkProtectionSupport())
|
||
{
|
||
ExecuteWirelessFlow();
|
||
}
|
||
else
|
||
{
|
||
ExecuteNonSpriteFlow();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, Properties.Resources.ASK_OPTIN_CODE_MESSAGE,
|
||
LogInteraction.Information, Properties.Resources.ASK_OPTIN_CODE_MESSAGE);
|
||
}
|
||
}
|
||
|
||
public bool PerformGracefulShutdown()
|
||
{
|
||
return PerformGracefulShutdown(true, true, true);
|
||
}
|
||
|
||
public bool PerformAMTShutDown(PowerState state)
|
||
{
|
||
return PerformAMTShutDown(state, true, true);
|
||
}
|
||
|
||
public void SetGUIToConnect()
|
||
{
|
||
UpdateGUIMessages(LogLevel.BASIC, "Successfully Connected to: " + Configuration.GetInstance().Basic.AmtHost,
|
||
LogInteraction.Connection, "Connected to the remote system");
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region IDisposable Members
|
||
|
||
public void Dispose()
|
||
{
|
||
Dispose(true);
|
||
GC.SuppressFinalize(this);
|
||
}
|
||
|
||
private void Dispose(bool disposing)
|
||
{
|
||
if (disposing)
|
||
{
|
||
_timerBoot.Elapsed -= new ElapsedEventHandler(timerBoot_Elapsed);
|
||
_timerGraceful.Elapsed -= new ElapsedEventHandler(timerGraceful_Elapsed);
|
||
_timer.Elapsed -= new ElapsedEventHandler(OnShortTimedEvent);
|
||
|
||
_timer.Dispose();
|
||
_timerBoot.Dispose();
|
||
_timerGraceful.Dispose();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
internal PowerState GetPowerState()
|
||
{
|
||
return _targetSystem.GetPowerState();
|
||
}
|
||
}
|
||
}
|