Exemplo n.º 1
0
        public byte[] GetBytesCemi()
        {
            byte[] send_data = new byte[Data.Length + 4];

            send_data[0] = ObjectIndex;
            send_data[1] = PropertyId;
            send_data[2] = 0x10;
            send_data[3] = 0x01;

            for (int i = 0; i < Data.Length; i++)
            {
                send_data[i + 4] = Data[i];
            }

            TunnelCemiRequest builder = new TunnelCemiRequest();

            builder.Build(UnicastAddress.FromString("0.0.0"), DestinationAddress, ApciTypes.PropertyValueWrite, SequenceNumber, send_data);
            return(builder.GetBytes());
        }
Exemplo n.º 2
0
        public byte[] GetBytesCemi()
        {
            TunnelRequest builder = new TunnelRequest();

            List <byte> data = new List <byte>();

            data.AddRange(Serial);

            data.AddRange(NewAddress.GetBytes());
            data.AddRange(new byte[] { 0, 0, 0, 0 });

            builder.Build(UnicastAddress.FromString("0.0.0"), MulticastAddress.FromString("0/0/0"), ApciTypes.IndividualAddressSerialNumberWrite, 255, data.ToArray());
            builder.SetPriority(Prios.System);

            data = new List <byte>()
            {
                0x11, 0x00
            };
            data.AddRange(builder.GetBytes());
            return(data.ToArray());
        }
Exemplo n.º 3
0
        public byte[] GetBytesCemi()
        {
            if (Length > 256)
            {
                throw new Exception("Bei cEmi kann maximal 256 Bytes ausgelesen werden. (Angefordert waren " + Length + " bytes)");
            }


            List <byte> data = new List <byte> {
                BitConverter.GetBytes(Length)[0]
            };

            byte[] addr = BitConverter.GetBytes(Address);
            data.Add(addr[1]);
            data.Add(addr[0]);

            Builders.TunnelCemiRequest builder = new TunnelCemiRequest();
            builder.Build(UnicastAddress.FromString("0.0.0"), DestinationAddress, ApciTypes.MemoryRead, SequenceNumber, data.ToArray());

            return(builder.GetBytes());
        }
Exemplo n.º 4
0
 public TunnelResponse(byte headerLength, byte protocolVersion, ushort totalLength, byte structureLength,
                       byte communicationChannel, byte sequenceCounter, byte messageCode, byte addInformationLength, bool isRequest, bool ackWanted, byte controlField,
                       byte controlField2, UnicastAddress sourceAddress, IKnxAddress destinationAddress, ApciTypes apci, int seqNumb,
                       byte[] data)
 {
     HeaderLength         = headerLength;
     ProtocolVersion      = protocolVersion;
     TotalLength          = totalLength;
     StructureLength      = structureLength;
     CommunicationChannel = communicationChannel;
     SequenceCounter      = sequenceCounter;
     MessageCode          = messageCode;
     AddInformationLength = addInformationLength;
     AckWanted            = ackWanted;
     ControlField         = controlField;
     ControlField2        = controlField2;
     SourceAddress        = sourceAddress;
     DestinationAddress   = destinationAddress;
     APCI           = apci;
     SequenceNumber = seqNumb;
     Data           = data;
     IsRequest      = IsRequest;
 }
Exemplo n.º 5
0
        public byte[] GetBytesCemi()
        {
            TunnelRequest builder = new TunnelRequest();
            List <byte>   data    = new List <byte> {
                Convert.ToByte(Data.Length)
            };

            byte[] addr = BitConverter.GetBytes(Convert.ToInt16(Address));
            Array.Reverse(addr);
            data.AddRange(addr);
            data.AddRange(Data);

            if (IsExtended)
            {
                builder.SetIsExtended();
            }
            builder.Build(UnicastAddress.FromString("0.0.0"), DestinationAddress, ApciTypes.MemoryWrite, SequenceNumber, data.ToArray());
            data = new List <byte>()
            {
                0x11, 0x00
            };
            data.AddRange(builder.GetBytes());
            return(data.ToArray());
        }
