예제 #1
0
        internal static bool ProcessCemi(KnxDatagram datagram, byte[] cemi)
        {
            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.AditionalInfoLength = cemi[1];

                if (datagram.AditionalInfoLength > 0)
                {
                    datagram.AditionalInfo = new byte[datagram.AditionalInfoLength];
                    for (var i = 0; i < datagram.AditionalInfoLength; i++)
                    {
                        datagram.AditionalInfo[i] = cemi[2 + i];
                    }
                }

                datagram.ControlField1 = cemi[2 + datagram.AditionalInfoLength];
                datagram.ControlField2 = cemi[3 + datagram.AditionalInfoLength];
                datagram.SourceAddress = GetIndividualAddress(new[] { cemi[4 + datagram.AditionalInfoLength], cemi[5 + datagram.AditionalInfoLength] });

                datagram.DestinationAddress =
                    GetKnxDestinationAddressType(datagram.ControlField2).Equals(KnxDestinationAddressType.Individual)
                        ? GetIndividualAddress(new[] { cemi[6 + datagram.AditionalInfoLength], cemi[7 + datagram.AditionalInfoLength] })
                        : GetGroupAddress(new[] { cemi[6 + datagram.AditionalInfoLength], cemi[7 + datagram.AditionalInfoLength] }, true);

                datagram.DataLength = cemi[8 + datagram.AditionalInfoLength];
                datagram.Apdu       = new byte[datagram.DataLength + 1];

                for (var i = 0; i < datagram.Apdu.Length; i++)
                {
                    datagram.Apdu[i] = cemi[9 + i + datagram.AditionalInfoLength];
                }

                datagram.Data = new byte[datagram.Apdu.Length - 2];
                Array.Copy(datagram.Apdu, 2, datagram.Data, 0, datagram.Apdu.Length - 2);

                if (datagram.Data.Length == 0)
                {
                    datagram.Data    = new byte[1];
                    datagram.Data[0] = (byte)(datagram.Apdu[1] & 0x01);
                }

                if (datagram.MessageCode != 0x29)
                {
                    return(false);
                }

                var type = datagram.Apdu[1] >> 4;

                return(true);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Unkown error occured");
            }

            return(false);
        }
예제 #2
0
 public KnxDatgramEventArgs(KnxDatagram datagram)
 {
     Datagram = datagram;
 }