/// <summary>
 /// Read a single message
 /// </summary>
 protected byte[] ReadMessage(ReplyLength replyLength, int fixedReplyLength)
 {
     if (port == null)
     {
         return(new byte[0]);
     }
     return(ReadMessage(port, replyLength, fixedReplyLength));
 }
        /// <summary>
        /// Read a single message
        /// </summary>
        private static byte[] ReadMessage(SerialPort port, ReplyLength replyLength, int fixedReplyLength)
        {
            // Try to read the message
            switch (replyLength)
            {
            case ReplyLength.Fixed:
            {
                var data = new byte[fixedReplyLength];
                Read(port, data, 0, fixedReplyLength);
                return(data);
            }

            case ReplyLength.Bit7:
            {
                var data   = new byte[1];
                var offset = 0;
                while (true)
                {
                    Read(port, data, offset, 1);
                    if ((data[offset] & 0x80) == 0)
                    {
                        return(data);
                    }
                    var oldData = data;
                    data = new byte[data.Length + 1];
                    Array.Copy(oldData, data, oldData.Length);
                    offset++;
                }
            }

            case ReplyLength.FirstByte:
            {
                var data = new byte[1];
                // Read first byte
                Read(port, data, 0, 1);
                // Read bytes that follow
                data = new byte[data[0]];
                if (data.Length > 0)
                {
                    Read(port, data, 0, data.Length);
                }
                return(data);
            }

            default:
                throw new ArgumentException("unknown ReplyLength");
            }
        }
        protected byte[] Transaction(byte[] msg, ReplyLength replyLength, int fixedReplyLength)
        {
            Idle = false;
            var port = Open();

            try
            {
                flushAvailableData(port);
                Send(port, msg, msg.Length);
                return(ReadMessage(port, replyLength, fixedReplyLength));
            }
            catch
            {
                Close();
                throw;
            }
        }