Exemplo n.º 6
0
        public byte[] GetBytesCemi()
        {
            TunnelRequest builder = new TunnelRequest();


            List <byte> data = new List <byte>()
            {
            };

            data.Add(0x00);
            data.Add((byte)(Key >> 24));
            data.Add((byte)(Key >> 16));
            data.Add((byte)(Key >> 8));
            data.Add((byte)Key);

            builder.Build(UnicastAddress.FromString("0.0.0"), DestinationAddress, ApciType, SequenceNumber, data.ToArray());

            data = new List <byte>()
            {
                0x11, 0x00
            };
            data.AddRange(builder.GetBytes());
            return(data.ToArray());
        }
Exemplo n.º 7
0
        public byte[] GetBytesCemi()
        {
            byte[] send_data = new byte[Data.Length + 4];

            send_data[0] = ObjectIndex;
            send_data[1] = PropertyId;
            send_data[2] = 0x10; //TODO check if it must be set to data.length
            send_data[3] = 0x01;

            for (int i = 0; i < Data.Length; i++)
            {
                send_data[i + 4] = Data[i];
            }

            List <byte> data = new List <byte>()
            {
                0x11, 0x00
            };
            TunnelRequest builder = new TunnelRequest();

            builder.Build(UnicastAddress.FromString("0.0.0"), DestinationAddress, ApciTypes.PropertyValueWrite, SequenceNumber, send_data);
            data.AddRange(builder.GetBytes());
            return(data.ToArray());
        }
Exemplo n.º 8
0
 /// <summary>
 /// Creates a telegram to write a group value
 /// </summary>
 /// <param name="from">Unicast Address from sender</param>
 /// <param name="to">Mulicast Address (GroupAddress)</param>
 /// <param name="data">Data to write</param>
 public MsgGroupWriteReq(UnicastAddress from, MulticastAddress to, byte[] data)
 {
     SourceAddress      = from;
     DestinationAddress = to;
     _data = data;
 }
        public Builders.TunnelResponse Build(byte headerLength, byte protocolVersion, ushort totalLength, byte[] responseBytes)
        {
            var structureLength      = responseBytes[0];
            var communicationChannel = responseBytes[1];
            var sequenceCounter      = responseBytes[2];
            var messageCode          = responseBytes[4];
            var addInformationLength = responseBytes[5];
            var controlField         = responseBytes[6];
            var controlField2        = responseBytes[7];
            var npduLength           = responseBytes[12];

            byte[] npdu;

            if (npduLength != 0)
            {
                npdu = new byte[] { responseBytes[13], responseBytes[14] };
            }
            else
            {
                npdu = new byte[] { responseBytes[13] };
            }


            byte[]    data    = null;
            int       seqNumb = 0x0;
            ApciTypes type    = ApciTypes.Undefined;

            if (npduLength != 0)
            {
                BitArray bitsNpdu = new BitArray(npdu);
                if (bitsNpdu.Get(6))
                {
                    seqNumb = npdu[0] >> 2;
                    seqNumb = seqNumb & 0xF;
                }

                int apci1 = ((npdu[0] & 3) << 2) | (npdu[1] >> 6);

                switch (apci1)
                {
                case 0:
                    type = ApciTypes.GroupValueRead;
                    break;

                case 1:
                    type = ApciTypes.GroupValueResponse;
                    int datai2 = npdu[1] & 63;
                    data    = new byte[responseBytes.Length - 15 + 1];
                    data[0] = Convert.ToByte(datai2);
                    for (int i = 1; i < responseBytes.Length - 15 + 1; i++)
                    {
                        data[i] = responseBytes[i];
                    }
                    break;

                case 2:
                    type = ApciTypes.GroupValueWrite;
                    int datai = npdu[1] & 63;
                    data    = new byte[responseBytes.Length - 15 + 1];
                    data[0] = Convert.ToByte(datai);
                    for (int i = 1; i < responseBytes.Length - 15 + 1; i++)
                    {
                        data[i] = responseBytes[i];
                    }
                    break;

                case 3:
                    type = ApciTypes.IndividualAddressWrite;
                    break;

                case 4:
                    type = ApciTypes.IndividualAddressRead;
                    break;

                case 5:
                    type = ApciTypes.IndividualAddressResponse;
                    break;

                case 6:
                    type = ApciTypes.ADCRead;
                    break;

                case 7:
                    if (npdu[1] == 0)
                    {
                        type = ApciTypes.ADCResponse;
                    }
                    break;

                case 8:
                    type = ApciTypes.MemoryRead;
                    break;

                case 9:
                    type = ApciTypes.MemoryResponse;
                    break;

                case 10:
                    type = ApciTypes.MemoryWrite;
                    break;


                default:
                    apci1 = ((npdu[0] & 3) << 8) | npdu[1];
                    type  = (ApciTypes)apci1;
                    break;
                }

                if (data == null)
                {
                    data = new byte[responseBytes.Length - 15];

                    int c = 0;
                    for (int i = 15; i < responseBytes.Length; i++)
                    {
                        data[c] = responseBytes[i];
                        c++;
                    }
                }
            }
            else
            {
                data = new byte[0];
                int apci3 = npdu[0] & 3;

                BitArray bitsNpdu = new BitArray(npdu);
                if (bitsNpdu.Get(6))
                {
                    seqNumb = npdu[0] >> 2;
                    seqNumb = seqNumb & 0xF;
                }

                switch (apci3)
                {
                case 0:
                    type = ApciTypes.Connect;
                    break;

                case 1:
                    type = ApciTypes.Disconnect;
                    break;

                case 2:
                    type = ApciTypes.Ack;
                    break;

                case 3:
                    type = ApciTypes.NAK;
                    break;

                default:
                    Debug.WriteLine("Unbekantes NPDU: " + apci3);
                    break;
                }
            }

            BitArray bitsCtrl1 = new BitArray(new[] { responseBytes[6] });
            BitArray bitsCtrl2 = new BitArray(new[] { responseBytes[7] });

            IKnxAddress destAddr = null;

            if (bitsCtrl2.Get(7))
            {
                destAddr = MulticastAddress.FromByteArray(new[] { responseBytes[10], responseBytes[11] });
            }
            else
            {
                destAddr = UnicastAddress.FromByteArray(new[] { responseBytes[10], responseBytes[11] });
            }

            bool ackWanted = bitsCtrl1.Get(2);
            bool isRequest = ReqMC.Contains(responseBytes[4]);


            switch (type)
            {
            case ApciTypes.MemoryWrite:
            case ApciTypes.MemoryRead:
                byte[] data_temp = new byte[data.Length + 1];

                int restData = npdu[1] & 127;

                data_temp[0] = BitConverter.GetBytes(restData)[0];

                for (int i = 0; i < data.Length; i++)
                {
                    data_temp[i + 1] = data[i];
                }
                data = data_temp;
                break;
            }



            return(new Builders.TunnelResponse(headerLength, protocolVersion, totalLength, structureLength, communicationChannel,
                                               sequenceCounter, messageCode, addInformationLength, isRequest, ackWanted, controlField, controlField2,
                                               UnicastAddress.FromByteArray(new[] { responseBytes[8], responseBytes[9] }),
                                               destAddr, type, seqNumb,
                                               data));
        }
