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