internal static ConnectResponseFrame CreateFrame(byte[] datagram, KnxConnection knx) { ConnectResponseFrame frame = new ConnectResponseFrame(knx); var knxDatagram = new KnxDatagram(datagram) { HeaderLength = datagram[0], ProtocolVersion = datagram[1], ServiceType = new[] { datagram[2], datagram[3] }, TotalLength = datagram[4] + datagram[5], ChannelId = datagram[6], Status = datagram[7] }; if (knxDatagram.ChannelId == 0x00 && knxDatagram.Status == 0x24) { frame.ErrorCode = "E_NO_MORE_CONNECTIONS"; return(frame); } else if (knxDatagram.Status == 0x2B || knxDatagram.Status == 0x2A) { /*if (knx is KnxConnectionTunnelingSecure knxIpSec) * { * knxIpSec.IpSecureErrorOccured?.Invoke(knx, new IpSecureEventArgs("E_NO_TUNNELLING_ADDRESS", KnxError.IpSecInvalidIndividualAddress)); * knx.Disconnect(); * }*/ } else if (knxDatagram.Status == 0x26) { frame.ErrorCode = "E_DATA_CONNECTION"; return(frame); } else if (knxDatagram.Status == 0x27) { frame.ErrorCode = "E_KNX_CONNECTION"; return(frame); } else { byte[] iab = new byte[2]; Array.Copy(datagram, 18, iab, 0, 2); string ia = KnxHelper.GetIndividualAddress(iab); if (!String.IsNullOrEmpty(knx.IndividualAddress) && ia != knx.IndividualAddress) { // ((KnxConnectionTunnelingSecure) knx).IpSecureErrorOccured.Invoke(knx, // new IpSecureEventArgs("E_DATA_CONNECTION", // KnxError.IpSecRespondedIndividualAddressDiffersToGiven)); // knx.Disconnect(); return(frame); } frame.IndividualAddress = ia; frame.ChannelId = knxDatagram.ChannelId; frame.IsValid = true; } return(frame); }
protected virtual void ConvertFromBus(KnxDatagram datagram) { var value = DptTranslator.Instance.FromDataPoint(DptTypeString, datagram.Data); if (ValueRead(value)) { DispatchValue(value); } }
internal KnxEventArgs(KnxDatagram datagram) : this( datagram.source_address, datagram.destination_address, datagram.control_field_1, datagram.control_field_2, datagram.data) { }
public static ResponseType ProcessDatagram(byte[] datagram, bool threeLevelGroupAddressing, bool isDebug, out KnxDatagram knxDatagram) { knxDatagram = new KnxDatagram { HeaderLength = datagram[0], ProtocolVersion = datagram[1], ServiceType = new[] { datagram[2], datagram[3] }, TotalLength = datagram[4] + datagram[5] }; var cemi = new byte[datagram.Length - 6]; Array.Copy(datagram, 6, cemi, 0, datagram.Length - 6); return(ProcessCEMI(ref knxDatagram, cemi, threeLevelGroupAddressing, isDebug)); }
protected override void ConvertFromBus(KnxDatagram datagram) { var value = DptTranslator.Instance.FromDataPoint(DptTypeString, datagram.Data); if (value is Dpt2Value dpt2Value) { foreach (var child in _children) { child.DispatchDpt2Value(dpt2Value); } } else { KnxHelper.Logger.LogError("Received value has invalud type"); } DispatchValue(value); }
internal static TunnelingRequestFrame CreateFrame(byte[] datagram, KnxConnection knx, int rxSequenceNumber, bool isFirstRequest) { TunnelingRequestFrame frame = new TunnelingRequestFrame(knx); var knxDatagram = new KnxDatagram(datagram) { HeaderLength = datagram[0], ProtocolVersion = datagram[1], ServiceType = new[] { datagram[2], datagram[3] }, TotalLength = datagram[4] + datagram[5] }; var channelId = datagram[7]; if (channelId != knx.ChannelId) { return(frame); } var sequenceNumber = datagram[8]; var isValid = isFirstRequest || (sequenceNumber >= rxSequenceNumber); frame.FrameSequenceNumber = sequenceNumber; frame.IsValid = isValid; if (isValid) { var cemi = new byte[datagram.Length - 10]; Array.Copy(datagram, 10, cemi, 0, datagram.Length - 10); frame.CemiPacket = cemi; frame.IsValid = true; frame.Datagram = knxDatagram; } return(frame); }
public static ResponseType ProcessCEMI(ref KnxDatagram datagram, byte[] cemi, bool threeLevelGroupAddressing, bool isDebug) { try { // CEMI // +--------+--------+--------+--------+----------------+----------------+--------+----------------+ // | Msg |Add.Info| Ctrl 1 | Ctrl 2 | Source Address | Dest. Address | Data | APDU | // | Code | Length | | | | | Length | | // +--------+--------+--------+--------+----------------+----------------+--------+----------------+ // 1 byte 1 byte 1 byte 1 byte 2 bytes 2 bytes 1 byte 2 bytes // // Message Code = 0x11 - a L_Data.req primitive // COMMON EMI MESSAGE CODES FOR DATA LINK LAYER PRIMITIVES // FROM NETWORK LAYER TO DATA LINK LAYER // +---------------------------+--------------+-------------------------+---------------------+------------------+ // | Data Link Layer Primitive | Message Code | Data Link Layer Service | Service Description | Common EMI Frame | // +---------------------------+--------------+-------------------------+---------------------+------------------+ // | L_Raw.req | 0x10 | | | | // +---------------------------+--------------+-------------------------+---------------------+------------------+ // | | | | Primitive used for | Sample Common | // | L_Data.req | 0x11 | Data Service | transmitting a data | EMI frame | // | | | | frame | | // +---------------------------+--------------+-------------------------+---------------------+------------------+ // | L_Poll_Data.req | 0x13 | Poll Data Service | | | // +---------------------------+--------------+-------------------------+---------------------+------------------+ // | L_Raw.req | 0x10 | | | | // +---------------------------+--------------+-------------------------+---------------------+------------------+ // FROM DATA LINK LAYER TO NETWORK LAYER // +---------------------------+--------------+-------------------------+---------------------+ // | Data Link Layer Primitive | Message Code | Data Link Layer Service | Service Description | // +---------------------------+--------------+-------------------------+---------------------+ // | L_Poll_Data.con | 0x25 | Poll Data Service | | // +---------------------------+--------------+-------------------------+---------------------+ // | | | | Primitive used for | // | L_Data.ind | 0x29 | Data Service | receiving a data | // | | | | frame | // +---------------------------+--------------+-------------------------+---------------------+ // | L_Busmon.ind | 0x2B | Bus Monitor Service | | // +---------------------------+--------------+-------------------------+---------------------+ // | L_Raw.ind | 0x2D | | | // +---------------------------+--------------+-------------------------+---------------------+ // | | | | Primitive used for | // | | | | local confirmation | // | L_Data.con | 0x2E | Data Service | that a frame was | // | | | | sent (does not mean | // | | | | successful receive) | // +---------------------------+--------------+-------------------------+---------------------+ // | L_Raw.con | 0x2F | | | // +---------------------------+--------------+-------------------------+---------------------+ // Add.Info Length = 0x00 - no additional info // Control Field 1 = see the bit structure above // Control Field 2 = see the bit structure above // Source Address = 0x0000 - filled in by router/gateway with its source address which is // part of the KNX subnet // Dest. Address = KNX group or individual address (2 byte) // Data Length = Number of bytes of data in the APDU excluding the TPCI/APCI bits // APDU = Application Protocol Data Unit - the actual payload including transport // protocol control information (TPCI), application protocol control // information (APCI) and data passed as an argument from higher layers of // the KNX communication stack // datagram.MessageCode = cemi[0]; datagram.AdditionalInfoLength = cemi[1]; if (datagram.AdditionalInfoLength > 0) { datagram.AdditionalInfo = new byte[datagram.AdditionalInfoLength]; for (var i = 0; i < datagram.AdditionalInfoLength; i++) { datagram.AdditionalInfo[i] = cemi[2 + i]; } } datagram.ControlField1 = cemi[2 + datagram.AdditionalInfoLength]; datagram.ControlField2 = cemi[3 + datagram.AdditionalInfoLength]; datagram.SourceAddress = Networking.GetIndividualAddress(new[] { cemi[4 + datagram.AdditionalInfoLength], cemi[5 + datagram.AdditionalInfoLength] }); datagram.DestinationAddress = Networking.GetKnxDestinationAddressType(datagram.ControlField2).Equals(KnxDestinationAddressType.Individual) ? Networking.GetIndividualAddress(new[] { cemi[6 + datagram.AdditionalInfoLength], cemi[7 + datagram.AdditionalInfoLength] }) : Networking.GetGroupAddress(new[] { cemi[6 + datagram.AdditionalInfoLength], cemi[7 + datagram.AdditionalInfoLength] }, threeLevelGroupAddressing); datagram.DataLength = cemi[8 + datagram.AdditionalInfoLength]; datagram.Apdu = new byte[datagram.DataLength + 1]; for (var i = 0; i < datagram.Apdu.Length; i++) { datagram.Apdu[i] = cemi[9 + i + datagram.AdditionalInfoLength]; } datagram.Data = DataProcessing.GetData(datagram.DataLength, datagram.Apdu); if (isDebug) { System.Diagnostics.Debug.WriteLine("-----------------------------------------------------------------------------------------------------"); System.Diagnostics.Debug.WriteLine(BitConverter.ToString(cemi)); System.Diagnostics.Debug.WriteLine("Event Header Length: " + datagram.HeaderLength); System.Diagnostics.Debug.WriteLine("Event Protocol Version: " + datagram.ProtocolVersion.ToString("x")); System.Diagnostics.Debug.WriteLine("Event Service Type: 0x" + BitConverter.ToString(datagram.ServiceType).Replace("-", string.Empty)); System.Diagnostics.Debug.WriteLine("Event Total Length: " + datagram.TotalLength); System.Diagnostics.Debug.WriteLine("Event Message Code: " + datagram.MessageCode.ToString("x")); System.Diagnostics.Debug.WriteLine("Event Aditional Info Length: " + datagram.AdditionalInfoLength); if (datagram.AdditionalInfoLength > 0) { System.Diagnostics.Debug.WriteLine("Event Aditional Info: 0x" + BitConverter.ToString(datagram.AdditionalInfo).Replace("-", string.Empty)); } System.Diagnostics.Debug.WriteLine("Event Control Field 1: " + Convert.ToString(datagram.ControlField1, 2)); System.Diagnostics.Debug.WriteLine("Event Control Field 2: " + Convert.ToString(datagram.ControlField2, 2)); System.Diagnostics.Debug.WriteLine("Event Source Address: " + datagram.SourceAddress); System.Diagnostics.Debug.WriteLine("Event Destination Address: " + datagram.DestinationAddress); System.Diagnostics.Debug.WriteLine("Event Data Length: " + datagram.DataLength); System.Diagnostics.Debug.WriteLine("Event APDU: 0x" + BitConverter.ToString(datagram.Apdu).Replace("-", string.Empty)); System.Diagnostics.Debug.WriteLine("Event Data: " + datagram.Data); System.Diagnostics.Debug.WriteLine("-----------------------------------------------------------------------------------------------------"); } if (datagram.MessageCode != 0x29) { return(ResponseType.Other); } var type = datagram.Apdu[1] >> 4; switch (type) { case 8: return(ResponseType.Event); case 4: return(ResponseType.Status); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } return(ResponseType.Other); }
internal KnxStatusArgs(KnxDatagram datagram) : base(datagram) { }
public Task OnDatagram(KnxDatagram datagram) { return(Task.CompletedTask); }