Пример #1
0
        protected byte[] CreateRequestStatusDatagramCommon(string destinationAddress, byte[] datagram, int cemi_start_pos)
        {
            var i = 0;

            datagram[cemi_start_pos + i++] =
                ActionMessageCode != 0x00
                    ? ActionMessageCode
                    : (byte)0x11;

            datagram[cemi_start_pos + i++] = 0x00;
            datagram[cemi_start_pos + i++] = 0xAC;

            datagram[cemi_start_pos + i++] =
                KnxHelper.IsAddressIndividual(destinationAddress)
                    ? (byte)0x50
                    : (byte)0xF0;

            datagram[cemi_start_pos + i++] = myAddress[0];
            datagram[cemi_start_pos + i++] = myAddress[1];
            byte[] dst_address = KnxHelper.GetAddress(destinationAddress);
            datagram[cemi_start_pos + i++] = dst_address[0];
            datagram[cemi_start_pos + i++] = dst_address[1];

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

            return(datagram);
        }
Пример #2
0
        protected byte[] CreateActionDatagram(string destinationAddress, bool b_bit, byte[] data)
        {
            try
            {
                var dataLength = KnxHelper.GetDataLength(b_bit, data);

                // HEADER
                var datagram = new byte[10];
                datagram[00] = 0x06;
                datagram[01] = 0x10;
                datagram[02] = 0x04;
                datagram[03] = 0x20;

                var totalLength = BitConverter.GetBytes(dataLength + 20);
                datagram[04] = totalLength[1];
                datagram[05] = totalLength[0];

                datagram[06] = 0x04;
                datagram[07] = ChannelId;
                datagram[08] = IncrementSequenceNumber();
                datagram[09] = 0x00;

                return(CreateActionDatagramCommon(destinationAddress, b_bit, data, datagram));
            }
            catch
            {
                DecrementSingleSequenceNumber();
                return(null);
            }
        }
Пример #3
0
        private void ProcessDatagram(byte[] datagram)
        {
            try
            {
                switch (KnxHelper.GetServiceType(datagram))
                {
                case KnxHelper.SERVICE_TYPE.CONNECT_RESPONSE:
                    ProcessConnectResponse(datagram);
                    break;

                case KnxHelper.SERVICE_TYPE.CONNECTIONSTATE_RESPONSE:
                    ProcessConnectionStateResponse(datagram);
                    break;

                case KnxHelper.SERVICE_TYPE.DISCONNECT_REQUEST:
                    ProcessDisconnectRequest(datagram);
                    break;

                case KnxHelper.SERVICE_TYPE.TUNNELLING_REQUEST:
                    ProcessDatagramHeaders(datagram);
                    break;
                }
            }
            catch (Exception e)
            {
                Logger.Log("ProcessDatagram: Exception ({0})", e.Message);
                ErrorLog.Exception("ProcessDatagram:", e);
            }
        }
Пример #4
0
        public int Connect(String address, int target_port, int src_port, string myAddress)
        {
            Logger.Log("Connect({0},{1},{2},{3})", address, target_port, src_port, myAddress);

            if (client != null)
            {
                if (client.ServerStatus == SocketStatus.SOCKET_STATUS_CONNECTED)
                {
                    DisconnectRequest();
                    client.DisableUDPServer();
                    client = null;
                }
            }

            SocketErrorCodes error = SocketErrorCodes.SOCKET_INVALID_STATE;

            try
            {
                this.myAddress = KnxHelper.GetAddress(myAddress);
                remoteEndpoint = get_IPEndpoint(address, target_port);

                if (src_port <= 0)
                {
                    src_port = target_port;
                }
                localEndpoint = get_IPEndpoint(getLocalIP(), src_port);

                client = new UDPServer(remoteEndpoint, src_port, buffersz, EthernetAdapterType.EthernetLANAdapter);

                InitialParametersClass.ReadInInitialParameters(1);

                error = client.EnableUDPServer();
                if (error == SocketErrorCodes.SOCKET_OK)
                {
                    // start recieveing
                    //error = client.ReceiveDataAsync(udpReceiver);
                    //if (error == SocketErrorCodes.SOCKET_OPERATION_PENDING)
                    //{
                    error = ConnectRequest();
                    if (error != SocketErrorCodes.SOCKET_OK)
                    {
                        client.DisableUDPServer();
                        client = null;
                    }
                    else
                    {
                        udpReadTimer.Reset();
                        stateRequestTimer.Reset(stateRequestTimerInterval);
                    }
                }
            }
            catch (System.Exception e)
            {
                Logger.Log("Connect: Exception ({0})", e.Message);
                return(-1);
            }

            Logger.Log("Connect: ({0})", error);
            return(Convert.ToInt32(error));
        }