Exemplo n.º 10
0
 public MsgAuthorizeReq(uint key, UnicastAddress address)
 {
     Key = key;
     DestinationAddress = address;
 }
Exemplo n.º 11
0
 public void ParseDataCemi()
 {
     Serial     = Raw.Take(6).ToArray();
     NewAddress = UnicastAddress.FromByteArray(Raw.Skip(4).Take(2).ToArray());
 }
Exemplo n.º 12
0
 /// <summary>
 /// Creates a telegram to connect to a device
 /// </summary>
 /// <param name="address">Unicast Address from device</param>
 public MsgConnectReq(UnicastAddress address)
 {
     DestinationAddress = address;
 }
Exemplo n.º 13
0
 /// <summary>
 /// Creates a telegram to write an individual address via serialnumber
 /// </summary>
 /// <param name="address">New Unicast Address</param>
 /// <param name="serial">Serialnumber</param>
 public MsgIndividualAddressSerialWriteReq(UnicastAddress newAddr, byte[] serial)
 {
     NewAddress = newAddr;
     Serial     = serial;
 }
Exemplo n.º 14
0
 /// <summary>
 /// Creates a telegram to read the device descriptor
 /// </summary>
 /// <param name="address">Unicast Address from device</param>
 public MsgDescriptorReadReq(UnicastAddress address)
 {
     DestinationAddress = address;
 }
Exemplo n.º 15
0
 public async void IndividualAddressWrite(UnicastAddress newAddr)
 {
     MsgIndividualAddressWriteReq message = new MsgIndividualAddressWriteReq(newAddr);
     await _conn.Send(message);
 }
