Пример #1
0
        public static KnxCEMI FromBytes(bool threeLevelGroupAssigning, byte[] cemiBytes)
        {
            var cemi = new KnxCEMI();

            cemi.message_code          = cemiBytes[0];
            cemi.aditional_info_length = cemiBytes[1];

            if (cemi.aditional_info_length > 0)
            {
                cemi.aditional_info = new byte[cemi.aditional_info_length];
                Array.Copy(cemiBytes, 2, cemi.aditional_info, 0, cemi.aditional_info_length);
            }

            cemi.control_field_1 = cemiBytes[2 + cemi.aditional_info_length];
            cemi.control_field_2 = cemiBytes[3 + cemi.aditional_info_length];
            cemi.source_address  = KnxHelper.GetIndividualAddress(new[] { cemiBytes[4 + cemi.aditional_info_length], cemiBytes[5 + cemi.aditional_info_length] });

            cemi.destination_address =
                KnxHelper.GetKnxDestinationAddressType(cemi.control_field_2).Equals(KnxHelper.KnxDestinationAddressType.INDIVIDUAL)
                    ? KnxHelper.GetIndividualAddress(new[] { cemiBytes[6 + cemi.aditional_info_length], cemiBytes[7 + cemi.aditional_info_length] })
                    : KnxHelper.GetGroupAddress(new[] { cemiBytes[6 + cemi.aditional_info_length], cemiBytes[7 + cemi.aditional_info_length] }, threeLevelGroupAssigning);

            var data_length = Math.Min(cemiBytes[8 + cemi.aditional_info_length], cemiBytes.Length - 10); // AR

            if (data_length > 0)
            {
                cemi.apdu = new byte[data_length];
                Array.Copy(cemiBytes, 10 + cemi.aditional_info_length, cemi.apdu, 0, data_length);
            }

            return(cemi);
        }
Пример #2
0
        /// <summary>
        ///     Send a byte array value as data to specified address
        /// </summary>
        /// <param name="address">KNX Address</param>
        /// <param name="data">Byte array value</param>
        public async void Action(string address, string type, object value)
        {
            byte[] asdu      = DataPointTranslator.Instance.ToASDU(type, value);
            var    cemi      = KnxCEMI.CreateActionCEMI(_messageCode, address, asdu);
            var    cemiBytes = cemi.ToBytes();

            // header
            var header = new byte[10];

            header[00] = 0x06; /* 06 - Header Length */
            header[01] = 0x10; /* 10 - KNXnet version (1.0) */
            header[02] = 0x04; /* 04 - hi-byte Service type descriptor (TUNNELLING_REQUEST) */
            header[03] = 0x20; /* 20 - lo-byte Service type descriptor (TUNNELLING_REQUEST) */
            var totalLength = BitConverter.GetBytes(header.Length + cemiBytes.Length);

            header[04] = totalLength[1];
            header[05] = totalLength[0];

            /* Connection Header (4 Bytes) */
            header[06] = 0x04; /* 04 - Structure length */
            header[07] = _channelId;
            header[08] = _sequenceNo++;
            header[09] = 0x00; /* 00 - Reserved */

            var datagram = new byte[header.Length + cemiBytes.Length];

            Array.Copy(header, datagram, header.Length);
            Array.Copy(cemiBytes, 0, datagram, header.Length, cemiBytes.Length);

            await _udpClient?.Send(datagram);
        }
Пример #3
0
        private void ProcessDatagramHeaders(byte[] datagram)
        {
            // HEADER
            // TODO: Might be interesting to take out these magic numbers for the datagram indices
            var knxDatagram = new KnxNetTunnelingDatagram
            {
                header_length    = datagram[0],
                protocol_version = datagram[1],
                service_type     = (ushort)((datagram[2] << 8) + datagram[3]),
                total_length     = datagram[4] + datagram[5]
            };

            var channelId = datagram[7];

            if (channelId != _channelId)
            {
                return;
            }

            var sequenceNumber = datagram[8];
            var process        = sequenceNumber > _rxSequenceNo;

            _rxSequenceNo = sequenceNumber;

            if (process)
            {
                // TODO: Magic number 10, what is it?
                var cemiBytes = new byte[datagram.Length - 10];
                Array.Copy(datagram, 10, cemiBytes, 0, datagram.Length - 10);

                var knxCEMI = KnxCEMI.FromBytes(_threeLevelGroupAssigning, cemiBytes);
                if (knxCEMI.IsEvent)
                {
                    Debug.WriteLine("KNX Event " + knxCEMI.destination_address + "  " + BitConverter.ToString(knxCEMI.apdu));

                    this.KnxEvent?.Invoke(this, new KnxEventArgs()
                    {
                        Address = knxCEMI.destination_address,
                        Data    = knxCEMI.apdu
                    });
                }
                else if (knxCEMI.IsStatus)
                {
                    Debug.WriteLine("KNX Status " + knxCEMI.destination_address + "  " + BitConverter.ToString(knxCEMI.apdu));

                    this.KnxStatus?.Invoke(this, new KnxEventArgs()
                    {
                        Address = knxCEMI.destination_address,
                        Data    = knxCEMI.apdu
                    });
                }
            }

            this.SendTunnelingAck(sequenceNumber);
        }
Пример #4
0
        public static KnxCEMI CreateStatusCEMI(byte messageCode, string destinationAddress)
        {
            KnxCEMI cemi = new KnxCEMI()
            {
                message_code          = messageCode != 0x00 ? messageCode : (byte)0x11,
                aditional_info_length = 0,
                control_field_1       = 0xAC,
                control_field_2       = KnxHelper.IsAddressIndividual(destinationAddress) ? (byte)0x50 : (byte)0xF0,
                destination_address   = destinationAddress,
                apdu      = new byte[] { 0x00 },
                _isstatus = true
            };

            return(cemi);
        }
Пример #5
0
        public static KnxCEMI CreateActionCEMI(byte messageCode, string destinationAddress, byte[] asdu)
        {
            KnxCEMI cemi = new KnxCEMI()
            {
                message_code          = messageCode != 0x00 ? messageCode : (byte)0x11,
                aditional_info_length = 0,
                control_field_1       = 0xAC,
                control_field_2       = KnxHelper.IsAddressIndividual(destinationAddress) ? (byte)0x50 : (byte)0xF0,
                destination_address   = destinationAddress,
                apdu = new byte[asdu.Length]
            };

            cemi.apdu[0] = (byte)(0x80 | (asdu[0] & 0x3f));
            for (var i = 1; i < asdu.Length; i++)
            {
                cemi.apdu[i] = asdu[i];
            }

            return(cemi);
        }