private static ConnectionResponseDataBlock ParseConnectionResponseDataBlock(IEnumerable <byte> bytes)
        {
            if (bytes.Count() == 0)
            {
                return(new ConnectionResponseDataBlock(0x00, 0x01, UnicastAddress.FromString("0.0.0")));
            }

            var enumerable = bytes as byte[] ?? bytes.ToArray();

            return(new ConnectionResponseDataBlock(enumerable.ElementAt(0), enumerable.ElementAt(1),
                                                   UnicastAddress.FromByteArray(enumerable.Skip(2).ToArray())));
        }
Exemplo n.º 2
0
 public void ParseDataCemi()
 {
     Serial     = Raw.Take(6).ToArray();
     NewAddress = UnicastAddress.FromByteArray(Raw.Skip(4).Take(2).ToArray());
 }
        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.º 4
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();
        }