Example #1
0
        // Function to be called by the getbladerequirement monitoring thread if chassisManagerSafeState is true
        internal static void BladeSerialSessionInactivityCheck()
        {
            // Timespan time parameters are in the order -- hours, minutes, and seconds.
            TimeSpan span              = new TimeSpan(0, 0, ConfigLoaded.TimeoutBladeSerialSessionInSecs);
            DateTime currTime          = DateTime.Now;
            DateTime lastActivityBound = currTime.Subtract(span);

            int currBladeId = bladeId;

            if (CompareAndSwapMetadata(ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken,
                                       ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken) ==
                CompletionCode.Success)
            {
                return;
            }

            // If there is an active session, if it has been inactive in the last 'x' minutes (2), then kill the session
            if (SetSecretMetadataIfInactive(lastActivityBound))
            {
                Contracts.ChassisResponse sessionResponse = new Contracts.ChassisResponse();
                sessionResponse = StopBladeSerialSession(ConfigLoaded.SecretBladePortId,
                                                         ConfigLoaded.SecretBladeSerialSessionToken, true);
                if (sessionResponse.completionCode != Contracts.CompletionCode.Success)
                {
                    Tracer.WriteError(
                        "BladeSerialSessionMetadata.BladeSerialSessionInactiveCheck: Error StopBladeSerialSession failure");
                }
            }
        }
Example #2
0
        internal static Contracts.ChassisResponse SendBladeSerialData(int bladeId, string sessionToken, byte[] data)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Failure;
            Tracer.WriteInfo("BladeSerialSessionMetadata.SendBladeSerialData({0})", bladeId);

            // If there is NOT an already existing Blade serial session (indicated by a invalid bladeId and a invalid sessionToken), return failure with appropriate completion code
            if (CompareAndSwapMetadata(ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken, ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken) == CompletionCode.Success)
            {
                Tracer.WriteError("SendBladeSerialData({0}): Send failed because of no active session.", bladeId);
                response.completionCode = Contracts.CompletionCode.NoActiveSerialSession;
                return(response);
            }

            // If this bladeid currently holds the serial session, update the timestamp else return failure
            if (BladeSerialSessionMetadata.CompareAndSwapMetadata(bladeId, sessionToken, bladeId, sessionToken, DateTime.Now) != CompletionCode.Success)
            {
                response.completionCode = Contracts.CompletionCode.SerialSessionActive;
                return(response);
            }

            BladeSerialSession currSession  = new BladeSerialSession((byte)bladeId);
            SerialStatusPacket serialStatus = new SerialStatusPacket();

            serialStatus = currSession.sendSerialData(data);
            if (serialStatus.completionCode != CompletionCode.Success)
            {
                Tracer.WriteError("BladeSerialSessionMetadata.SendBladeSerialData({0}): Error in BladeSerialSession.sendSerialData()", bladeId);
                return(response);
            }
            response.completionCode = Contracts.CompletionCode.Success;
            return(response);
        }
        public Contracts.ChassisResponse StopSerialPortConsole(int portID, string sessionToken, bool forceKillExistingSession = false)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Failure;
            this.portId             = portID;

            Tracer.WriteInfo("Received StopSerialPortConsole({0}) with sessionToken({1}) and forcekill({2})", this.portId, sessionToken, forceKillExistingSession);
            Tracer.WriteUserLog("Received StopSerialPortConsole({0}) with sessionToken({1}) and forcekill({2})", this.portId, sessionToken, forceKillExistingSession);
            int currPort = this.portId;

            // If there is NOT an already existing serial session (indicated by an invalid sessionToken), return failure with appropriate completion code
            if (CompareAndSwapMetadata(ConfigLoaded.InactiveSerialPortSessionToken, ConfigLoaded.InactiveSerialPortSessionToken) == CompletionCode.Success)
            {
                Tracer.WriteError("StopSerialPortConsole({0}): Stop failed because of no active session.", portID);
                response.completionCode = Contracts.CompletionCode.NoActiveSerialSession;
                return(response);
            }

            if (!forceKillExistingSession)
            {
                // If this do not currently hold the serial session, return failure
                if (CompareAndSwapMetadata(sessionToken, sessionToken) != CompletionCode.Success)
                {
                    response.completionCode = Contracts.CompletionCode.SerialSessionActive;
                    return(response);
                } // else proceed further to stop the session
            }
            else
            {
                // else force kill the current session
            }

            // Ipmi command to indicate end of serial session
            if (!ResetMetadata())
            {
                Tracer.WriteError("StopSerialPortConsole({0}): Unable to reset metadata", this.portId);
            }
            SerialPortConsole  currConsole  = new SerialPortConsole((byte)currPort);
            SerialStatusPacket serialStatus = new SerialStatusPacket();

            serialStatus = currConsole.closeSerialPortConsole();
            if (serialStatus.completionCode != CompletionCode.Success)
            {
                Tracer.WriteError("StopSerialConsolePort({0}): Error in closeserialportconsole()", currPort);
                return(response);
            }
            response.completionCode = Contracts.CompletionCode.Success;
            return(response);
        }
