private void SendDisconnect(BacnetPtpDisconnectReasons bacnetPtpDisconnectReasons) { var buffer = new byte[PTP.PTP_HEADER_LENGTH + 1 + 2]; buffer[PTP.PTP_HEADER_LENGTH] = (byte)bacnetPtpDisconnectReasons; SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_DISCONNECT_REQUEST, buffer, 1); }
private void SendDisconnect(BacnetPtpFrameTypes bacnetPtpFrameTypes, BacnetPtpDisconnectReasons bacnetPtpDisconnectReasons) { byte[] buffer = new byte[PTP.PTP_HEADER_LENGTH + 1 + 2]; buffer[PTP.PTP_HEADER_LENGTH] = (byte)bacnetPtpDisconnectReasons; SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_DISCONNECT_REQUEST, buffer, 1); }
private void ptp_thread() { byte[] buffer = new byte[MaxBufferLength]; try { while (m_port != null) { //connect if needed if (!m_is_connected) { if (!Reconnect()) { Thread.Sleep(1000); continue; } } //read message int offset = 0; BacnetPtpFrameTypes frame_type; int msg_length; BacnetMstpProtocolTransport.GetMessageStatus status = GetNextMessage(buffer, ref offset, T_HEARTBEAT, out frame_type, out msg_length); //action switch (status) { case BacnetMstpProtocolTransport.GetMessageStatus.ConnectionClose: case BacnetMstpProtocolTransport.GetMessageStatus.ConnectionError: Trace.TraceWarning("Connection disturbance"); Reconnect(); break; case BacnetMstpProtocolTransport.GetMessageStatus.DecodeError: Trace.TraceWarning("PTP decode error"); break; case BacnetMstpProtocolTransport.GetMessageStatus.SubTimeout: Trace.TraceWarning("PTP frame abort"); break; case BacnetMstpProtocolTransport.GetMessageStatus.Timeout: SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XON); //both server and client will send this break; case BacnetMstpProtocolTransport.GetMessageStatus.Good: //action switch (frame_type) { case BacnetPtpFrameTypes.FRAME_TYPE_GREETING: //request connection SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_CONNECT_REQUEST); break; case BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XON: m_may_send.Set(); break; case BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XOFF: m_may_send.Reset(); break; case BacnetPtpFrameTypes.FRAME_TYPE_DATA0: //send confirm SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_DATA_ACK0_XON); //notify the sky! if (MessageRecieved != null) { MessageRecieved(this, buffer, PTP.PTP_HEADER_LENGTH, msg_length, GetBroadcastAddress()); } break; case BacnetPtpFrameTypes.FRAME_TYPE_DATA1: //send confirm SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_DATA_ACK1_XON); //notify the sky! if (MessageRecieved != null) { MessageRecieved(this, buffer, PTP.PTP_HEADER_LENGTH, msg_length, GetBroadcastAddress()); } break; case BacnetPtpFrameTypes.FRAME_TYPE_DATA_ACK0_XOFF: case BacnetPtpFrameTypes.FRAME_TYPE_DATA_ACK1_XOFF: //so, the other one got the message, eh? m_may_send.Reset(); break; case BacnetPtpFrameTypes.FRAME_TYPE_DATA_ACK0_XON: case BacnetPtpFrameTypes.FRAME_TYPE_DATA_ACK1_XON: //so, the other one got the message, eh? m_may_send.Set(); break; case BacnetPtpFrameTypes.FRAME_TYPE_DATA_NAK0_XOFF: case BacnetPtpFrameTypes.FRAME_TYPE_DATA_NAK1_XOFF: m_may_send.Reset(); //denial, eh? break; case BacnetPtpFrameTypes.FRAME_TYPE_DATA_NAK0_XON: case BacnetPtpFrameTypes.FRAME_TYPE_DATA_NAK1_XON: m_may_send.Set(); //denial, eh? break; case BacnetPtpFrameTypes.FRAME_TYPE_CONNECT_REQUEST: //also send a password perhaps? if (!string.IsNullOrEmpty(m_password)) { byte[] pass = Encoding.ASCII.GetBytes(m_password); byte[] tmp_buffer = new byte[PTP.PTP_HEADER_LENGTH + pass.Length + 2]; Array.Copy(pass, 0, tmp_buffer, PTP.PTP_HEADER_LENGTH, pass.Length); SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_CONNECT_RESPONSE, tmp_buffer, pass.Length); } else { SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_CONNECT_RESPONSE); } //we're ready SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XON); break; case BacnetPtpFrameTypes.FRAME_TYPE_CONNECT_RESPONSE: if (msg_length > 0 && !string.IsNullOrEmpty(m_password)) { string password = Encoding.ASCII.GetString(buffer, PTP.PTP_HEADER_LENGTH, msg_length); if (password != m_password) { SendDisconnect(BacnetPtpFrameTypes.FRAME_TYPE_DISCONNECT_REQUEST, BacnetPtpDisconnectReasons.PTP_DISCONNECT_INVALID_PASSWORD); } else { SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XON); //we're ready } } else { //we're ready SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XON); } break; case BacnetPtpFrameTypes.FRAME_TYPE_DISCONNECT_REQUEST: BacnetPtpDisconnectReasons reason = BacnetPtpDisconnectReasons.PTP_DISCONNECT_OTHER; if (msg_length > 0) { reason = (BacnetPtpDisconnectReasons)buffer[PTP.PTP_HEADER_LENGTH]; } SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_DISCONNECT_RESPONSE); Trace.WriteLine("Disconnect requested: " + reason, null); Reconnect(); break; case BacnetPtpFrameTypes.FRAME_TYPE_DISCONNECT_RESPONSE: m_may_send.Reset(); //hopefully we'll be closing down now break; case BacnetPtpFrameTypes.FRAME_TYPE_TEST_REQUEST: SendFrame(BacnetPtpFrameTypes.FRAME_TYPE_TEST_RESPONSE, buffer, msg_length); break; case BacnetPtpFrameTypes.FRAME_TYPE_TEST_RESPONSE: //good break; } break; } } Trace.WriteLine("PTP thread is closing down", null); } catch (Exception ex) { Trace.TraceError("Exception in PTP thread: " + ex.Message); } }