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

GetNextMessage() private method

private GetNextMessage ( byte buffer, int &offset, int timeout_ms, BacnetPtpFrameTypes &frame_type, int &msg_length ) : BacnetMstpProtocolTransport.GetMessageStatus
buffer byte
offset int
timeout_ms int
frame_type BacnetPtpFrameTypes
msg_length int
return BacnetMstpProtocolTransport.GetMessageStatus
        private BacnetMstpProtocolTransport.GetMessageStatus GetNextMessage(byte[]buffer, ref int offset, int timeout_ms, out BacnetPtpFrameTypes frame_type, out int msg_length)
        {
            BacnetMstpProtocolTransport.GetMessageStatus status;
            int timeout = timeout_ms;

            frame_type = BacnetPtpFrameTypes.FRAME_TYPE_HEARTBEAT_XOFF;
            msg_length = 0;
            bool compliment_next = false;

            //fetch header
            while (offset < PTP.PTP_HEADER_LENGTH)
            {
                if (m_port == null) return BacnetMstpProtocolTransport.GetMessageStatus.ConnectionClose;

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

                //read
                int rx = m_port.Read(buffer, offset, PTP.PTP_HEADER_LENGTH - offset, timeout);
                status = ProcessRxStatus(buffer, ref offset, rx);
                if (status != BacnetMstpProtocolTransport.GetMessageStatus.Good) return status;

                //remove XON/XOFF
                int new_offset = offset + rx;
                RemoveXonOff(buffer, offset, ref new_offset, ref compliment_next);
                offset = new_offset;

                //remove garbage
                RemoveGarbage(buffer, ref offset);
            }

            //greeting
            if (IsGreeting(buffer, 0, offset))
            {
                //get last byte
                int rx = m_port.Read(buffer, offset, 1, timeout);
                status = ProcessRxStatus(buffer, ref offset, rx);
                if (status != BacnetMstpProtocolTransport.GetMessageStatus.Good) return status;
                offset += 1;
                if (IsGreeting(buffer, 0, offset))
                {
                    frame_type = BacnetPtpFrameTypes.FRAME_TYPE_GREETING;
                    if (StateLogging) Trace.WriteLine(frame_type, null);
                    return BacnetMstpProtocolTransport.GetMessageStatus.Good;
                }
                else
                {
                    //drop message
                    buffer[0] = 0xFF;
                    RemoveGarbage(buffer, ref offset);
                    return BacnetMstpProtocolTransport.GetMessageStatus.DecodeError;
                }
            }

            //decode
            if (PTP.Decode(buffer, 0, offset, out frame_type, out msg_length) < 0)
            {
                //drop message
                buffer[0] = 0xFF;
                RemoveGarbage(buffer, ref offset);
                return BacnetMstpProtocolTransport.GetMessageStatus.DecodeError;
            }

            //valid length?
            int full_msg_length = msg_length + PTP.PTP_HEADER_LENGTH + (msg_length > 0 ? 2 : 0);
            if (msg_length > MaxBufferLength)
            {
                //drop message
                buffer[0] = 0xFF;
                RemoveGarbage(buffer, ref offset);
                return BacnetMstpProtocolTransport.GetMessageStatus.DecodeError;
            }

            //fetch data
            if (msg_length > 0)
            {
                timeout = T_FRAME_ABORT;    //set sub timeout
                while (offset < full_msg_length)
                {
                    //read
                    int rx = m_port.Read(buffer, offset, full_msg_length - offset, timeout);
                    status = ProcessRxStatus(buffer, ref offset, rx);
                    if (status != BacnetMstpProtocolTransport.GetMessageStatus.Good) return status;

                    //remove XON/XOFF
                    int new_offset = offset + rx;
                    RemoveXonOff(buffer, offset, ref new_offset, ref compliment_next);
                    offset = new_offset;
                }

                //verify data crc
                if (PTP.Decode(buffer, 0, offset, out frame_type, out msg_length) < 0)
                {
                    //drop message
                    buffer[0] = 0xFF;
                    RemoveGarbage(buffer, ref offset);
                    return BacnetMstpProtocolTransport.GetMessageStatus.DecodeError;
                }
            }

            //debug
            if (StateLogging)
                Trace.WriteLine(frame_type, null);

            //done
            return BacnetMstpProtocolTransport.GetMessageStatus.Good;
        }