Exemple #1
0
        internal override byte[] CreateActionDatagram(string destination_address, byte[] data)
        {
            lock (this.KNXConnectionTunneling.SequenceNumberLock)
            {
                try
                {
                    int data_length = KNXHelper.GetDataLength(data);
                    // HEADER
                    byte[] dgram = new byte[10];
                    dgram[00] = 0x06;
                    dgram[01] = 0x10;
                    dgram[02] = 0x04;
                    dgram[03] = 0x20;
                    byte[] total_length = BitConverter.GetBytes(data_length + 20);
                    dgram[04] = total_length[1];
                    dgram[05] = total_length[0];

                    dgram[06] = 0x04;
                    dgram[07] = this.KNXConnectionTunneling.ChannelId;
                    dgram[08] = this.KNXConnectionTunneling.GenerateSequenceNumber();
                    dgram[09] = 0x00;

                    return(base.CreateActionDatagramCommon(destination_address, data, dgram));
                }
                catch (Exception)
                {
                    this.KNXConnectionTunneling.RevertSingleSequenceNumber();
                    return(null);
                }
            }
        }
Exemple #2
0
        protected byte[] CreateRequestStatusDatagramCommon(string destination_address, byte[] dgram, int cemi_start_pos)
        {
            int i = 0;

            if (this._connection.ActionMessageCode != 0x00)
            {
                dgram[cemi_start_pos + i++] = this._connection.ActionMessageCode;
            }
            else
            {
                dgram[cemi_start_pos + i++] = 0x11;
            }
            dgram[cemi_start_pos + i++] = 0x00;
            dgram[cemi_start_pos + i++] = 0xAC;
            if (KNXHelper.IsAddressIndividual(destination_address))
            {
                dgram[cemi_start_pos + i++] = 0x50;
            }
            else
            {
                dgram[cemi_start_pos + i++] = 0xF0;
            }
            dgram[cemi_start_pos + i++] = 0x00;
            dgram[cemi_start_pos + i++] = 0x00;
            byte[] dst_address = KNXHelper.GetAddress(destination_address);
            dgram[cemi_start_pos + i++] = dst_address[0];
            dgram[cemi_start_pos + i++] = dst_address[1];

            dgram[cemi_start_pos + i++] = 0x01;
            dgram[cemi_start_pos + i++] = 0x00;
            dgram[cemi_start_pos + i]   = 0x00;

            return(dgram);
        }
Exemple #3
0
        internal override byte[] CreateActionDatagram(string destination_address, byte[] data)
        {
            int data_length = KNXHelper.GetDataLength(data);

            // HEADER
            byte[] dgram = new byte[6];
            dgram[0] = 0x06;
            dgram[1] = 0x10;
            dgram[2] = 0x05;
            dgram[3] = 0x30;
            byte[] total_length = BitConverter.GetBytes(data_length + 16);
            dgram[4] = total_length[1];
            dgram[5] = total_length[0];

            return(base.CreateActionDatagramCommon(destination_address, data, dgram));
        }
Exemple #4
0
        internal override void ProcessDatagram(byte[] dgram)
        {
            try
            {
                switch (KNXHelper.GetServiceType(dgram))
                {
                case KNXHelper.SERVICE_TYPE.CONNECT_RESPONSE:
                    ProcessConnectResponse(dgram);
                    break;

                case KNXHelper.SERVICE_TYPE.CONNECTIONSTATE_RESPONSE:
                    ProcessConnectionStateResponse(dgram);
                    break;

                case KNXHelper.SERVICE_TYPE.TUNNELLING_ACK:
                    ProcessTunnelingAck(dgram);
                    break;

                case KNXHelper.SERVICE_TYPE.DISCONNECT_REQUEST:
                    ProcessDisconnectRequest(dgram);
                    break;

                case KNXHelper.SERVICE_TYPE.TUNNELLING_REQUEST:
                    ProcessDatagramHeaders(dgram);
                    break;
                }
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
                Console.Write(e.ToString());
                Console.Write(e.StackTrace);
                if (e.InnerException != null)
                {
                    Console.Write(e.InnerException.Message);
                    Console.Write(e.ToString());
                    Console.Write(e.InnerException.StackTrace);
                }

                // ignore, missing warning information
            }
        }
