// UNCLASSIFIED /*------------------------------------------------------------------------- RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON COMPANY. THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S. GOVERNMENT. UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. -------------------------------------------------------------------------*/ using System; using System.Runtime.InteropServices; using System.Threading; using NLog; using Raytheon.Common; using Raytheon.Instruments; namespace BitMeasurementManagerLib { /// /// An interface to sending/receiving data over TCP sockets /// internal class BitSimCommDeviceNode : ICommDevice, IDisposable { #region PrivateClassMembers private ICommDevice _commDevice; private BitMessageIDs _messageIds; private IWorkerInterface _socketReadWorker; private Thread _socketReadThread; private readonly string _name; private SelfTestResult _selfTestResult; private State _state; private readonly ILogger _logger; #endregion #region PrivateFunctions /// /// The finalizer. Necessary for quitting the read thread /// ~BitSimCommDeviceNode() { Dispose(false); } /// /// Quit the threads associated with the node /// /// protected virtual void Dispose(bool disposing) { if (disposing) { State initialState = _state; // close the socket and threads if (initialState == State.Ready) { Shutdown(); _commDevice.Shutdown(); } // dispose of the resources if (initialState == State.Ready) { _socketReadWorker.Dispose(); _state = State.Uninitialized; } } } #endregion #region PublicFuctions /// /// /// /// The name of this instance /// /// /// /// public BitSimCommDeviceNode(string name, ICommDevice commDevice, BitMessageIDs messageIds, MsgDevice msgHandler, uint commReadWorkerBufferSize = 100000, uint readWorkerRestTimeInMs = 10) { _logger = LogManager.GetCurrentClassLogger(); _name = name; _commDevice = commDevice; _messageIds = messageIds; _socketReadWorker = new CommReadWorker(this, msgHandler, commReadWorkerBufferSize, readWorkerRestTimeInMs); _socketReadThread = new Thread(_socketReadWorker.DoWork); // start the read thread _socketReadThread.Start(); _selfTestResult = SelfTestResult.Unknown; _state = State.Uninitialized; } public void Open() { } /// /// /// /// public bool ClearErrors() { return true; } /// /// /// public bool DisplayEnabled { get { return false; } set { throw new NotImplementedException(); } } /// /// /// public string DetailedStatus { get { return "This is a BIT Comm Sim Device Node " + _name; } } public void Close() { Dispose(); } /// /// /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// /// public bool FrontPanelEnabled { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } /// /// /// public InstrumentMetadata Info { get { throw new NotImplementedException(); } } /// /// /// public void Initialize() { _commDevice.Initialize(); _state = State.Ready; } /// /// /// public string Name { get { return _name; } } /// /// /// /// public SelfTestResult PerformSelfTest() { return _commDevice.SelfTestResult; } /// /// Read data from the socket /// /// The data that was read /// the number of bytes read public uint Read(ref byte[] dataRead) { return 0; } /// /// public void Reset() { Close(); Initialize(); } /// /// /// /// public void SetReadTimeout(uint readTimeout) { } /// /// /// public SelfTestResult SelfTestResult { get { return _selfTestResult; } } /// /// /// public State Status { get { return _state; } } /// /// /// public void Shutdown() { const int THREAD_QUIT_TIMEOUT_MS = 3000; if (_state == State.Ready) { // tell the thread to quit _socketReadWorker.QuitWork(); // close the socket which the thread might be blocked on _commDevice.Shutdown(); if (_socketReadThread.IsAlive) { bool didThreadQuit = _socketReadThread.Join(THREAD_QUIT_TIMEOUT_MS); if (didThreadQuit == false) { _logger.Debug("Logging Thread did not quit as expected, aborting it"); _socketReadThread.Abort(); } else { _logger.Debug("Logging Thread quit successfully after join"); } } else { _logger.Debug("Logging Thread quit successfully"); } } _state = State.Uninitialized; } /// /// Send data on the socket /// /// The data to send /// The number of bytes to write from the dataToSend buffer /// The number of bytes sent public uint Write(byte[] dataToSend, uint numBytesToWrite) { // determine the id and get create the rsp message IntPtr pDataPtr = Marshal.AllocHGlobal(dataToSend.Length); Marshal.Copy(dataToSend, 0, pDataPtr, dataToSend.Length); uint commandId = BitConfigurableMessageHeader.GetMessageId(pDataPtr, (uint)dataToSend.Length); Marshal.FreeHGlobal(pDataPtr); bool isThereAResponse = _messageIds.IsThereAResponseMessage(commandId); // if there is a rsp msg, create a dummy msg if (isThereAResponse == true) { uint rspId = _messageIds.GetResponseId(commandId); BitConfigurableMessage rspMessage = BitConfigurableMessageFactory.Instance().RetreiveMessage(rspId); BitMsgRxBuffer.Instance().AddMsg(rspMessage); //uint msgLen = rspMessage.GetEntireMsgLength(); //byte[] simData = new byte[msgLen]; //_msgHandler.AddData(); } else { } return (uint)dataToSend.Length; } #endregion } }