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 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); }