public byte[] Build(byte communicationChannelId, byte sequenceCounter, IKnxAddress receivingAddress, IKnxData data) { var dataBytes = data.GetBytes(); var length = GetLength(dataBytes); const byte headerLength = 0x06; const byte protocolVersion = 0x10; byte[] serviceTypeTunnelingRequest = { 0x04, 0x20 }; var sendingBytes = new List <byte> { headerLength, protocolVersion }; sendingBytes.AddRange(serviceTypeTunnelingRequest); const byte bodyStructureLength = 0x04; sendingBytes.Add(bodyStructureLength); sendingBytes.Add(communicationChannelId); sendingBytes.Add(sequenceCounter); sendingBytes.Add(0x00); sendingBytes.Add(0x11); sendingBytes.Add(0x00); sendingBytes.Add(0xAC); sendingBytes.Add(receivingAddress is MultiCastAddress ? (byte)0xF0 : (byte)0x50); sendingBytes.Add(0x00); sendingBytes.Add(0x00); sendingBytes.AddRange(receivingAddress.GetBytes()); sendingBytes.Add((byte)length); sendingBytes.Add(0x00); sendingBytes.Add(0x80); AddSendingData(sendingBytes, dataBytes); sendingBytes.InsertRange(4, BitConverter.GetBytes((ushort)(sendingBytes.Count + 2)).Reverse()); return(sendingBytes.ToArray()); }
//TODO sequenz obsolet machen!! public void Build(IKnxAddress sourceAddress, IKnxAddress destinationAddress, ApciTypes apciType, int sCounter = 255, byte[] data = null) { bytes.Add(0x11); //Message Code bytes.Add(0x00); //Manufacturer Code bytes.Add(bitToByte(ctrlByte)); // Control Byte drlByte.Set(7, destinationAddress is MulticastAddress); bytes.Add(bitToByte(drlByte)); // DRL Byte bytes.AddRange(new byte[] { 0x00, 0x00 }); // Source Address Unused bytes.AddRange(destinationAddress.GetBytes()); // Destination Address byte lengthData = 0x01; //TODO when apci first 4 bites is lower than 1111 thenlength++ or shift data to left in npdu byte if (data != null) { lengthData = BitConverter.GetBytes((ushort)(data.Count() + 1))[0]; List <ApciTypes> length0Apci = new List <ApciTypes>() { ApciTypes.MemoryRead, ApciTypes.MemoryWrite, ApciTypes.GroupValueWrite, ApciTypes.ADCRead, ApciTypes.Disconnect }; if (apciType == ApciTypes.MemoryRead || apciType == ApciTypes.MemoryWrite || apciType == ApciTypes.GroupValueWrite || apciType == ApciTypes.ADCRead) { lengthData--; } } else { switch (apciType) { case ApciTypes.ADCRead: case ApciTypes.ADCResponse: case ApciTypes.GroupValueResponse: case ApciTypes.GroupValueWrite: case ApciTypes.Ack: case ApciTypes.Connect: case ApciTypes.Disconnect: lengthData = 0x0; break; } } bytes.Add(lengthData); List <ApciTypes> datatypes = new List <ApciTypes>() { ApciTypes.Restart, ApciTypes.IndividualAddressRead, ApciTypes.DeviceDescriptorRead, ApciTypes.GroupValueRead, ApciTypes.GroupValueResponse, ApciTypes.GroupValueWrite, ApciTypes.ADCRead, ApciTypes.ADCResponse, ApciTypes.MemoryRead, ApciTypes.MemoryResponse, ApciTypes.MemoryWrite }; int _apci = (int)apciType; if (apciType == ApciTypes.Ack) { _apci--; } _apci = _apci | ((sCounter == 255 ? 0 : sCounter) << 10); _apci = _apci | ((sCounter == 255 ? 0 : 1) << 14); _apci = _apci | (((data == null && !datatypes.Contains(apciType)) ? 1 : 0) << 15); switch (apciType) { case ApciTypes.MemoryWrite: case ApciTypes.MemoryRead: int number = BitConverter.ToInt16(new byte[] { data[0], 0, 0, 0 }, 0); if (number > 63) { number = 63; } _apci = _apci | number; byte[] data_temp = new byte[data.Length - 1]; for (int i = 1; i < data.Length; i++) { data_temp[i - 1] = data[i]; } data = data_temp; break; } byte[] _apci2 = BitConverter.GetBytes(Convert.ToUInt16(_apci)); switch (apciType) { case ApciTypes.GroupValueResponse: case ApciTypes.GroupValueWrite: case ApciTypes.ADCRead: case ApciTypes.ADCResponse: case ApciTypes.Ack: case ApciTypes.Connect: case ApciTypes.Disconnect: bytes.Add(_apci2[1]); break; default: bytes.Add(_apci2[1]); bytes.Add(_apci2[0]); break; } if (data != null) { bytes.AddRange(data); } }
//TODO sequenz obsolet machen!! public void Build(IKnxAddress sourceAddress, IKnxAddress destinationAddress, ApciTypes apciType, int sCounter = 255, byte[] data = null) { bytes.Add(0x11); //Message Code bytes.Add(0x00); //Manufacturer Code bytes.Add(bitToByte(ctrlByte)); // Control Byte drlByte.Set(7, destinationAddress is MulticastAddress); bytes.Add(bitToByte(drlByte)); // DRL Byte bytes.AddRange(sourceAddress.GetBytes()); // Source Address bytes.AddRange(destinationAddress.GetBytes()); // Destination Address byte lengthData = Convert.ToByte(data?.Length ?? 0); List <ApciTypes> datatypes = new List <ApciTypes>() { ApciTypes.Restart, ApciTypes.IndividualAddressRead, ApciTypes.DeviceDescriptorRead, ApciTypes.GroupValueRead, ApciTypes.GroupValueResponse, ApciTypes.GroupValueWrite, ApciTypes.ADCRead, ApciTypes.ADCResponse, ApciTypes.MemoryRead, ApciTypes.MemoryResponse, ApciTypes.MemoryWrite }; int _apci = (int)apciType; if (apciType == ApciTypes.Ack) { _apci--; } _apci = _apci | ((sCounter == 255 ? 0 : sCounter) << 10); _apci = _apci | ((sCounter == 255 ? 0 : 1) << 14); _apci = _apci | (((data == null && !datatypes.Contains(apciType)) ? 1 : 0) << 15); List <ApciTypes> withData = new List <ApciTypes>() { ApciTypes.GroupValueRead, ApciTypes.GroupValueResponse, ApciTypes.GroupValueWrite, ApciTypes.ADCRead, ApciTypes.ADCResponse, ApciTypes.MemoryRead, ApciTypes.MemoryResponse, ApciTypes.MemoryWrite, ApciTypes.DeviceDescriptorRead, ApciTypes.DeviceDescriptorResponse, ApciTypes.Restart }; if (withData.Contains(apciType) && data != null) { byte first = data[0]; if (first < 64) { first &= 0b00111111; _apci |= first; data = data.Skip(1).ToArray(); lengthData--; } } byte[] _apci2 = BitConverter.GetBytes(Convert.ToUInt16(_apci)); switch (apciType) { case ApciTypes.ADCRead: case ApciTypes.ADCResponse: case ApciTypes.Ack: case ApciTypes.Connect: case ApciTypes.Disconnect: bytes.Add(lengthData); bytes.Add(_apci2[1]); break; default: bytes.Add(++lengthData); bytes.Add(_apci2[1]); bytes.Add(_apci2[0]); break; } if (data != null) { bytes.AddRange(data); } }