System.IO.BACnet.BacnetPtpProtocolTransport.ptp_thread C# (CSharp) Method

ptp_thread() private method

private ptp_thread ( ) : void
return void
        private void ptp_thread()
        {
            byte[] buffer = new byte[MaxBufferLength];
            try
            {
                while (m_port != null)
                {
                    //connect if needed
                    if (!m_is_connected)
                    {
                        if (!Reconnect())
                        {
                            System.Threading.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 = System.Text.ASCIIEncoding.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 = System.Text.ASCIIEncoding.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.ToString(), 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);
            }
        }