Exemplo n.º 16
0
 public async void IndividualAddressWrite(UnicastAddress newAddr, byte[] serialNumber)
 {
     MsgIndividualAddressSerialWriteReq message = new MsgIndividualAddressSerialWriteReq(newAddr, serialNumber);
     await _conn.Send(message);
 }
Exemplo n.º 17
0
 public MsgRestartReq(UnicastAddress address)
 {
     DestinationAddress = address;
 }
Exemplo n.º 18
0
 /// <summary>
 /// Creates a telegram to read a property
 /// </summary>
 /// <param name="objIndex">Object Index</param>
 /// <param name="propId">Property Id</param>
 /// <param name="address">Unicast Address from device</param>
 public MsgPropertyReadReq(byte objIndex, byte propId, UnicastAddress address)
 {
     ObjectIndex        = objIndex;
     PropertyId         = propId;
     DestinationAddress = address;
 }
Exemplo n.º 19
0
        //TODO Adresse der Schnitstelle schreibt man im Speicher an Adresse 279

        public async Task Connect()
        {
            byte[] packet = new byte[64]; //Create packet which will be fixed 64 bytes long

            //Report Header
            packet[0] = 1;    //Report Id (fixed)
            packet[1] = 0x13; // First Packet with start and end
            packet[2] = 9;    // Data length

            //Transfer Header
            packet[3]  = 0;    // Version fixed 0
            packet[4]  = 8;    // Header length
            packet[5]  = 0;    // Body length
            packet[6]  = 1;    // Body length
            packet[7]  = 0x0F; // Protocol ID
            packet[8]  = 0x01; // Service Identifier
            packet[9]  = 0;    // Manufacturer Code
            packet[10] = 0;    // Manufacturer Code

            // Body
            packet[11] = 1; // Supported Emis

            bool isInited = DeviceKnx.IsInitialized;

            await DeviceKnx.InitializeAsync();

            CancellationTokenSource source = new CancellationTokenSource(1000);

            TransferResult read = await DeviceKnx.WriteAndReadAsync(packet, source.Token);

            BitArray emis = new BitArray(new byte[] { read.Data[13] });

            byte setEmi = 0;

            if (emis.Get(2))
            {
                Debug.WriteLine("USB: Verwende cEmi");
                CurrentType = ProtocolTypes.cEmi;
            }
            else if (emis.Get(1))
            {
                Debug.WriteLine("USB: Verwende Emi2");
                CurrentType = ProtocolTypes.Emi2;
            }
            else if (emis.Get(0))
            {
                CurrentType = ProtocolTypes.Emi1;
                Debug.WriteLine("USB: Verwende Emi1");
            }
            else
            {
                Debug.WriteLine("USB: unterstützt kein Emi1/Emi2/cEmi");
            }


            packet[6]  = 0x02;
            packet[8]  = 0x03;                        //Device Feature Set
            packet[11] = 0x05;                        //Set Emi Type
            packet[12] = Convert.ToByte(CurrentType); //Selected Emi type

            source = new CancellationTokenSource(1000);
            await DeviceKnx.WriteAsync(packet, source.Token);

            packet[6]  = 0x01;
            packet[8]  = 0x01; //Device Feature Get
            packet[11] = 0x03; //Bus Status
            packet[12] = 0x00;

            source = new CancellationTokenSource(1000);
            read   = await DeviceKnx.WriteAndReadAsync(packet, source.Token);

            int status = read.Data[12];

            if (status == 0)
            {
                throw new Exception("Schnittstelle hat keine Verbindung zum Bus.");
            }


            packet[2]  = 0x0c;
            packet[6]  = 0x04;                        //Body length
            packet[7]  = 0x01;                        //Tunnel
            packet[8]  = Convert.ToByte(CurrentType); //Selected Emi
            packet[11] = 0x4c;                        //Memory Read
            packet[12] = 0x02;                        //Length
            packet[13] = 0x01;                        //Address High
            packet[14] = 0x17;                        //Address Low

            source = new CancellationTokenSource(1000);
            read   = await DeviceKnx.WriteAndReadAsync(packet, source.Token);

            PhysicalAddress = UnicastAddress.FromByteArray(new byte[] { read.Data[15], read.Data[16] });

            if (source.IsCancellationRequested)
            {
                DeviceKnx.Close();
                throw new Exception("Schnittstelle antwortet nicht.");
            }

            IsConnected = true;
            ConnectionChanged?.Invoke(true);

            ProcessSendMessages();
        }
