Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        protected virtual void ConvertFromBus(KnxDatagram datagram)
        {
            var value = DptTranslator.Instance.FromDataPoint(DptTypeString, datagram.Data);

            if (ValueRead(value))
            {
                DispatchValue(value);
            }
        }
Esempio n. 3
0
 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));
        }
Esempio n. 5
0
        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);
        }
Esempio n. 8
0
 internal KnxStatusArgs(KnxDatagram datagram) : base(datagram)
 {
 }
 public Task OnDatagram(KnxDatagram datagram)
 {
     return(Task.CompletedTask);
 }