/// <summary> /// Copy constructor /// </summary> /// <param name="message"></param> public Message(Message message) : base(message) { Revision = message.Revision; mSpindleID = message.mSpindleID; mStationID = message.mStationID; NoAck = message.NoAck; }
public Client() : base() { mInitialized = false; mCommStarted = false; mTorqueEventSubscribed = false; mKeepAliveMessage = new Message(MessageType.KeepAlive); mConnetionInterval = 500; mKeepAliveInterval = 5000; mTorqueIDs = new List<int>(); }
protected void OnMessageReceived(Message message) { mLastResponse = DateTime.Now; if (message.MID == MessageType.KeepAlive) return; if (message.MID == MessageType.LastTighteningResultUpload) { ThreadPool.QueueUserWorkItem(OnTorqueEventReceived, message); } else { switch (mMessage.MID) { case MessageType.CommunicationStart: mCommStarted = (mMessage.Success == message.MID); break; case MessageType.LastTighteningResultSubscribe: mTorqueEventSubscribed = (mMessage.Success == message.MID); break; } } }
protected void SendMessage(Message message) { if (mSocket == null || !mSocket.Connected) return; Send(message.ToByteArray()); }
public static bool TryParse(byte[] data, out Message message) { try { message = Message.Parse(data); return true; } catch { message = null; return false; } }
protected void ConnectionCallback(object state) { if (!Connected) { mLastResponse = DateTime.Now; mCommStarted = false; mTorqueEventSubscribed = false; base.Connect(); } else if(!mCommStarted) { if (mMessage == null || mMessage.Age > 2000 || mMessage.MID != MessageType.CommunicationStart) { mMessage = new Message(MessageType.CommunicationStart); mMessage.Success = MessageType.CommunicationStartAck; SendMessage(mMessage); } } else if (!mTorqueEventSubscribed) { if (mMessage == null || mMessage.Age > 2000 || mMessage.MID != MessageType.LastTighteningResultSubscribe) { mMessage = new Message(MessageType.LastTighteningResultSubscribe); SendMessage(mMessage); } } int age = (int)(DateTime.Now - mLastResponse).TotalMilliseconds; if (Connected && (age > mKeepAliveInterval)) { SendMessage(mKeepAliveMessage); } if (Connected && (age > (mKeepAliveInterval * 3))) { Disconnect(); } }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Syncronous Send. Sends a message to the torque controller and waits 2 seconds for /// the response. This function retries 3 times. Returns the reponse if successful, /// null otherwise. /// </summary> /// <param name="message">The message to send</param> /// <param name="success">The message exepected in response</param> /// <returns></returns> /////////////////////////////////////////////////////////////////////////////////////////// private Message Send(Message message, MessageType success) { return Send(message, success, 1000, 2); }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Syncronous Send. Sends a message to the torque controller and waits for /// the response. Returns the reponse if successful, null otherwise. /// </summary> /// <param name="message">The message to send</param> /// <param name="success">The message exepected in response</param> /// <param name="timeout">The time to wait between retries</param> /// <param name="retries">The number of send attempts before aborting</param> /// <returns></returns> /////////////////////////////////////////////////////////////////////////////////////////// private Message Send(Message message, MessageType success, int timeout, int retries) { lock (mSendLock) { Message result = null; int count = timeout / 50; //Determine loop count to satisfy the timeout if (Connected) { mResult = null; //Send the message and retry if necessary for (int i = 0; i <= retries; i++) { //Send the message and wait for a response Send(message); for (int j = 0; j < count; j++) { result = mResult; //Make sure that the result is the response to THIS message if (result != null && (result.Command == success || result.Command == MessageType.CommandError)) { return result; } else { //If no response then sleep and check again. result = null; Thread.Sleep(50); } if (!Connected) break; //In case we lost connection while sending; } if (!Connected) break; //In case we lost connection while sending; } } return (Message)result; } }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Asyncronous Send. Sends a message to the torque controller and returns immediately /// </summary> /// <param name="message">The message to send</param> /////////////////////////////////////////////////////////////////////////////////////////// private void Send(Message message) { if (!Connected) return; mClient.Send(message); //Update keep alive timestamp so it is not sent more than it needs to be mKeepAlive.TimeStamp = DateTime.Now; }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Called each time the client thread is executed /// </summary> /////////////////////////////////////////////////////////////////////////////////////////// private void mClient_ThreadCallback(object sender, EventArgs e) { //If we are not connected set all flags to false if (!Connected) { mCommunicationStarted = false; mTorqueEventSubscribed = false; mAlarmEventSubscribed = false; mStatus = OpenProtocolStatus.Disconnected; } else { StartCommunication(); SubscribeToLastTighteningResult(); if (mCommunicationStarted && mLastSetTime < DateTime.Now.AddHours(4)) { Message setTime = new Message(MessageType.SetTime); mLastSetTime = DateTime.Now.AddMilliseconds(500); // Add 500 milliseconds for transfer time. setTime.Data = mLastSetTime.ToString("yyyy-MM-dd:HH:mm:ss"); Send(setTime, MessageType.CommandAccepted); } if (mTorqueEventSubscribed) { mStatus = (mEnabled) ? OpenProtocolStatus.Running : OpenProtocolStatus.Disabled; } else { mStatus = OpenProtocolStatus.Initializing; } } }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Called each time the client receives a new message /// </summary> /////////////////////////////////////////////////////////////////////////////////////////// private void mClient_MessageReceived(object sender, MessageReceivedEventArgs<Message> e) { Message result = null; if (e.Message is Message) { switch (e.Message.Command) { case MessageType.CommandError: if (!CommandError.TryParse(e.Message, out result)) { System.Diagnostics.Debug.Write("Error parsing received CommandError"); return; }; break; case MessageType.OldTighteningResultUpload: if (!OldTighteningResultUpload.TryParse(e.Message, out result)) { System.Diagnostics.Debug.Write("Error parsing received OldTighteningResultUpload"); return; }; break; case MessageType.LastTighteningResultUpload: if (LastTighteningResultUpload.TryParse(e.Message, out result)) { OnLastTighteningResultUpload((LastTighteningResultUpload)result); } else { System.Diagnostics.Debug.Write("Error parsing received LastTighteningResultUpload"); return; } return; //Must return because this is an event driven messate and we do not want to sent mResult //All others are responses to sent messages so set mResult default: mResult = e.Message; return; } if (result != null) mResult = result; } }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Starts communication with the torque controller /// </summary> /////////////////////////////////////////////////////////////////////////////////////////// public bool StartCommunication() { if (!Connected || mCommunicationStarted) return mCommunicationStarted; //Send message to start communication Message result = Send(new Message(MessageType.CommunicationStart), MessageType.CommunicationStartAck); if (result != null && result.Command == MessageType.CommunicationStartAck) { mCommunicationStarted = true; } else { Disconnect(); } //Always sync the time when starting communication if (mCommunicationStarted) { Message setTime = new Message(MessageType.SetTime); mLastSetTime = DateTime.Now.AddMilliseconds(500); // Add 500 milliseconds for transfer time. setTime.Data = mLastSetTime.ToString("yyyy-MM-dd:HH:mm:ss"); Send(setTime, MessageType.CommandAccepted); //Make sure tool state is syncronized if (mEnabled) { SendEnable(); } else { SendDisable(); } //Make sure last tightening id is syncronized. Request with 0 returns last result //Check for missing torque values if in auto mode and missing torques exist OldTighteningResultUpload last = null; if (RequestOldTighteningResult(0, out last)) { if (mLastTighteningID == last.TighteningID || mLastTighteningID == 0 || (mFlags & OpenProtocolFlags.AutoMode) != OpenProtocolFlags.AutoMode) { mLastTighteningID = last.TighteningID; } else { RecoverTighteningResults(mLastTighteningID, last.TighteningID); } } } return mCommunicationStarted; }
/////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Initializes the Client object /// </summary> /// <param name="host">IP address or host name of the remote host</param> /// <param name="port">Port number of the remote host</param> /////////////////////////////////////////////////////////////////////////////////////////// public void Initialize(string host, int port) { mLastTighteningID = 0; mTighteningIDs = new List<UInt32>(); if (mFlags == OpenProtocolFlags.AutoMode) { mClient = new TCPClient<Message>(host, port, ClientFlags.AutoConnect | ClientFlags.AutoKeepAlive); mClient.Disconnected += new EventHandler(mClient_Disconnected); mClient.MessageReceived += new MessageReceivedEventHandler<Message>(mClient_MessageReceived); mKeepAlive = new Message(MessageType.KeepAlive); mClient.SetKeepAlive(mKeepAlive, 5000); mClient.ThreadCallback += new EventHandler(mClient_ThreadCallback); } else { mClient = new TCPClient<Message>(host, port, ClientFlags.None); } mPSet = 0; //Default to 1 mClient.STX = null; mClient.ETX = 0x00; mTorqueEventLock = new object(); mSendLock = new object(); mInitialized = true; }