System.IO.BACnet.BacnetMstpProtocolTransport.GetNextMessage C# (CSharp) Method

GetNextMessage() private method

private GetNextMessage ( int timeout_ms, BacnetMstpFrameTypes &frame_type, byte &destination_address, byte &source_address, int &msg_length ) : GetMessageStatus
timeout_ms int
frame_type BacnetMstpFrameTypes
destination_address byte
source_address byte
msg_length int
return GetMessageStatus
        private GetMessageStatus GetNextMessage(int timeout_ms, out BacnetMstpFrameTypes frame_type, out byte destination_address, out byte source_address, out int msg_length)
        {
            int timeout;

            frame_type = BacnetMstpFrameTypes.FRAME_TYPE_TOKEN;
            destination_address = 0;
            source_address = 0;
            msg_length = 0;

            //fetch header
            while (m_local_offset < MSTP.MSTP_HEADER_LENGTH)
            {
                if (m_port == null) return GetMessageStatus.ConnectionClose;

                if (m_local_offset > 0)
                    timeout = T_FRAME_ABORT;    //set sub timeout
                else
                    timeout = timeout_ms;       //set big silence timeout

                //read
                int rx = m_port.Read(m_local_buffer, m_local_offset, MSTP.MSTP_HEADER_LENGTH - m_local_offset, timeout);
                if (rx == -ETIMEDOUT)
                {
                    //drop message
                    GetMessageStatus status = m_local_offset == 0 ? GetMessageStatus.Timeout : GetMessageStatus.SubTimeout;
                    m_local_buffer[0] = 0xFF;
                    RemoveGarbage();
                    return status;
                }
                else if (rx < 0)
                {
                    //drop message
                    m_local_buffer[0] = 0xFF;
                    RemoveGarbage();
                    return GetMessageStatus.ConnectionError;
                }
                else if (rx == 0)
                {
                    //drop message
                    m_local_buffer[0] = 0xFF;
                    RemoveGarbage();
                    return GetMessageStatus.ConnectionClose;
                }
                m_local_offset += rx;

                //remove paddings & garbage
                RemoveGarbage();
            }

            //decode
            if (MSTP.Decode(m_local_buffer, 0, m_local_offset, out frame_type, out destination_address, out source_address, out msg_length) < 0)
            {
                //drop message
                m_local_buffer[0] = 0xFF;
                RemoveGarbage();
                return GetMessageStatus.DecodeError;
            }

            //valid length?
            int full_msg_length = msg_length + MSTP.MSTP_HEADER_LENGTH + (msg_length > 0 ? 2 : 0);
            if (msg_length > MaxBufferLength)
            {
                //drop message
                m_local_buffer[0] = 0xFF;
                RemoveGarbage();
                return GetMessageStatus.DecodeError;
            }

            //fetch data
            if (msg_length > 0)
            {
                timeout = T_FRAME_ABORT;    //set sub timeout
                while (m_local_offset < full_msg_length)
                {
                    //read
                    int rx = m_port.Read(m_local_buffer, m_local_offset, full_msg_length - m_local_offset, timeout);
                    if (rx == -ETIMEDOUT)
                    {
                        //drop message
                        GetMessageStatus status = m_local_offset == 0 ? GetMessageStatus.Timeout : GetMessageStatus.SubTimeout;
                        m_local_buffer[0] = 0xFF;
                        RemoveGarbage();
                        return status;
                    }
                    else if (rx < 0)
                    {
                        //drop message
                        m_local_buffer[0] = 0xFF;
                        RemoveGarbage();
                        return GetMessageStatus.ConnectionError;
                    }
                    else if (rx == 0)
                    {
                        //drop message
                        m_local_buffer[0] = 0xFF;
                        RemoveGarbage();
                        return GetMessageStatus.ConnectionClose;
                    }
                    m_local_offset += rx;
                }

                //verify data crc
                if (MSTP.Decode(m_local_buffer, 0, m_local_offset, out frame_type, out destination_address, out source_address, out msg_length) < 0)
                {
                    //drop message
                    m_local_buffer[0] = 0xFF;
                    RemoveGarbage();
                    return GetMessageStatus.DecodeError;
                }
            }

            //signal frame event
            if (FrameRecieved != null)
            {
                BacnetMstpFrameTypes _frame_type = frame_type;
                byte _destination_address = destination_address;
                byte _source_address = source_address;
                int _msg_length = msg_length;
                System.Threading.ThreadPool.QueueUserWorkItem((o) => { FrameRecieved(this, _frame_type, _destination_address, _source_address, _msg_length); }, null);
            }

            if(StateLogging) Trace.WriteLine("" + frame_type + " " + destination_address.ToString("X2") + " ");

            //done
            return GetMessageStatus.Good;
        }