public static int GetFrameSizeFromDataCount(MuComFrameDesc description, int dataCount) { if (description == MuComFrameDesc.ReadRequest) { return(2); } return((dataCount * 8 + 5) / 7 + 2); }
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); }
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--; } }
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); }
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); }