Exemplo n.º 20
0
 /// <summary>
 /// Creates a telegram to read from memory
 /// </summary>
 /// <param name="address">Memory Address</param>
 /// <param name="length">Length of data to read</param>
 /// <param name="addr">Unicast Address from device</param>
 public MsgMemoryReadReq(int address, int length, UnicastAddress addr)
 {
     Address            = address;
     Length             = length;
     DestinationAddress = addr;
 }
Exemplo n.º 21
0
        private void ProcessReceivingMessages(UdpClient _udpClient)
        {
            Debug.WriteLine("Höre jetzt auf: " + (_udpClient.Client.LocalEndPoint as IPEndPoint).Port);
            Task.Run(async() =>
            {
                int rofl = 0;
                try
                {
                    while (!StopProcessing)
                    {
                        rofl++;
                        var result      = await _udpClient.ReceiveAsync();
                        var knxResponse = _receiveParserDispatcher.Build(result.Buffer);

                        //if(!(knxResponse is SearchResponse))
                        //    Debug.WriteLine("Telegram angekommen: " + knxResponse?.ToString());


                        switch (knxResponse)
                        {
                        case ConnectStateResponse connectStateResponse:
                            Debug.WriteLine("Connection State Response: " + connectStateResponse.Status.ToString());
                            switch (connectStateResponse.Status)
                            {
                            case 0x00:
                                IsConnected = true;
                                ConnectionChanged?.Invoke(IsConnected);
                                break;

                            default:
                                Debug.WriteLine("Connection State: Fehler: " + connectStateResponse.Status.ToString());
                                LastError   = ConnectionErrors.NotConnectedToBus;
                                IsConnected = false;
                                ConnectionChanged?.Invoke(IsConnected);
                                break;
                            }
                            break;

                        case ConnectResponse connectResponse:
                            _flagCRRecieved = true;
                            switch (connectResponse.Status)
                            {
                            case 0x00:
                                _sequenceCounter      = 0;
                                _communicationChannel = connectResponse.CommunicationChannel;
                                IsConnected           = true;
                                ConnectionChanged?.Invoke(IsConnected);
                                PhysicalAddress = connectResponse.ConnectionResponseDataBlock.KnxAddress;
                                Debug.WriteLine("Connected: Eigene Adresse: " + PhysicalAddress.ToString());
                                break;

                            default:
                                Debug.WriteLine("Connected: Fehler: " + connectResponse.Status.ToString());
                                LastError   = ConnectionErrors.Undefined;
                                IsConnected = false;
                                ConnectionChanged?.Invoke(IsConnected);
                                break;
                            }
                            break;

                        case Builders.TunnelResponse tunnelResponse:
                            if (tunnelResponse.IsRequest && tunnelResponse.DestinationAddress != PhysicalAddress)
                            {
                                Debug.WriteLine("Telegram erhalten das nicht mit der Adresse selbst zu tun hat!");
                                Debug.WriteLine("Typ: " + tunnelResponse.APCI);
                                Debug.WriteLine("Eigene Adresse: " + PhysicalAddress.ToString());
                                break;
                            }

                            _sendMessages.Add(new Responses.TunnelResponse(0x06, 0x10, 0x0A, 0x04, _communicationChannel, tunnelResponse.SequenceCounter, 0x00).GetBytes());

                            //Debug.WriteLine("Telegram APCI: " + tunnelResponse.APCI.ToString());

                            if (tunnelResponse.APCI.ToString().EndsWith("Response"))
                            {
                                List <byte> data = new List <byte>()
                                {
                                    0x11, 0x00
                                };
                                TunnelRequest builder = new TunnelRequest();
                                builder.Build(UnicastAddress.FromString("0.0.0"), tunnelResponse.SourceAddress, ApciTypes.Ack, tunnelResponse.SequenceNumber);
                                data.AddRange(builder.GetBytes());
                                _ = Send(data.ToArray(), _sequenceCounter);
                                _sequenceCounter++;
                                //Debug.WriteLine("Got Response " + tunnelResponse.SequenceCounter + " . " + tunnelResponse.SequenceNumber);
                            }
                            else if (tunnelResponse.APCI == ApciTypes.Ack)
                            {
                                OnTunnelAck?.Invoke(new MsgAckRes()
                                {
                                    ChannelId          = tunnelResponse.CommunicationChannel,
                                    SequenceCounter    = tunnelResponse.SequenceCounter,
                                    SequenceNumber     = tunnelResponse.SequenceNumber,
                                    SourceAddress      = tunnelResponse.SourceAddress,
                                    DestinationAddress = tunnelResponse.DestinationAddress
                                });
                                break;
                            }


                            List <string> temp = new List <string>();
                            var q = from t in Assembly.GetExecutingAssembly().GetTypes()
                                    where t.IsClass && t.IsNested == false && (t.Namespace == "Kaenx.Konnect.Messages.Response" || t.Namespace == "Kaenx.Konnect.Messages.Request")
                                    select t;

                            IMessage message = null;

                            foreach (Type t in q.ToList())
                            {
                                IMessage resp = (IMessage)Activator.CreateInstance(t);

                                if (resp.ApciType == tunnelResponse.APCI)
                                {
                                    message = resp;
                                    break;
                                }
                            }


                            if (message == null)
                            {
                                //throw new Exception("Kein MessageParser für den APCI " + tunnelResponse.APCI);
                                message = new MsgDefaultRes()
                                {
                                    ApciType = tunnelResponse.APCI
                                };
                                Debug.WriteLine("Kein MessageParser für den APCI " + tunnelResponse.APCI);
                            }

                            message.Raw                = tunnelResponse.Data;
                            message.ChannelId          = tunnelResponse.CommunicationChannel;
                            message.SequenceCounter    = tunnelResponse.SequenceCounter;
                            message.SequenceNumber     = tunnelResponse.SequenceNumber;
                            message.SourceAddress      = tunnelResponse.SourceAddress;
                            message.DestinationAddress = tunnelResponse.DestinationAddress;

                            switch (CurrentType)
                            {
                            case ProtocolTypes.cEmi:
                                message.ParseDataCemi();
                                break;

                            case ProtocolTypes.Emi1:
                                message.ParseDataEmi1();
                                break;

                            case ProtocolTypes.Emi2:
                                message.ParseDataEmi2();
                                break;

                            default:
                                throw new NotImplementedException("Unbekanntes Protokoll - TunnelResponse KnxIpTunneling");
                            }


                            if (tunnelResponse.APCI.ToString().EndsWith("Response"))
                            {
                                OnTunnelResponse?.Invoke(message as IMessageResponse);
                            }
                            else
                            {
                                OnTunnelRequest?.Invoke(message as IMessageRequest);
                            }

                            break;

                        case SearchResponse searchResponse:
                            MsgSearchRes msg = new MsgSearchRes(searchResponse.responseBytes);
                            switch (CurrentType)
                            {
                            case ProtocolTypes.cEmi:
                                msg.ParseDataCemi();
                                break;

                            case ProtocolTypes.Emi1:
                                msg.ParseDataEmi1();
                                break;

                            case ProtocolTypes.Emi2:
                                msg.ParseDataEmi2();
                                break;

                            default:
                                throw new NotImplementedException("Unbekanntes Protokoll - SearchResponse KnxIpTunneling");
                            }
                            OnSearchResponse?.Invoke(msg);
                            break;

                        case TunnelAckResponse tunnelAck:
                            //Do nothing
                            break;

                        case DisconnectResponse disconnectResponse:
                            IsConnected           = false;
                            _communicationChannel = 0;
                            ConnectionChanged?.Invoke(IsConnected);
                            break;
                        }
                    }

                    Debug.WriteLine("Stopped Processing Messages " + _udpClient.Client.LocalEndPoint.ToString());
                    _udpClient.Close();
                    _udpClient.Dispose();
                }
                catch
                {
                }
            });
        }
 /// <summary>
 /// Creates a telegram to write an individual addres via programm button
 /// </summary>
 /// <param name="newAddress">New Unicast Address</param>
 public MsgIndividualAddressWriteReq(UnicastAddress newAddress)
 {
     _address = newAddress;
 }
 public ConnectionResponseDataBlock(byte structureLength, byte connectionType, UnicastAddress knxAddress)
 {
     StructureLength = structureLength;
     ConnectionType  = connectionType;
     KnxAddress      = knxAddress;
 }