Exemple #5
0
        internal void 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.message_code          = cemi[0];
                datagram.aditional_info_length = (int)cemi[1];
                if (datagram.aditional_info_length > 0)
                {
                    datagram.aditional_info = new byte[datagram.aditional_info_length];
                    for (int i = 0; i < datagram.aditional_info_length; i++)
                    {
                        datagram.aditional_info[i] = cemi[2 + i];
                    }
                }
                datagram.control_field_1 = cemi[2 + datagram.aditional_info_length];
                datagram.control_field_2 = cemi[3 + datagram.aditional_info_length];
                datagram.source_address  = KNXHelper.GetIndividualAddress(new byte[] { cemi[4 + datagram.aditional_info_length], cemi[5 + datagram.aditional_info_length] });
                if (KNXHelper.GetKNXDestinationAddressType(datagram.control_field_2).Equals(KNXHelper.KNXDestinationAddressType.INDIVIDUAL))
                {
                    datagram.destination_address = KNXHelper.GetIndividualAddress(new byte[] { cemi[6 + datagram.aditional_info_length], cemi[7 + datagram.aditional_info_length] });
                }
                else
                {
                    datagram.destination_address = KNXHelper.GetGroupAddress(new byte[] { cemi[6 + datagram.aditional_info_length], cemi[7 + datagram.aditional_info_length] }, KNXConnection.ThreeLevelGroupAddressing);
                }

                datagram.data_length = (int)cemi[8 + datagram.aditional_info_length];
                datagram.apdu        = new byte[datagram.data_length + 1];
                for (int i = 0; i < datagram.apdu.Length; i++)
                {
                    datagram.apdu[i] = cemi[9 + i + datagram.aditional_info_length];
                }
                datagram.data = KNXHelper.GetRawData(datagram.data_length, datagram.apdu);

                if (KNXConnection.Debug)
                {
                    Console.WriteLine("-----------------------------------------------------------------------------------------------------");
                    Console.WriteLine(BitConverter.ToString(cemi));
                    Console.WriteLine("Event Header Length: " + datagram.header_length);
                    Console.WriteLine("Event Protocol Version: " + datagram.protocol_version.ToString("x"));
                    Console.WriteLine("Event Service Type: 0x" + BitConverter.ToString(datagram.service_type).Replace("-", string.Empty));
                    Console.WriteLine("Event Total Length: " + datagram.total_length);

                    Console.WriteLine("Event Message Code: " + datagram.message_code.ToString("x"));
                    Console.WriteLine("Event Aditional Info Length: " + datagram.aditional_info_length);
                    if (datagram.aditional_info_length > 0)
                    {
                        Console.WriteLine("Event Aditional Info: 0x" + BitConverter.ToString(datagram.aditional_info).Replace("-", string.Empty));
                    }
                    Console.WriteLine("Event Control Field 1: " + Convert.ToString(datagram.control_field_1, 2));
                    Console.WriteLine("Event Control Field 2: " + Convert.ToString(datagram.control_field_2, 2));
                    Console.WriteLine("Event Source Address: " + datagram.source_address);
                    Console.WriteLine("Event Destination Address: " + datagram.destination_address);
                    Console.WriteLine("Event Data Length: " + datagram.data_length);
                    Console.WriteLine("Event APDU: 0x" + BitConverter.ToString(datagram.apdu).Replace("-", string.Empty));
                    Console.WriteLine("Event Data: " + datagram.data);
                    Console.WriteLine("-----------------------------------------------------------------------------------------------------");
                }

                if (datagram.message_code == 0x29)
                {
                    int type = ((int)datagram.apdu[1]) >> 4;

                    if (type == 8)
                    {
                        this.KNXConnection.Event(datagram.source_address, datagram.destination_address, datagram.data);
                    }
                    else if (type == 4 || type == 0)
                    {
                        this.KNXConnection.Status(datagram.source_address, datagram.destination_address, datagram.data);
                    }
                }
            }
            catch (Exception)
            {
                // ignore, missing warning information
            }
        }
Exemple #6
0
        protected byte[] CreateActionDatagramCommon(string destination_address, byte[] data, byte[] header)
        {
            int i           = 0;
            int data_length = KNXHelper.GetDataLength(data);

            // HEADER
            byte[] dgram = new byte[data_length + 10 + header.Length];
            for (i = 0; i < header.Length; i++)
            {
                dgram[i] = header[i];
            }

            // CEMI (start at position 6)
            // +--------+--------+--------+--------+----------------+----------------+--------+----------------+
            // |  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
            //
            if (this._connection.ActionMessageCode != 0x00)
            {
                dgram[i++] = this._connection.ActionMessageCode;
            }
            else
            {
                dgram[i++] = 0x11;
            }
            dgram[i++] = 0x00;
            dgram[i++] = 0xAC;
            if (KNXHelper.IsAddressIndividual(destination_address))
            {
                dgram[i++] = 0x50;
            }
            else
            {
                dgram[i++] = 0xF0;
            }
            dgram[i++] = 0x00;
            dgram[i++] = 0x00;
            byte[] dst_address = KNXHelper.GetAddress(destination_address);
            dgram[i++] = dst_address[0];
            dgram[i++] = dst_address[1];
            dgram[i++] = (byte)(data_length);
            dgram[i++] = 0x00;
            dgram[i]   = 0x80;
            KNXHelper.WriteData(dgram, data, i);

            return(dgram);
        }