Пример #5
0
        protected byte[] CreateActionDatagramCommon(string destinationAddress, bool b_bit, byte[] data, byte[] header)
        {
            int i;
            var dataLength = KnxHelper.GetDataLength(b_bit, data);

            // HEADER
            var datagram = new byte[dataLength + 10 + header.Length];

            for (i = 0; i < header.Length; i++)
            {
                datagram[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
            //

            datagram[i++] =
                ActionMessageCode != 0x00
                    ? ActionMessageCode
                    : (byte)0x11;

            datagram[i++] = 0x00;
            datagram[i++] = 0xAC;

            datagram[i++] =
                KnxHelper.IsAddressIndividual(destinationAddress)
                    ? (byte)0x50
                    : (byte)0xF0;

            datagram[i++] = myAddress[0];   // Source address
            datagram[i++] = myAddress[1];
            var dst_address = KnxHelper.GetAddress(destinationAddress);

            datagram[i++] = dst_address[0];
            datagram[i++] = dst_address[1];
            datagram[i++] = (byte)dataLength;
            datagram[i++] = 0x00;
            datagram[i]   = 0x80;

            KnxHelper.WriteData(datagram, b_bit, data, i);

            return(datagram);
        }
Пример #6
0
        protected 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 = cemi[1];

                if (datagram.aditional_info_length > 0)
                {
                    datagram.aditional_info = new byte[datagram.aditional_info_length];
                    for (var 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[] { cemi[4 + datagram.aditional_info_length], cemi[5 + datagram.aditional_info_length] });

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

                datagram.data_length = cemi[8 + datagram.aditional_info_length];
                datagram.apdu        = new byte[datagram.data_length + 1];

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

                datagram.data = KnxHelper.GetData(datagram.data_length, datagram.apdu);

                Logger.Log("-----------------------------------------------------------------------------------------------------");
                Logger.Log(BitConverter.ToString(cemi));
                Logger.Log("Event Header Length: " + datagram.header_length);
                Logger.Log("Event Protocol Version: " + datagram.protocol_version.ToString("x"));
                Logger.Log("Event Service Type: 0x" + BitConverter.ToString(datagram.service_type).Replace("-", string.Empty));
                Logger.Log("Event Total Length: " + datagram.total_length);

                Logger.Log("Event Message Code: " + datagram.message_code.ToString("x"));
                Logger.Log("Event Aditional Info Length: " + datagram.aditional_info_length);

                if (datagram.aditional_info_length > 0)
                {
                    Logger.Log("Event Aditional Info: 0x" + BitConverter.ToString(datagram.aditional_info).Replace("-", string.Empty));
                }

                Logger.Log("Event Control Field 1: " + Convert.ToString(datagram.control_field_1, 2));
                Logger.Log("Event Control Field 2: " + Convert.ToString(datagram.control_field_2, 2));
                Logger.Log("Event Source Address: " + datagram.source_address);
                Logger.Log("Event Destination Address: " + datagram.destination_address);
                Logger.Log("Event Data Length: " + datagram.data_length);
                Logger.Log("Event APDU: 0x" + BitConverter.ToString(datagram.apdu).Replace("-", string.Empty));
                Logger.Log("-----------------------------------------------------------------------------------------------------");

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

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

                switch (type)
                {
                case 8:
                    BuildAndExecuteKnxRx(datagram);
                    Logger.Log("{0}", datagram.source_address);
                    break;

                case 4:
                    BuildAndExecuteKnxRx(datagram);
                    Logger.Log("Device {0} status {1}", datagram.source_address, datagram.destination_address);
                    break;
                }
            }
            catch (Exception e)
            {
                Logger.Log("ProcessCEMI: {0}", e.Message);
            }
        }