/// <summary> /// Clear the queued requests and release the requests' /// MsgResponse lock signal. /// </summary> private void ClearRequests() { lock (SyncRoot) { MsgRequest[] reqs = GetRequests(); if (reqs != null) { for (int i = 0; i < reqs.Length; i++) { MsgRequest req = DequeueRequest(reqs[i].ReqMsgId); if (req != null) { try { req.Response.SetResponse(); } catch (ThreadStateException) { ; // do nothing } } } } } }
/// <summary> /// Get the queued requests. /// </summary> /// <returns><see cref="MsgRequest"/> object array</returns> private MsgRequest[] GetRequests() { MsgRequest[] reqs = null; if (m_Requests.Count > 0) { // make a copy of all the request objects first reqs = new MsgRequest[m_Requests.Count]; m_Requests.CopyTo(reqs, 0); } return(reqs); }
/// <summary> /// Send a Hart-IP Request /// </summary> /// <param name="Request"><see cref="HartIPRequest"></see></param> /// <param name="MsgRsp"><see cref="MsgResponse"></see></param> /// <para>see the HartIPRequest.Command for HART specification references.</para> /// <returns>bool if it is success</returns> public bool SendHartRequest(HartIPRequest Request, MsgResponse MsgRsp) { bool bSuccess = false; if (Request == null) { throw new ArgumentException("Invalid argument in SendHartRequest."); } lock (SyncRoot) { m_Error = String.Empty; try { if (m_RspMsgReader == null) { // Create a thread that is constantly reading on the input stream m_bStopped = false; m_RspMsgReader = new Thread(new ThreadStart(this.ReceiveMsg)); m_RspMsgReader.Name = "HartIPConnection"; m_RspMsgReader.Start(); } // add the request object into the m_Requests list MsgRequest MsgReq = new MsgRequest(Request.TransactionId, MsgRsp); m_Requests.Add(MsgReq); // send the request bSuccess = SendRequest(Request); LogMsg.Instance.Log(Request.ToString()); } catch (SocketException se) { m_Error = String.Format("SendHartRequest SocketException: ErrorCode:{0}. {1}", se.ErrorCode, se.Message); LogMsg.Instance.Log("Error, " + m_Error, true); } catch (Exception e) { m_Error = String.Format("SendHartRequest Exception: {0}", e.Message); LogMsg.Instance.Log("Error, " + m_Error, true); } if (!bSuccess) { LogMsg.Instance.Log("Error, Failed sending Request: " + Request.ToString(), true); DequeueRequest(Request.TransactionId); } } return(bSuccess); }
/// <summary> /// Continue get Hart-IP Response from the connected stream. /// Remove the received request from the list and release the /// MsgResponse lock signal. /// </summary> private void ReceiveMsg() { bool stoploop; lock (SyncRoot) { stoploop = m_bStopped; } while (!stoploop) { try { HartIPResponse Rsp = GetResponse(); if (Rsp == null) { continue; } m_lLastActivityTime = DateTime.Now.Ticks; if (Rsp.MessageType == HARTIPMessage.HART_ACK) { MsgRequest Req = DequeueRequest(Rsp.TransactionId); if (Req != null) { Req.Response.SetResponse(Rsp); } else { // just in case can't find the request in the list LogMsg.Instance.Log(Rsp.ToString()); } } else { if ((Rsp.MessageType == HARTIPMessage.HART_PUBLISH_NOTIFY) && (PublishedCmdNotify != null)) { HartIPResponseArg Arg = new HartIPResponseArg(Rsp); PublishedCmdNotify(this, Arg); } else { LogMsg.Instance.Log(Rsp.ToString()); } } } catch (SocketException se) { int nErrorCode = se.ErrorCode; // socket receive timeout if ((nErrorCode == 10060) || (nErrorCode == 10035)) { if (m_nConnection != UDP) { break; } } // socket closed, server close the connection or interrupted else if ((nErrorCode == 995) || (nErrorCode == 10004) || (nErrorCode == 10054)) { break; } else { LogMsg.Instance.Log("Error, ReceiveMsg SocketException: ErrorCode:" + nErrorCode + ". " + se.Message, true); break; } } catch (EndOfStreamException e) { LogMsg.Instance.Log("Error, ReceiveMsg EndOfStreamException: " + e.Message, true); break; } catch (IOException io) { if (m_nConnection != TCP) { LogMsg.Instance.Log("Error, ReceiveMsg IOException: " + io.Message, true); break; } } catch (ObjectDisposedException obex) { LogMsg.Instance.Log("Error, ReceiveMsg Expection :" + obex.Message, true); break; } catch (ThreadStateException tsEx) { // caller failed to release the lock signal and it will timeout LogMsg.Instance.Log("Error, ReceiveMsg ThreadStateException: " + tsEx.Message, true); } } ClearRequests(); }