예제 #1
0
 public static int GetFrameSizeFromDataCount(MuComFrameDesc description, int dataCount)
 {
     if (description == MuComFrameDesc.ReadRequest)
     {
         return(2);
     }
     return((dataCount * 8 + 5) / 7 + 2);
 }
예제 #2
0
        public void ConstructorMustDecodeFrameProperly(byte[] inputBuffer, MuComFrameDesc desc, byte ID, byte[] dataBytes)
        {
            //Arrange

            //Act
            var frame = new MuComFrame(inputBuffer);

            //Assert
            frame.ID.Should().Be(ID);
            frame.Description.Should().Be(desc);
            frame.DataBytes.Should().Equal(dataBytes);
        }
예제 #3
0
        public MuComFrame(MuComFrameDesc description, byte ID, int dataCount, byte[] data)
        {
            if ((dataCount == 0) || (dataCount > 8))
            {
                throw new ArgumentException("Invalid dataCount '" + dataCount.ToString() + "'!");
            }

            this.Description = description;
            this.ID          = ID;
            this.DataCount   = dataCount;
            this.RawBuffer   = new byte[MuComFrame.GetFrameSizeFromDataCount(this.Description, this.DataCount)];

            //Create first bytes with header and variable index
            this.RawBuffer[0] = (byte)(0x80 | (int)this.Description | ((this.DataCount - 1) << 2) | (this.ID >> 6));
            this.RawBuffer[1] = (byte)((this.ID << 1) & 0x7F);

            //Handle read request differently
            if (this.Description == MuComFrameDesc.ReadRequest)
            {
                this.DataBytes = new byte[0];
                return;
            }

            //Copy data array
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (data.Length != dataCount)
            {
                throw new ArgumentException("Invalid length of array '" + nameof(data) + "'! " + data.Length.ToString() + " instead of " + dataCount.ToString() + "!");
            }
            this.DataBytes = data;

            //Fill payload with data bytes
            int payload_pos = 1;
            int byte_pos    = 0;

            for (int data_pos = 0; data_pos < dataCount; data_pos++)
            {
                if (byte_pos < 0)
                {
                    byte_pos = 6;
                    payload_pos++;
                    this.RawBuffer[payload_pos] = 0;
                }
                this.RawBuffer[payload_pos] |= (byte)(data[data_pos] >> (7 - byte_pos));
                payload_pos++;
                this.RawBuffer[payload_pos] = (byte)((data[data_pos] << byte_pos) & 0x7F);
                byte_pos--;
            }
        }
예제 #4
0
        public void ConstructorShouldConvertFineInBothDirections(MuComFrameDesc desc, byte ID, int dataCount, byte[] dataBytes)
        {
            //Arrange
            var frameOne = new MuComFrame(desc, ID, dataCount, dataBytes);

            //Act
            var frameTwo = new MuComFrame(frameOne.RawBuffer);

            //Assert
            frameOne.Description.Should().Be(desc);
            frameTwo.Description.Should().Be(desc);
            frameOne.ID.Should().Be(ID);
            frameTwo.ID.Should().Be(ID);
            frameOne.DataCount.Should().Be(dataCount);
            frameTwo.DataCount.Should().Be(dataCount);
            frameOne.DataBytes.Should().Equal(dataBytes);
            frameTwo.DataBytes.Should().Equal(dataBytes);
            frameOne.RawBuffer.Should().Equal(frameTwo.RawBuffer);
        }
예제 #5
0
        public MuComFrame(byte[] inputBuffer)
        {
            if (inputBuffer is null)
            {
                throw new ArgumentNullException(nameof(inputBuffer));
            }
            if (inputBuffer.Length < 2)
            {
                throw new ArgumentException("Input buffer must contain at least two elements");
            }

            //Copy buffer
            this.RawBuffer = new byte[inputBuffer.Length];
            inputBuffer.CopyTo(this.RawBuffer, 0);

            //Decode header
            this.Description = MuComFrame.GetFrameDescriptionFromHeader(this.RawBuffer[0]);
            this.ID          = MuComFrame.GetIdFromFrame(this.RawBuffer);
            this.DataCount   = MuComFrame.GetDataByteCountFromHeader(this.RawBuffer[0]);

            //A read request frame is only two bytes long and does not
            if (this.Description == MuComFrameDesc.ReadRequest)
            {
                this.DataBytes = new byte[0];
                return;
            }

            //Check input frame size
            int expectedLength = MuComFrame.GetFrameSizeFromDataCount(this.Description, this.DataCount);

            if (inputBuffer.Length < expectedLength)
            {
                throw new ArgumentException("Input buffer size too small! " + expectedLength.ToString() + " expected but input buffer contains only " + inputBuffer.Length.ToString() + " bytes.");
            }

            //Create buffer for data bytes and intermediate buffer
            byte[] buffer = new byte[this.DataCount + 1];
            this.DataBytes = new byte[this.DataCount];

            //Reconstruct data from frame
            //Buffer[0..8] = Data bytes (first byte will be index)
            int dataPos = 0;
            int bytePos = 1;

            for (int i = 0; i < (this.DataBytes.Length + 1); i++)
            {
                if (bytePos < 0)
                {
                    bytePos = 6;
                    dataPos++;
                }
                buffer[i] = (byte)(this.RawBuffer[dataPos] << (7 - bytePos));
                dataPos++;
                buffer[i] |= (byte)(this.RawBuffer[dataPos] >> bytePos);
                bytePos--;
            }

            //Copy data
            this.ID = buffer[0];
            Array.Copy(buffer, 1, this.DataBytes, 0, this.DataBytes.Length);
        }