Example #4
0
        // This function should be called before executing any service APIs
        // TODO: Add other checks that needs to be done before executing APIs - like check for chassis terminating etc
        internal static CompletionCode ApiGreenSignalling()
        {
            CompletionCode response = new CompletionCode();

            response = CompletionCode.UnspecifiedError;

            int currBladeId = bladeId;

            // Return Success if there is no active serial console session in progress
            if (!BladeSerialSessionMetadata.IsSerialConsoleSessionActive())
            {
                response = CompletionCode.Success;
                return(response);
            }

            // If App.config parameter, KillSerialConsoleSession, is enabled,
            // terminate existing serial console session and proceed executing incoming commmands.
            if (ConfigLoaded.KillSerialConsoleSession)
            {
                response = CompletionCode.UnspecifiedError;

                Tracer.WriteInfo("Kill serial console session is enabled to allow incoming commands to succeed.");
                Contracts.ChassisResponse sessionResponse = new Contracts.ChassisResponse();
                sessionResponse = StopBladeSerialSession(ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken, true);
                if (sessionResponse.completionCode != Contracts.CompletionCode.Success)
                {
                    Tracer.WriteError("BladeSerialSessionMetadata.ApiGreenSignalling:Error stopserialsession failed");
                    return(response);
                }

                response = CompletionCode.Success;
                return(response);
            }
            // If App.config parameter, KillSerialConsoleSession, is not  enabled, maintain existing serial console session,
            // and ignore incoming commands, with explicit failure message output as warning in trace, since it will not
            // affect service correctness.
            else
            {
                response = CompletionCode.SerialPortOtherErrors;
                Tracer.WriteWarning("Serial console session in progress. Ignore incoming command with message:{0}", response);

                // We are returning non-Success completion code (represented as SerialPortOtherErrors)
                // to indicate/trigger the failure of this incoming command.
                return(response);
            }
        }
        // This function should be called before executing any service APIs
        // TODO: Add other checks that needs to be done before executing APIs - like check for chassis terminating etc
        internal static CompletionCode ApiGreenSignalling()
        {
            CompletionCode response = new CompletionCode();
            response = CompletionCode.UnspecifiedError;

            // Return Success if there is no active serial console session in progress - by checking the safe mode
            if (!IsSerialConsoleSessionActive())
            {
                response = CompletionCode.Success;
                return response;
            }

            // If App.config parameter, KillSerialConsoleSession, is enabled,
            // terminate existing serial console session and proceed executing incoming commmands.
            if (ConfigLoaded.KillSerialConsoleSession)
            {
                response = CompletionCode.UnspecifiedError;

                Tracer.WriteInfo("Kill serial console session is enabled to allow incoming commands to succeed.");
                Contracts.ChassisResponse sessionResponse = new Contracts.ChassisResponse();
                sessionResponse = StopBladeSerialSession(BladeId, ConfigLoaded.InactiveBladeSerialSessionToken, true);
                if (sessionResponse.completionCode != Contracts.CompletionCode.Success)
                {
                    Tracer.WriteError("BladeSerialSessionMetadata.ApiGreenSignalling:Error stopserialsession failed BladeId: {0}", BladeId);

                    if (sessionResponse.completionCode != Contracts.CompletionCode.NoActiveSerialSession)
                    return response;
                }

                response = CompletionCode.Success;
                return response;
            }
            // If App.config parameter, KillSerialConsoleSession, is not  enabled, maintain existing serial console session,
            // and ignore incoming commands, with explicit failure message output as warning in trace, since it will not
            // affect service correctness.
            else
            {
                    response = CompletionCode.SerialPortOtherErrors;
                    Tracer.WriteWarning("Serial console session in progress. Ignore incoming command with message:{0}", response);

                    // We are returning non-Success completion code (represented as SerialPortOtherErrors)
                    // to indicate/trigger the failure of this incoming command.
                    return response;
            }
        }
        public Contracts.ChassisResponse SendSerialPortData(int portID, string sessionToken, byte[] data)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Failure;
            this.portId             = portID;

            Tracer.WriteInfo("Received SendSerialPortConsoleData({0})", this.portId);

            // If there is NOT an already existing serial session (indicated by an invalid sessionToken), return failure with appropriate completion code
            if (CompareAndSwapMetadata(ConfigLoaded.InactiveSerialPortSessionToken, ConfigLoaded.InactiveSerialPortSessionToken) == CompletionCode.Success)
            {
                Tracer.WriteError("SendSerialPortData({0}): Send failed because of no active session.", portID);
                response.completionCode = Contracts.CompletionCode.NoActiveSerialSession;
                return(response);
            }

            // If this bladeid currently holds the serial session, update the timestamp else return failure
            if (this.CompareAndSwapMetadata(sessionToken, sessionToken, DateTime.Now) != CompletionCode.Success)
            {
                response.completionCode = Contracts.CompletionCode.SerialSessionActive;
                return(response);
            }

            SerialPortConsole  currConsole  = new SerialPortConsole((byte)this.portId);
            SerialStatusPacket serialStatus = new SerialStatusPacket();

            if (data != null && data.Length != 0)
            {
                serialStatus = currConsole.sendSerialData(data);
                if (serialStatus.completionCode != CompletionCode.Success)
                {
                    Tracer.WriteError("SendBladeSerialData({0}): Error in SerialPortConsole.SendSerialData()", portId);
                    return(response);
                }
            } // If data is null or if data has zero length, we are renewing activity lease and returning success to the user
            response.completionCode = Contracts.CompletionCode.Success;
            return(response);
        }
        // Function to be called by the getbladerequirement monitoring thread if chassisManagerSafeState is true
        internal void SerialPortConsoleInactivityCheck(int portID)
        {
            // Negative values in clientInactivityTimeoutIn100ms indicate infinite timeout - return immediately.
            if (clientInactivityTimeoutInSecs < 0)
            {
                Tracer.WriteError("Infinite client session inactivity timeout set for COM{0}", portId);
                return;
            }

            // ConfigLoaded.SerialPortConsoleClientSessionInactivityTimeout has 100ms scaling - therefore divide by 10 to get seconds
            TimeSpan span = new TimeSpan(0, 0, 0, ConfigLoaded.SerialPortConsoleClientSessionInactivityTimeoutInSecs);

            if (clientInactivityTimeoutInSecs > 0)
            {
                span = new TimeSpan(0, 0, 0, clientInactivityTimeoutInSecs);
            }
            DateTime currTime          = DateTime.Now;
            DateTime lastActivityBound = currTime.Subtract(span);

            if (CompareAndSwapMetadata(ConfigLoaded.InactiveSerialPortSessionToken, ConfigLoaded.InactiveSerialPortSessionToken) == CompletionCode.Success)
            {
                return;
            }

            // Check if inactive since 2 minutes back - if so write secret metadata
            if (!SetSecretMetadataIfInactive(lastActivityBound))
            {
                Tracer.WriteInfo("SerialConsolePortInactiveCheck({0}): Activity detected", this.portId);
                return; // Activity detected and hence not stopping the serial session
            }

            Contracts.ChassisResponse sessionResponse = new Contracts.ChassisResponse();
            sessionResponse = StopSerialPortConsole(portID, ConfigLoaded.SecretSerialPortSessionToken);
            if (sessionResponse.completionCode != Contracts.CompletionCode.Success)
            {
                Tracer.WriteError("SerialConsolePortInactiveCheck({0}): Error StopBladeSerialSession failure", this.portId);
            }
        }
        /// <summary>
        /// This method validates blade response for GetAll* APIs
        /// If even one blade response is not failure/timeout, return success.
        /// If all Blade response are failure/timeout, return failure
        /// </summary>
        /// <returns>Success if even one blade response is not failure/timeout, else retruns Failure</returns>
        public static Contracts.ChassisResponse ValidateAllBladeResponse(Contracts.CompletionCode[] responseCollection)
        {
            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            if (responseCollection != null)
            {
                // Check blade response for all blades, if even one blade has a valid response (other than failure/timeout..)
                // then return true. Else return false after cheicng all blades.
                for (int loop = 0; loop < responseCollection.Length; loop++)
                {
                    if (CheckCompletionCode(responseCollection[loop]))
                    {
                        varResponse.statusDescription = "Fetched result successfully";
                        varResponse.completionCode    = Contracts.CompletionCode.Success;
                        return(varResponse);
                    }
                }
            }

            // None of the blades has a valid response, return false
            varResponse.statusDescription = "Failure in fetching result";
            varResponse.completionCode    = Contracts.CompletionCode.Failure;
            return(varResponse);
        }
        /// <summary>
        /// Get All Blades PSU ALERT Default Power Cap
        /// </summary>
        public AllBladesPsuAlertDpcResponse GetAllBladesPsuAlertDefaultPowerCap()
        {
            AllBladesPsuAlertDpcResponse responses = new AllBladesPsuAlertDpcResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = String.Empty;
            responses.bladeDpcResponseCollection = new List<BladePsuAlertDpcResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[ConfigLoaded.Population];
            Tracer.WriteUserLog("Invoked GetAllBladesPsuAlertDefaultPowerCap");
            Tracer.WriteInfo("Received GetAllBladsePsuAlertDefaultPowerCap for all blades");

            for (int loop = 0; loop < ConfigLoaded.Population; loop++)
            {
                responses.bladeDpcResponseCollection.Add(GetBladePsuAlertDefaultPowerCap(loop + 1));
                // Set the internal blade response to the blade completion code.
                bladeInternalResponseCollection[loop] = responses.bladeDpcResponseCollection[loop].completionCode;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
        /// <summary>
        /// Get power reading for all blades
        /// </summary>
        /// <returns>Array of blade responses containing the power reading</returns>
        public GetAllBladesPowerReadingResponse GetAllBladesPowerReading()
        {
            byte MaxbladeCount = (byte)ConfigLoaded.Population;
            GetAllBladesPowerReadingResponse responses = new GetAllBladesPowerReadingResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.bladePowerReadingCollection = new List<BladePowerReadingResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[MaxbladeCount];

            Tracer.WriteUserLog("Invoked GetAllBladesPowerReading()");

            try
            {
                for (int index = 0; index < ConfigLoaded.Population; index++)
                {
                    int bladeId = index + 1;
                    responses.bladePowerReadingCollection.Add(GetBladePowerReading((int)bladeId));

                    // Set the internal blade response to the blade completion code.
                    bladeInternalResponseCollection[index] = responses.bladePowerReadingCollection[index].completionCode;
                }
            }
            catch (Exception ex)
            {
                responses.completionCode = Contracts.CompletionCode.Failure;
                responses.statusDescription = responses.completionCode.ToString() + ": " + ex.Message;
                Tracer.WriteError("GetAllBladesPowerReading Exception" + ex);
                return responses;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
        /// <summary>
        /// Update firmware on specified PSU
        /// </summary>
        /// <param name="psuId">The psu identifier.</param>
        /// <param name="fwFilepath">The firmware image file path. The file must be in hex format.</param>
        /// <param name="primaryImage">
        /// True:  Firmware image is for primary controller. 
        /// False: Firmware image is for secondary controller. 
        /// <returns>
        /// Response indicating if firmware upgrade was started successfully.
        /// </returns>
        public Contracts.ChassisResponse UpdatePSUFirmware(int psuId, string fwFilepath, bool primaryImage)
        {
            Tracer.WriteUserLog("Invoked UpdatePSUFirmware(psuId: {0}, fwFilepath: {1}, primaryImage: {2})", psuId, fwFilepath, primaryImage);

            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            // Check PSU ID
            if (ChassisManagerUtil.CheckPsuId(psuId) != CompletionCode.Success)
            {
                Tracer.WriteWarning("UpdatePSUFirmware failed. Invalid PSU Id: {0}", psuId);

                response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                response.statusDescription = Contracts.CompletionCode.ParameterOutOfRange.ToString();
                return response;
            }

            // Firmware upgrade only valid for Emerson PSU
            if (!(ChassisState.Psu[psuId - 1] is EmersonPsu))
            {
                Tracer.WriteWarning("UpdatePSUFirmware failed. PSU {0} is not an Emerson PSU.", psuId);

                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = "UpdatePSUFirmware() only supported on Emerson PSU.";
                return response;
            }

            // If firmware update is already in progress, return error
            if (ChassisState.PsuFwUpdateInProgress[psuId - 1])
            {
                response.completionCode = Contracts.CompletionCode.PSUFirmwareUpdateInProgress;
                response.statusDescription = "PSU firmware update in progress";
                return response;
            }

            try
            {
                Tracer.WriteInfo("UpdatePSUFirmware: Updating PSU: {0} with file {1}. primaryImage: {2}", psuId, fwFilepath, primaryImage);

                // Check that firmware image file can be opened for reading.
                // If file does not exist or cannot be read, the method will throw an exception
                File.OpenRead(fwFilepath);

                // Build firmware update data
                EmersonPsu.FirmwareUpdateInfo fwUpdateInfo = new EmersonPsu.FirmwareUpdateInfo();
                fwUpdateInfo.fwFilepath = fwFilepath;
                fwUpdateInfo.primaryImage = primaryImage;

                // Execute firmware update
                EmersonPsu emersonPsu = (EmersonPsu)ChassisState.Psu[(psuId - 1)];
                CompletionCode completionCode = emersonPsu.ExecuteFirmwareUpdate(fwUpdateInfo);
                if (completionCode == CompletionCode.Success)
                {
                    response.completionCode = Contracts.CompletionCode.Success;
                }
                else
                {
                    response.completionCode = Contracts.CompletionCode.Failure;
                    response.statusDescription = response.completionCode.ToString();
                }
            }
            catch (Exception ex)
            {
                Tracer.WriteWarning("UpdatePSUFirmware failed with exception: " + ex.Message);

                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = response.completionCode.ToString() + ": " + ex.Message;
                return response;
            }

            return response;
        }
        /// <summary>
        /// Stops serial session on a blade
        /// </summary>
        public Contracts.ChassisResponse StopBladeSerialSession(int bladeId, string sessionToken, bool forceKill)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            Tracer.WriteInfo("Received StopBladeSerialSession(bladeId: {0})", bladeId);
            Tracer.WriteUserLog("Invoked StopBladeSerialSession(bladeId: {0})", bladeId);

                if (ChassisManagerUtil.CheckBladeId((byte)bladeId) != (byte)CompletionCode.Success)
                {
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;

                    Tracer.WriteWarning("StopBladeSerialSession failed: Blade ID: {0} out of range: ", bladeId);
                    return response;
                }

                response = CheckBladeAndFirmwareState((byte)bladeId);
            if (response.completionCode != Contracts.CompletionCode.Success)
                {
                    return response;
                }

                if (!FunctionValidityChecker.CheckBladeTypeValidity((byte)bladeId))
                {
                    response.completionCode = Contracts.CompletionCode.CommandNotValidForBlade;
                    return response;
                }

            response = ChassisState.BladeSerialMetadata[bladeId].StopBladeSerialSession(bladeId, sessionToken, forceKill);

            if (ChassisManagerUtil.CheckCompletionCode(response.completionCode))
            {
                Tracer.WriteInfo("StopBladeSerialSession succeeded for bladeId: " + bladeId);
            }
            else
            {
                Tracer.WriteError("StopBladeSerialSession failed for bladeId: {0} with completion code: {1}",
                    bladeId, response.completionCode.ToString());
            }

            response.statusDescription = response.completionCode.ToString();
            return response;
        }
Example #13
0
        /// <summary>
        /// command specific implementation 
        /// </summary>
        internal override void commandImplementation()
        {
            Contracts.ChassisResponse myResponse = new Contracts.ChassisResponse();
            dynamic uname = null;

            try
            {
                if (this.argVal.TryGetValue('u', out uname))
                {
                    myResponse = WcsCli2CmConnectionManager.channel.RemoveChassisControllerUser((string)uname);
                }
                else
                {
                    Console.WriteLine(WcsCliConstants.invalidCommandString);
                }
            }
            catch (Exception ex)
            {
                SharedFunc.ExceptionOutput(ex);
                return;
            }

            if (myResponse == null)
            {
                Console.WriteLine(WcsCliConstants.serviceResponseEmpty);
                return;
            }

            if (myResponse.completionCode == Contracts.CompletionCode.Success)
            {
                Console.WriteLine(WcsCliConstants.commandSucceeded);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.Failure)
            {
                Console.WriteLine(WcsCliConstants.commandFailure);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.Timeout)
            {
                Console.WriteLine(WcsCliConstants.commandTimeout);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.UserNotFound)
            {
                Console.WriteLine(WcsCliConstants.commandUserNotFound);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.UserPasswordDoesNotMeetRequirement)
            {
                Console.WriteLine(WcsCliConstants.commandUserPwdDoesNotMeetReq);
            }
            else
            {
                Console.WriteLine("Command failed with completion code: {0}", myResponse.completionCode.ToString());
            }
        }
        /// <summary>
        /// Set soft blade power limit ON for all blades
        /// </summary>
        /// <returns>Array of blade responses indicating blade operation was success/failure</returns>
        public AllBladesResponse SetAllBladesOn()
        {
            byte MaxbladeCount = (byte)ConfigLoaded.Population;

            AllBladesResponse responses = new AllBladesResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.bladeResponseCollection = new List<BladeResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[MaxbladeCount];

            Tracer.WriteInfo("Received SetAllBladesOn()");
            Tracer.WriteUserLog("Invoked SetAllBladesOn()");
            try
            {
                for (int index = 0; index < ConfigLoaded.Population; index++)
                {
                    int bladeId = index + 1;
                    responses.bladeResponseCollection.Add(SetBladeOn(bladeId));

                    // Set the internal blade response to the blade completion code.
                    bladeInternalResponseCollection[index] = responses.bladeResponseCollection[index].completionCode;
                }
            }
            catch (Exception ex)
            {
                Tracer.WriteError("SetAllBladesOn failed with exception" + ex);
                responses.completionCode = Contracts.CompletionCode.Failure;
                responses.statusDescription = Contracts.CompletionCode.Failure + ": " + ex.Message;
                return responses;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
        /// <summary>
        /// Activate Deactivate PSU ALERT Action against all blades.
        /// </summary>
        public Contracts.AllBladesResponse SetAllBladesPsuAlert(bool enableProchot, int action, bool removeCap)
        {
            Contracts.AllBladesResponse responses = new Contracts.AllBladesResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = String.Empty;
            responses.bladeResponseCollection = new List<BladeResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[ConfigLoaded.Population];

            Tracer.WriteUserLog("Invoked SetAllBladesPsuAlert");
            Tracer.WriteInfo("Received SetAllBladesPsuAlert");

            for (int loop = 0; loop < ConfigLoaded.Population; loop++)
            {
                responses.bladeResponseCollection.Add(SetBladePsuAlert(loop + 1, enableProchot, action, removeCap));
                // Set the internal blade response to the blade completion code.
                bladeInternalResponseCollection[loop] = responses.bladeResponseCollection[loop].completionCode;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
        public Contracts.ChassisResponse StopSerialPortConsole(int portID, string sessionToken, bool forceKillExistingSession = false)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Failure;
            this.portId = portID;

            Tracer.WriteInfo("Received StopSerialPortConsole({0}) with sessionToken({1}) and forcekill({2})", this.portId, sessionToken, forceKillExistingSession);
            Tracer.WriteUserLog("Received StopSerialPortConsole({0}) with sessionToken({1}) and forcekill({2})", this.portId, sessionToken, forceKillExistingSession);
            int currPort = this.portId;

            // If there is NOT an already existing serial session (indicated by an invalid sessionToken), return failure with appropriate completion code
            if (CompareAndSwapMetadata(ConfigLoaded.InactiveSerialPortSessionToken, ConfigLoaded.InactiveSerialPortSessionToken) == CompletionCode.Success)
            {
                Tracer.WriteError("StopSerialPortConsole({0}): Stop failed because of no active session.", portID);
                response.completionCode = Contracts.CompletionCode.NoActiveSerialSession;
                return response;
            }

            if (!forceKillExistingSession)
            {
                // If this do not currently hold the serial session, return failure
                if (CompareAndSwapMetadata(sessionToken, sessionToken) != CompletionCode.Success)
                {
                    response.completionCode = Contracts.CompletionCode.SerialSessionActive;
                    return response;
                } // else proceed further to stop the session
            }
            else
            {
                // else force kill the current session
            }

            // Ipmi command to indicate end of serial session
            if (!ResetMetadata())
            {
                Tracer.WriteError("StopSerialPortConsole({0}): Unable to reset metadata", this.portId);
            }
            SerialPortConsole currConsole = new SerialPortConsole((byte)currPort);
            SerialStatusPacket serialStatus = new SerialStatusPacket();
            serialStatus = currConsole.closeSerialPortConsole();
            if (serialStatus.completionCode != CompletionCode.Success)
            {
                Tracer.WriteError("StopSerialConsolePort({0}): Error in closeserialportconsole()", currPort);
                return response;
            }
            response.completionCode = Contracts.CompletionCode.Success;
            return response;
        }
        public Contracts.ChassisResponse SendSerialPortData(int portID, string sessionToken, byte[] data)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Failure;
            this.portId = portID;

            Tracer.WriteInfo("Received SendSerialPortConsoleData({0})", this.portId);

            // If there is NOT an already existing serial session (indicated by an invalid sessionToken), return failure with appropriate completion code
            if (CompareAndSwapMetadata(ConfigLoaded.InactiveSerialPortSessionToken, ConfigLoaded.InactiveSerialPortSessionToken) == CompletionCode.Success)
            {
                Tracer.WriteError("SendSerialPortData({0}): Send failed because of no active session.", portID);
                response.completionCode = Contracts.CompletionCode.NoActiveSerialSession;
                return response;
            }

            // If this bladeid currently holds the serial session, update the timestamp else return failure
            if (this.CompareAndSwapMetadata(sessionToken, sessionToken, DateTime.Now) != CompletionCode.Success)
            {
                response.completionCode = Contracts.CompletionCode.SerialSessionActive;
                return response;
            }

            SerialPortConsole currConsole = new SerialPortConsole((byte)this.portId);
            SerialStatusPacket serialStatus = new SerialStatusPacket();
            if (data != null && data.Length != 0)
            {
                serialStatus = currConsole.sendSerialData(data);
                if (serialStatus.completionCode != CompletionCode.Success)
                {
                    Tracer.WriteError("SendBladeSerialData({0}): Error in SerialPortConsole.SendSerialData()", portId);
                    return response;
                }
            } // If data is null or if data has zero length, we are renewing activity lease and returning success to the user
            response.completionCode = Contracts.CompletionCode.Success;
            return response;
        }
        // Function to be called by the getbladerequirement monitoring thread if chassisManagerSafeState is true
        internal void SerialPortConsoleInactivityCheck(int portID)
        {
            // Negative values in clientInactivityTimeoutIn100ms indicate infinite timeout - return immediately.
            if (clientInactivityTimeoutInSecs < 0)
            {
                Tracer.WriteError("Infinite client session inactivity timeout set for COM{0}", portId);
                return;
            }

            // ConfigLoaded.SerialPortConsoleClientSessionInactivityTimeout has 100ms scaling - therefore divide by 10 to get seconds
            TimeSpan span = new TimeSpan(0, 0, 0, ConfigLoaded.SerialPortConsoleClientSessionInactivityTimeoutInSecs);

            if (clientInactivityTimeoutInSecs > 0)
            {
                span = new TimeSpan(0, 0, 0, clientInactivityTimeoutInSecs);
            }
            DateTime currTime = DateTime.Now;
            DateTime lastActivityBound = currTime.Subtract(span);

            if (CompareAndSwapMetadata(ConfigLoaded.InactiveSerialPortSessionToken, ConfigLoaded.InactiveSerialPortSessionToken) == CompletionCode.Success)
            {
                return;
            }

            // Check if inactive since 2 minutes back - if so write secret metadata
            if (!SetSecretMetadataIfInactive(lastActivityBound))
            {
                Tracer.WriteInfo("SerialConsolePortInactiveCheck({0}): Activity detected", this.portId);
                return; // Activity detected and hence not stopping the serial session
            }

            Contracts.ChassisResponse sessionResponse = new Contracts.ChassisResponse();
            sessionResponse = StopSerialPortConsole(portID, ConfigLoaded.SecretSerialPortSessionToken);
            if (sessionResponse.completionCode != Contracts.CompletionCode.Success)
                Tracer.WriteError("SerialConsolePortInactiveCheck({0}): Error StopBladeSerialSession failure", this.portId);
        }
        /// <summary>
        /// Power cycle all blades
        /// </summary>
        /// <param name="offTime">time for which the blades will be powered off in seconds</param>
        /// <returns>Collection of Blade responses indicating if blade operation was success/failure</returns>
        public AllBladesResponse SetAllBladesActivePowerCycle(uint offTime)
        {
            byte maxbladeCount = (byte)ConfigLoaded.Population;

            AllBladesResponse responses = new AllBladesResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.bladeResponseCollection = new List<BladeResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[maxbladeCount];

            Tracer.WriteUserLog(" Invoked SetAllBladesActivePowerCycle(offTime: {0})", offTime);

            // Check that the power off time is valid for a byte value since the IPMI command takes a byte value
            if (offTime > Byte.MaxValue)
            {
                Tracer.WriteWarning("SetAllBladesActivePowerCycle failed, Invalid power off time: {0}", offTime);

                responses.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                responses.statusDescription = Contracts.CompletionCode.ParameterOutOfRange.ToString();
                return responses;
            }

            for (int loop = 0; loop < maxbladeCount; loop++)
            {
                int bladeId = loop + 1;

                responses.bladeResponseCollection.Add(SetBladeActivePowerCycle(bladeId, offTime));

                // Set the internal blade response to the blade completion code.
                bladeInternalResponseCollection[loop] = responses.bladeResponseCollection[loop].completionCode;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
        /// <summary>
        /// Get information for all blades
        /// </summary>
        /// <returns>Array of blade info response</returns>
        public GetAllBladesInfoResponse GetAllBladesInfo()
        {
            byte maxbladeCount = (byte)ConfigLoaded.Population;

            Tracer.WriteInfo("Received GetAllBladesInfo()");
            Tracer.WriteUserLog("Invoked GetAllBladesInfo()");

            // Server side class structure to populate blade information
            GetAllBladesInfoResponse responses = new GetAllBladesInfoResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.bladeInfoResponseCollection = new List<BladeInfoResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[maxbladeCount];

            Tracer.WriteInfo("GetAllBladesInfo: Processing Blades ");

            // Loop to populate blade information for requested number of blades
            for (int loop = 0; loop < maxbladeCount; loop++)
            {
                int bladeId = loop + 1; // we need to get for all blades

                //Call getBladeInfo for the Blade ID
                responses.bladeInfoResponseCollection.Add(this.GetBladeInfo(bladeId));

                // Set the internal blade response to the blade completion code.
                bladeInternalResponseCollection[loop] = responses.bladeInfoResponseCollection[loop].completionCode;

            }

            Tracer.WriteInfo("GetAllBladesInfo: Completed populating for Blades");

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;

            return responses;
        }
        /// <summary>
        /// Clear chassis log
        /// </summary>
        /// <returns>1 indicates success. 0 indicates failure.</returns>
        public Contracts.ChassisResponse ClearChassisLog()
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            string filePath = ConfigLoaded.UserLogFilePath;
            Tracer.WriteUserLog("Invoked ClearChassisLog()");

            // Initialize to failure to start with
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            try
            {
                if (Tracer.ClearUserLog())
                {
                    response.completionCode = Contracts.CompletionCode.Success;
                    Tracer.WriteInfo("Cleared chassis log");
                }
                else
                {
                    response.completionCode = Contracts.CompletionCode.Failure;
                    response.statusDescription = "Failed to clear chassis log";
                    Tracer.WriteError("Failed to clear chassis log");
                }
            }
            catch (IOException ex)
            {
                Tracer.WriteError("ClearChassisLog Error " + ex.Message);
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = String.Format("ClearChassisLog Error " + ex.Message);
            }

            return response;
        }
        /// <summary>
        /// Method to add chassis controller user
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="passwordString">password</param>
        /// <returns>Response indicating if add user was success/failure</returns>
        public Contracts.ChassisResponse AddChassisControllerUser(string userName, string passwordString, Contracts.WCSSecurityRole role)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            Tracer.WriteUserLog("Invoked AddChassisControllerUser(UserName: {0}, role: {1})", userName, role.ToString());
            try
            {
                // password never expires flag.
                int neverExpire = 0x10000;

                // Check if security role is valid
                if (!Enum.IsDefined(typeof(WCSSecurityRole), role))
                {
                    Tracer.WriteError("AddChassisControllerUser: Invalid security role " + role.ToString());
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "Input security role is invalid";
                    return response;
                }

                // Return BadRequest if any data is missing.
                if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(passwordString))
                {
                    Tracer.WriteError("AddChassisControllerUser: Invalid input parameters.");
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "Username or Password is null or empty";
                    return response;
                }

                userName = userName.Trim();
                passwordString = passwordString.Trim();

                if (userName == null || passwordString == null)
                {
                    Tracer.WriteError("AddChassisControllerUser: Invalid input parameters.");

                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "Username or Password is null or empty";
                    return response;
                }

                DirectoryEntry AD = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
                DirectoryEntry NewUser = AD.Children.Add(userName, "user");

                // create account
                NewUser.Invoke("SetPassword", new object[] { passwordString });
                NewUser.Invoke("Put", new object[] { "Description", "WcsCli chassis manager request" });
                NewUser.CommitChanges();

                // update properteis for password to never expire.
                int userProperties = (int)NewUser.Properties["userFlags"].Value;
                NewUser.Properties["userFlags"].Value = userProperties | neverExpire;
                NewUser.CommitChanges();

                DirectoryEntry grp;
                // Find group, if not exists, create
                grp = ChassisManagerUtil.FindGroupIfNotExistsCreate(role);

                if (grp != null)
                {
                    grp.Invoke("Add", new object[] { NewUser.Path.ToString() });

                    Tracer.WriteInfo("AddChassisControllerUser: User Account Created Successfully");
                    response.completionCode = Contracts.CompletionCode.Success;
                }
                else
                {
                    Tracer.WriteInfo("AddChassisControllerUser: Failed to create account, failed to add user to group");
                    response.completionCode = Contracts.CompletionCode.Failure;
                    response.statusDescription = String.Format("AddChassisControllerUser: Failed to create account, failed to add user to group");
                }

                return response;
            }
            catch (Exception ex)
            {
                Tracer.WriteError("AddChassisControllerUser: failed with exception: " + ex);

                // check if password did not meet the requirements, display appropriate message to user.
                if (ex.ToString().Contains("0x800708C5") || ex.ToString().Contains("password does not meet"))
                {
                    response.completionCode = Contracts.CompletionCode.UserPasswordDoesNotMeetRequirement;
                    response.statusDescription = "User password does not meet requirement";
                }
                else if (ex.ToString().Contains("0x800708B0"))
                {
                    response.completionCode = Contracts.CompletionCode.UserAccountExists;
                    response.statusDescription = "User account already exists";
                }
                else
                {
                    response.completionCode = Contracts.CompletionCode.Failure;
                    response.statusDescription = String.Format("AddChassisControllerUser failed. Unknown Error.");
                }
                return response;
            }
        }
        /// <summary>
        /// Set all blades power limit to the given value
        /// </summary>
        /// <param name="powerLimitInWatts">Power limit to set</param>
        /// <returns>Array of blade responses indicating blade operation was success/failure</returns>
        public AllBladesResponse SetAllBladesPowerLimit(double powerLimitInWatts)
        {
            byte MaxbladeCount = (byte)ConfigLoaded.Population;

            AllBladesResponse responses = new AllBladesResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.bladeResponseCollection = new List<BladeResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[MaxbladeCount];

            Tracer.WriteUserLog("Invoked SetAllBladesPowerLimit(powerLimitInWatts: {0})", powerLimitInWatts);
            try
            {
                for (int index = 0; index < ConfigLoaded.Population; index++)
                {
                    responses.bladeResponseCollection.Add(SetBladePowerLimit((int)(index + 1), powerLimitInWatts));

                    // Set the internal blade response to the blade completion code.
                    bladeInternalResponseCollection[index] = responses.bladeResponseCollection[index].completionCode;
                }
            }
            catch (Exception ex)
            {
                responses.completionCode = Contracts.CompletionCode.Failure;
                responses.statusDescription = responses.completionCode.ToString() + ": " + ex.Message;
                Tracer.WriteError("SetAllBladesPowerLimit Exception" + ex.Message);
                return responses;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
Example #24
0
        /// <summary>
        /// command specific implementation 
        /// </summary>
        internal override void commandImplementation()
        {
            Contracts.ChassisResponse myResponse = new Contracts.ChassisResponse();
            dynamic uname = null;

            try
            {
                if (this.argVal.TryGetValue('u', out uname) && this.argVal.ContainsKey('a'))
                {
                    myResponse = WcsCli2CmConnectionManager.channel.ChangeChassisControllerUserRole((string)uname, WCSSecurityRole.WcsCmAdmin);
                }
                else if (this.argVal.TryGetValue('u', out uname) && this.argVal.ContainsKey('o'))
                {
                    myResponse = WcsCli2CmConnectionManager.channel.ChangeChassisControllerUserRole((string)uname, WCSSecurityRole.WcsCmOperator);
                }
                else if (this.argVal.TryGetValue('u', out uname) && this.argVal.ContainsKey('r'))
                {
                    myResponse = WcsCli2CmConnectionManager.channel.ChangeChassisControllerUserRole((string)uname, WCSSecurityRole.WcsCmUser);
                }
                else
                {
                    Console.WriteLine(WcsCliConstants.invalidCommandString);
                }
            }
            catch (Exception ex)
            {
                SharedFunc.ExceptionOutput(ex);
                return;
            }

            if (myResponse == null)
            {
                Console.WriteLine(WcsCliConstants.serviceResponseEmpty);
                return;
            }

            if (myResponse.completionCode == Contracts.CompletionCode.Success)
            {
                Console.WriteLine(WcsCliConstants.commandSucceeded);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.Failure)
            {
                Console.WriteLine(WcsCliConstants.commandFailure);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.Timeout)
            {
                Console.WriteLine(WcsCliConstants.commandTimeout);
            }
            else if (myResponse.completionCode == Contracts.CompletionCode.UserNotFound)
            {
                Console.WriteLine(WcsCliConstants.commandUserNotFound);
            }
            else
            {
                Console.WriteLine("Command failed with the completion code: {0}", myResponse.completionCode.ToString());
            }
        }
        /// <summary>
        /// Power On all blades
        /// </summary>
        /// <returns>Array of blade responses, one for each blade. Indicates success/failure.</returns>
        public AllBladesResponse SetAllPowerOn()
        {
            byte maxBladeCount = (byte)ConfigLoaded.Population;

            AllBladesResponse responses = new AllBladesResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.bladeResponseCollection = new List<BladeResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[maxBladeCount];

            Tracer.WriteInfo("Invoked SetAllPowerOn()");
            Tracer.WriteUserLog("Invoked SetAllPowerOn()");

            for (int loop = 0; loop < maxBladeCount; loop++)
            {
                int bladeId = loop + 1;
                responses.bladeResponseCollection.Add(SetPowerOn(bladeId));

                // Set the internal blade response to the blade completion code.
                bladeInternalResponseCollection[loop] = responses.bladeResponseCollection[loop].completionCode;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
Example #26
0
        internal static Contracts.ChassisResponse StopBladeSerialSession(int bladeId, string sessionToken, bool forceKill = false)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Failure;
            Tracer.WriteInfo("BladeSerialSessionMetadata.Received Stopbladeserialsession({0})", bladeId);

            // If there is NOT an already existing Blade serial session (indicated by a invalid bladeId and a invalid sessionToken), return failure with appropriate completion code
            if (CompareAndSwapMetadata(ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken,
                                       ConfigLoaded.InactiveBladePortId, ConfigLoaded.InactiveBladeSerialSessionToken) == CompletionCode.Success)
            {
                Tracer.WriteError("StopBladeSerialSession({0}): Stop failed because of no active session.", bladeId);
                response.completionCode = Contracts.CompletionCode.NoActiveSerialSession;
                return(response);
            }

            // Normal scenario when forcekill option is not true.. check for bladeid correctness and if it currently holds the serial session
            if (!forceKill)
            {
                if (ChassisManagerUtil.CheckBladeId((byte)bladeId) != (byte)CompletionCode.Success)
                {
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    return(response);
                }

                // If this bladeid do not currently hold the serial session, return failure
                if (CompareAndSwapMetadata(bladeId, sessionToken, bladeId, sessionToken) != CompletionCode.Success)
                {
                    response.completionCode = Contracts.CompletionCode.SerialSessionActive;
                    return(response);
                }
            }

            // Communication device has to come out of safe mode - should allow IPMI commands to go to the BMC
            if (!CommunicationDevice.DisableSafeMode())
            {
                Tracer.WriteError(
                    "BladeSerialSessionMetadata.StopBladeSerialSession({0}): CommunicationDevice.DisableSafeMode Failed",
                    bladeId);
            }

            Ipmi.SerialMuxSwitch rms;
            // If forcekill parameter is false, then use the bladeid that is passed by the user
            if (!forceKill)
            {
                rms = WcsBladeFacade.ResetSerialMux((byte)bladeId);
            }
            // If forcekill parameter is true, then use the bladeid that currently holds the serial session
            else
            {
                rms = WcsBladeFacade.ResetSerialMux((byte)BladeSerialSessionMetadata.bladeId);
            }

            if (rms.CompletionCode != (byte)CompletionCode.Success)
            {
                Tracer.WriteError("BladeSerialSessionMetadata.StopBladeSerialSession({0}): Ipmi ReSetSerialMuxSwitch Failed", bladeId);
            }

            if (!BladeSerialSessionMetadata.ResetMetadata())
            {
                Tracer.WriteError("BladeSerialSessionMetadata.StopBladeSerialSession: Unable to reset metadata");
            }
            response.completionCode = Contracts.CompletionCode.Success;
            // Resetting TimeoutBladeSerialSessionInSecs to 0 to account for default or user provided session timeout value
            ConfigLoaded.TimeoutBladeSerialSessionInSecs = 0;
            return(response);
        }
        /// <summary>
        /// Switch chassis Attention LED On
        /// </summary>
        /// <returns>Chassis Response packet</returns>
        public Contracts.ChassisResponse SetChassisAttentionLEDOn()
        {
            Tracer.WriteInfo("Received SetChassisAttentionLEDOn()");

            Tracer.WriteUserLog("Invoked SetChassisAttentionLEDOn()");

            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            // Turn On the Attention LED.
            byte status = ChassisState.AttentionLed.TurnLedOn();

            Tracer.WriteInfo("SetChassisAttentionLEDOn Return: {0}", status);

            if (status != (byte)Contracts.CompletionCode.Success)
            {
                response.completionCode = Contracts.CompletionCode.Failure;
                Tracer.WriteError("Chassis attention LED turn on failed with Completion Code: {0:X}", status);
                response.statusDescription = String.Format("Chassis attention LED turn on failed with Completion Code: {0:X}", status);
            }
            else
            {
                response.completionCode = Contracts.CompletionCode.Success;
                Tracer.WriteInfo("Chassis attention LED is turned ON successfully");
            }

            return response;
        }
        /// <summary>
        /// Method to change chassis controller user password to given values
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="newPassword">New password</param>
        /// <returns>Chassis Response indicating if user password change was a success/failure</returns>
        public Contracts.ChassisResponse ChangeChassisControllerUserPassword(string userName, string newPassword)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            Tracer.WriteUserLog("Invoked ChangeChassisControllerUserPassword(userName: {0})", userName);
            try
            {
                userName = userName.Trim();
                newPassword = newPassword.Trim();

                if (userName == null || newPassword == null)
                {
                    Tracer.WriteError("ChangeChassisControllerUserPassword: Invalid input parameters.");
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "User name or password is null";
                    return response;
                }

                DirectoryEntry AD = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
                DirectoryEntry myEntry = AD.Children.Find(userName, "user");

                if (myEntry != null)
                {
                    myEntry.Invoke("SetPassword", new object[] { newPassword });
                    myEntry.CommitChanges();
                    Tracer.WriteInfo("ChangeChassisControllerUserPassword: Password changed Successfully for user: {0}", userName);
                    response.completionCode = Contracts.CompletionCode.Success;
                }
                else
                {
                    Tracer.WriteError("ChangeChassisControllerUserPassword: Failed to change user password, User: {0} does not exists",
                        userName);
                }
                return response;
            }
            catch (Exception ex)
            {
                Tracer.WriteError("ChangeChassisControllerUserPassword: failed with exception: " + ex);
                response.completionCode = Contracts.CompletionCode.Failure;

                // check if password did not meet the requirements, display appropriate message to user.
                if (ex.ToString().Contains("0x800708C5") || ex.ToString().Contains("password does not meet"))
                {
                    response.completionCode = Contracts.CompletionCode.UserPasswordDoesNotMeetRequirement;
                    response.statusDescription = "User password does not meet system requirements";
                }
                // check the exception code for user not found
                else if (ex.ToString().Contains("0x800708AD"))
                {
                    response.completionCode = Contracts.CompletionCode.UserNotFound;
                    response.statusDescription = "User not found";
                }
                else
                {
                    response.statusDescription = String.Format("ChangeChassisControllerUserPassword failed. Unknown Error.");
                }
                return response;
            }
        }
        /// <summary>
        /// Set SNTP Time Service
        /// </summary>
        public Contracts.ChassisResponse SetSntpServer(string primary, string secondary)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();

            Tracer.WriteInfo("Received SetSntpServer({0}, {1})", primary, secondary);
            Tracer.WriteUserLog("Received SetSntpServer({0}, {1})", primary, secondary);

            CompletionCode code = Sntp.SetNtpServer(new Sntp.NtpServerName(primary, secondary));

            if (code == CompletionCode.InvalidDataFieldInRequest)
            {
                response.completionCode = Contracts.CompletionCode.Unknown;
                response.statusDescription = "Null values and zero Ip address not supported";
            }
            else
            {
                response.completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping((byte)code);
            }

            return response;
        }
        /// <summary>
        /// Method to change chassis controller user role
        /// </summary>
        /// <param name="userName">User name</param>
        /// <param name="role">WCS Security role</param>
        /// <returns>Chassis Response indicating if the update user settings was a success/failure</returns>
        public Contracts.ChassisResponse ChangeChassisControllerUserRole(string userName, WCSSecurityRole role)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            DirectoryEntry grp;
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            Tracer.WriteUserLog(String.Format("Invoked ChangeChassisControllerUserRole(userName: {0}, role: {1})", userName, role.ToString()));
            try
            {
                // Validate input parameters

                // Check if input user security role is valid
                if (!Enum.IsDefined(typeof(WCSSecurityRole), role))
                {
                    Tracer.WriteError("ChangeChassisControllerUser: Invalid security role " + role.ToString());
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "Input security role is invalid";
                    return response;
                }

                userName = userName.Trim();

                if (userName == null)
                {
                    Tracer.WriteError("ChangeChassisControllerUserRole: Invalid input parameters.");
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "User name provided is null";
                    return response;
                }

                DirectoryEntry AD = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
                DirectoryEntry myEntry = AD.Children.Find(userName, "user");

                // Remove user from other WCS security group , if it exists in them
                // This step is required as if the user permissions are decreased from
                // admin to user, then he should no longer be in admin role.Similar with operator to user.

                if (role != WCSSecurityRole.WcsCmAdmin)
                {
                    ChassisManagerUtil.RemoveUserFromWCSSecurityGroups(userName, WCSSecurityRole.WcsCmAdmin);
                }

                if (role != WCSSecurityRole.WcsCmOperator)
                {
                    ChassisManagerUtil.RemoveUserFromWCSSecurityGroups(userName, WCSSecurityRole.WcsCmOperator);
                }

                if (role != WCSSecurityRole.WcsCmUser)
                {
                    ChassisManagerUtil.RemoveUserFromWCSSecurityGroups(userName, WCSSecurityRole.WcsCmUser);
                }

                // Add if user does not already exists in the given group
                if (!ChassisManagerUtil.CheckIfUserExistsInGroup(userName, role))
                {
                    // Find group if not exists create new
                    grp = ChassisManagerUtil.FindGroupIfNotExistsCreate(role);

                    if (grp != null)
                    {
                        // Add user to group
                        grp.Invoke("Add", new object[] { myEntry.Path.ToString() });
                        grp.CommitChanges();
                        grp.Close();
                    }
                    else
                    {
                        Tracer.WriteError("ChangeChassisControllerUserRole: Failed to change user role, failed to find/add group");
                        response.completionCode = Contracts.CompletionCode.Failure;
                        response.statusDescription = String.Format("ChangeChassisControllerUserRole: Failed to change user role, failed to find/add group");
                        return response;
                    }
                }

                Tracer.WriteInfo("ChangeChassisControllerUserRole: Role changed successfully");
                response.completionCode = Contracts.CompletionCode.Success;
                return response;
            }
            catch (Exception ex)
            {
                Tracer.WriteError("ChangeChassisControllerUserRole: failed with exception: " + ex);

                // user already belongs to the role, we don't need any action hence consider it success
                if (ex.ToString().Contains("The specified account name is already a member of the group"))
                {
                    response.completionCode = Contracts.CompletionCode.Success;
                }
                // check if password did not meet the requirements, display appropriate message to user.
                else if (ex.ToString().Contains("0x800708C5") || ex.ToString().Contains("password does not meet"))
                {
                    response.completionCode = Contracts.CompletionCode.UserPasswordDoesNotMeetRequirement;
                    response.statusDescription = "User password does not meet system requirements";
                }
                // check the exception code for user not found
                else if (ex.ToString().Contains("0x800708AD"))
                {
                    response.completionCode = Contracts.CompletionCode.UserNotFound;
                    response.statusDescription = "User name provided cannot be found";
                }
                else
                {
                    response.completionCode = Contracts.CompletionCode.Failure;
                    response.statusDescription = String.Format("ChangeChassisControllerUserRole failed. Unknown Error.");
                }
                return response;
            }
        }
        /// <summary>
        /// Stops serial session on a port
        /// </summary>
        public Contracts.ChassisResponse StopSerialPortConsole(int portId, string sessionToken, bool forceKill)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            Tracer.WriteUserLog("Invoked StopSerialPortConsole(portId: {0}, sessionToken: {1})", portId, sessionToken);
            Tracer.WriteInfo("Received StopSerialPortConsole({0})", portId);

            if (ChassisManagerUtil.CheckSerialConsolePortId((byte)portId) != (byte)CompletionCode.Success)
            {
                response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                Tracer.WriteWarning("StopSerialPortConsole failed: Port ID out of range " + portId);
                response.statusDescription = String.Format("StopSerialPortConsole failed: Port ID out of range " + portId);
                return response;
            }

            int portIndex = ChassisManagerUtil.GetSerialConsolePortIndexFromId(portId);
            response = ChassisState.SerialConsolePortsMetadata[portIndex].StopSerialPortConsole(ChassisManagerUtil.GetSerialConsolePortIdFromIndex(portIndex), sessionToken, forceKill);

            if (ChassisManagerUtil.CheckCompletionCode(response.completionCode))
            {
                Tracer.WriteInfo("StopSerialPortConsole succeeded for portId: " + portId);
            }
            else
            {
                Tracer.WriteError("StopSerialPortConsole: failed for portId: {0} with completion code: {1}", portId, response.completionCode.ToString());
                response.statusDescription = String.Format("StopSerialPortConsole: failed for portId: {0} with completion code: {1}", portId, response.completionCode.ToString());
            }
            return response;
        }
        /// <summary>
        /// Method to remove user. **TO-DO* Authenticate who can Add/delete user.
        /// </summary>
        /// <param name="userName">User Name</param>
        /// <returns>Chassis Response to indicate if reomve user operation was success/failure</returns>
        public Contracts.ChassisResponse RemoveChassisControllerUser(string userName)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            Tracer.WriteUserLog("Invoked RemoveChassisControllerUser(userName: {0})", userName);
            try
            {
                userName = userName.Trim();

                if (userName == null)
                {
                    Tracer.WriteError("RemoveChassisControllerUser: Invalid input parameters.");
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    response.statusDescription = "Username is null";
                    return response;
                }

                DirectoryEntry AD = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
                DirectoryEntry myEntry = AD.Children.Find(userName, "user");
                AD.Children.Remove(myEntry);
                Tracer.WriteInfo("RemoveChassisControllerUser: User Account deleted Successfully");
                response.completionCode = Contracts.CompletionCode.Success;

                return response;
            }
            catch (Exception ex)
            {
                Tracer.WriteError("RemoveChassisControllerUser: failed with exception: " + ex);

                // check the exception code for password did not meet the requirements, display appropriate message to user.
                if (ex.ToString().Contains("0x800708C5") || ex.ToString().Contains("password does not meet"))
                {
                    response.completionCode = Contracts.CompletionCode.UserPasswordDoesNotMeetRequirement;
                    response.statusDescription = "User password does not meet system requirements";
                }
                // check the exception code for user not found
                else if (ex.ToString().Contains("0x800708AD"))
                {
                    response.completionCode = Contracts.CompletionCode.UserNotFound;
                    response.statusDescription = "User not found";
                }
                else
                {
                    response.completionCode = Contracts.CompletionCode.Failure;
                    response.statusDescription = String.Format("RemoveChassisControllerUser failed. Unknown Error.");
                }
                return response;
            }
        }
        /// <summary>
        /// Check Blade Firmware State
        /// </summary>
        /// <param name="bladeId"></param>
        private Contracts.ChassisResponse CheckBladeAndFirmwareState(byte bladeId)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();

            BladePowerStatePacket powerState = FunctionValidityChecker.CheckBladeStateValidity(bladeId);

            if (powerState.PowerStatus == PowerState.OFF)
            {
                Tracer.WriteInfo("Blade: {0} Current Power State: {1}", bladeId, powerState.PowerStatus);

                response.completionCode = Contracts.CompletionCode.DevicePoweredOff;
                response.statusDescription = Contracts.CompletionCode.DevicePoweredOff.ToString();
                return response;
            }
            else if (powerState.PowerStatus == PowerState.ON)
            {
                if (powerState.DecompressionTime > 0)
                {
                    response.completionCode = Contracts.CompletionCode.FirmwareDecompressing;
                    response.statusDescription = string.Format("Decompression Time Remaining {0}", powerState.DecompressionTime);
                    return response;
                }
            }

            response.completionCode = Contracts.CompletionCode.Success;
            response.statusDescription = "Command Completed Successfully";
            return response;
        }
        /// <summary>
        /// Turns a power supply off and on
        /// </summary>
        public Contracts.ChassisResponse ResetPsu(int psuId)
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();

            if (ConfigLoaded.NumPsus > 0)
            {
                if (psuId < 0 || psuId > ConfigLoaded.NumPsus)
                {
                    response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                    return response;
                }

                // Step 1: Turn Psu off
                byte completionCode = (byte)ChassisState.Psu[(psuId - 1)].SetPsuOnOff(true);
                if (completionCode != (byte)CompletionCode.Success)
                {
                    Tracer.WriteWarning("Error on psu power off: PsuId {0} CompletionCode: 0x{1:X2}",
                        psuId, completionCode);

                    response.completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping(completionCode);
                }
                else
                {
                    // subsequent commands are permitted to change upon failure.
                    response.completionCode = Contracts.CompletionCode.Success;
                }

                // Step 2: Turn Psu On
                completionCode = (byte)ChassisState.Psu[(psuId - 1)].SetPsuOnOff(false);
                if (completionCode != (byte)CompletionCode.Success)
                {
                    Tracer.WriteWarning("Error on psu power on: PsuId {0} CompletionCode: 0x{1:X2}",
                        psuId, completionCode);

                    response.completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping(completionCode);
                }
            }
            else
            {
                response.completionCode = Contracts.CompletionCode.CommandNotValidAtThisTime;
                response.statusDescription += "\nPower Supply control not supported in sku configuration.";
            }

            return response;
        }
        /// <summary>
        /// Adds string description to Chassis Response status description
        /// </summary>
        private Contracts.ChassisResponse ValidateRequest(string cmd, int bladeId)
        {
            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();

            // Check blade ID is valid
            if (ChassisManagerUtil.CheckBladeId(bladeId) == CompletionCode.InvalidBladeId)
            {
                Tracer.WriteWarning("{0} failed, Invalid blade Id {1}", cmd, bladeId);

                varResponse.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                varResponse.statusDescription = Contracts.CompletionCode.ParameterOutOfRange.ToString();
                return varResponse;
            }

            if (!FunctionValidityChecker.CheckBladeTypeValidity((byte)bladeId))
            {
                Tracer.WriteWarning("{0} failed, Invalid blade Type {1}", cmd, bladeId);

                varResponse.completionCode = Contracts.CompletionCode.CommandNotValidForBlade;
                varResponse.statusDescription = Contracts.CompletionCode.CommandNotValidForBlade.ToString();
                return varResponse;
            }

            return CheckBladeAndFirmwareState((byte)bladeId);
        }
        /// <summary>
        /// Restore SNTP Time Service
        /// </summary>
        public Contracts.ChassisResponse RestoreSntpServer()
        {
            Contracts.ChassisResponse response = new Contracts.ChassisResponse();

            Tracer.WriteInfo("Received RestoreSntpServer()");
            Tracer.WriteUserLog("Received RestoreSntpServer()");

            CompletionCode code = Sntp.RestoreNtpServerDefault();

            if (code == CompletionCode.CannotExecuteRequestInvalidState)
            {
                response.completionCode = Contracts.CompletionCode.Unknown;
                response.statusDescription = "Win32Time service not responding";
            }
            else
            {
                response.completionCode = ChassisManagerUtil.GetContractsCompletionCodeMapping((byte)code);
            }

            return response;
        }
        /// <summary>
        /// Get power state of all blades
        /// </summary>
        /// <returns>Collection of Blade State response packets</returns>
        public GetAllPowerStateResponse GetAllPowerState()
        {
            byte MaxbladeCount = (byte)ConfigLoaded.Population;

            GetAllPowerStateResponse responses = new GetAllPowerStateResponse();
            responses.completionCode = Contracts.CompletionCode.Unknown;
            responses.statusDescription = string.Empty;
            responses.powerStateResponseCollection = new List<PowerStateResponse>();
            Contracts.CompletionCode[] bladeInternalResponseCollection = new Contracts.CompletionCode[MaxbladeCount];
            uint bladeCount = MaxbladeCount;

            Tracer.WriteUserLog("Invoked GetAllPowerState()");
            Tracer.WriteInfo("Invoked GetAllPowerState()");

            for (int loop = 0; loop < bladeCount; loop++)
            {
                responses.powerStateResponseCollection.Add(GetPowerState(loop + 1));
                Tracer.WriteInfo("Blade power state: ", responses.powerStateResponseCollection[loop].powerState);

                // Set the internal blade response to the blade completion code.
                bladeInternalResponseCollection[loop] = responses.powerStateResponseCollection[loop].completionCode;
            }

            Contracts.ChassisResponse varResponse = new Contracts.ChassisResponse();
            varResponse = ChassisManagerUtil.ValidateAllBladeResponse(bladeInternalResponseCollection);
            responses.completionCode = varResponse.completionCode;
            responses.statusDescription = varResponse.statusDescription;
            return responses;
        }
        /// <summary>
        /// Turn on AC socket within the chassis 
        /// </summary>
        /// <param name="portNo">Port no corresponding to the AC sockets internal to the chassis like TOR switches</param>
        /// <returns>Chassis Response success/failure</returns>
        public Contracts.ChassisResponse SetACSocketPowerStateOn(uint portNo)
        {
            Tracer.WriteInfo("Received SetACSocketPowerStateOn({0})", portNo);

            Tracer.WriteUserLog("Invoked SetACSocketPowerStateOn(portNo: {0})", portNo);

            Contracts.ChassisResponse response = new Contracts.ChassisResponse();
            response.completionCode = Contracts.CompletionCode.Unknown;
            response.statusDescription = String.Empty;

            // Validate port number
            if (!ChassisManagerUtil.CheckPortValidity(portNo))
            {
                Tracer.WriteError("SetACSocketPowerStateOn: Input port number is invalid {0}", portNo);
                response.completionCode = Contracts.CompletionCode.ParameterOutOfRange;
                response.statusDescription = "Port Number is invalid";
                return response;
            }

            AcSocket acSocket = ChassisState.AcPowerSockets[portNo - 1];
            byte status = acSocket.turnOnAcSocket();

            Tracer.WriteInfo("Return: {0}", status);

            if (status != (byte)CompletionCode.Success)
            {
                Tracer.WriteWarning("AC Socket Turn On Failed with Completion code {0:X}", status);
                response.completionCode = Contracts.CompletionCode.Failure;
                response.statusDescription = String.Format("AC Socket Turn On Failed with Completion code {0:X}", status);
            }
            else
            {
                response.completionCode = Contracts.CompletionCode.Success;
            }
            return response;
        }