Exemple #1
0
 def test_connect_request(self):
     """Test string representation of KNX/IP ConnectRequest."""
     xknx = XKNX(loop=self.loop)
     connect_request = ConnectRequest(xknx)
     connect_request.request_type = ConnectRequestType.TUNNEL_CONNECTION
     connect_request.control_endpoint = HPAI(ip_addr='192.168.42.1', port=33941)
     connect_request.data_endpoint = HPAI(ip_addr='192.168.42.2', port=33942)
     self.assertEqual(
         str(connect_request),
         '<ConnectRequest control_endpoint="<HPAI 192.168.42.1:33941 />" data_endpoint="<HPAI 192.168.42.2:33942 />" request_type="ConnectRequest'
         'Type.TUNNEL_CONNECTION" />')
Exemple #2
0
 def test_connect_request(self):
     """Test string representation of KNX/IP ConnectRequest."""
     xknx = XKNX(loop=self.loop)
     connect_request = ConnectRequest(xknx)
     connect_request.request_type = ConnectRequestType.TUNNEL_CONNECTION
     connect_request.control_endpoint = HPAI(ip_addr='192.168.42.1', port=33941)
     connect_request.data_endpoint = HPAI(ip_addr='192.168.42.2', port=33942)
     self.assertEqual(
         str(connect_request),
         '<ConnectRequest control_endpoint="<HPAI 192.168.42.1:33941 />" data_endpoint="<HPAI 192.168.42.2:33942 />" request_type="ConnectRequest'
         'Type.TUNNEL_CONNECTION" />')
Exemple #3
0
 def test_connect_request(self):
     """Test string representation of KNX/IP ConnectRequest."""
     xknx = XKNX()
     connect_request = ConnectRequest(xknx)
     connect_request.request_type = ConnectRequestType.TUNNEL_CONNECTION
     connect_request.control_endpoint = HPAI(ip_addr="192.168.42.1", port=33941)
     connect_request.data_endpoint = HPAI(ip_addr="192.168.42.2", port=33942)
     assert (
         str(connect_request)
         == '<ConnectRequest control_endpoint="<HPAI 192.168.42.1:33941 />" data_endpoint="<HPAI 192.168.42.2:33942 />" '
         'request_type="ConnectRequestType.TUNNEL_CONNECTION" />'
     )
Exemple #4
0
 def create_knxipframe(self) -> KNXIPFrame:
     """Create KNX/IP Frame object to be sent to device."""
     # use the same HPAI for control_endpoint and data_endpoint
     connect_request = ConnectRequest(
         request_type=ConnectRequestType.TUNNEL_CONNECTION,
         control_endpoint=self.local_hpai,
         data_endpoint=self.local_hpai,
     )
     return KNXIPFrame.init_from_body(connect_request)
Exemple #5
0
    def test_connect(self):
        """Test connecting from KNX bus."""
        xknx = XKNX()
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connect = Connect(xknx, udp_client, route_back=False)
        connect.timeout_in_seconds = 0

        self.assertEqual(connect.awaited_response_class, ConnectResponse)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            ConnectRequest(
                xknx,
                request_type=ConnectRequestType.TUNNEL_CONNECTION,
                control_endpoint=HPAI(ip_addr="192.168.1.3", port=4321),
                data_endpoint=HPAI(ip_addr="192.168.1.3", port=4321),
            )
        )

        with patch("xknx.io.UDPClient.send") as mock_udp_send, patch(
            "xknx.io.UDPClient.getsockname"
        ) as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            self.loop.run_until_complete(connect.start())
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame(xknx)
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch("logging.Logger.warning") as mock_warning:
            connect.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with("Could not understand knxipframe")

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.CONNECT_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            connect.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(connect).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.CONNECT_RESPONSE)
        res_knxipframe.body.communication_channel = 23
        res_knxipframe.body.identifier = 7
        connect.response_rec_callback(res_knxipframe, None)
        self.assertTrue(connect.success)
        self.assertEqual(connect.communication_channel, 23)
        self.assertEqual(connect.identifier, 7)
Exemple #6
0
    async def test_connect(self):
        """Test connecting from KNX bus."""
        udp_transport = UDPTransport(("192.168.1.1", 0), ("192.168.1.2", 1234))
        local_hpai = HPAI(ip_addr="192.168.1.3", port=4321)
        connect = Connect(udp_transport, local_hpai=local_hpai)
        connect.timeout_in_seconds = 0

        assert connect.awaited_response_class == ConnectResponse

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            ConnectRequest(
                request_type=ConnectRequestType.TUNNEL_CONNECTION,
                control_endpoint=local_hpai,
                data_endpoint=local_hpai,
            ))

        with patch(
                "xknx.io.transport.UDPTransport.send") as mock_udp_send, patch(
                    "xknx.io.transport.UDPTransport.getsockname"
                ) as mock_udp_getsockname:
            mock_udp_getsockname.return_value = ("192.168.1.3", 4321)
            await connect.start()
            mock_udp_send.assert_called_with(exp_knxipframe)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame()
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch("logging.Logger.warning") as mock_warning:
            connect.response_rec_callback(wrong_knxipframe, HPAI(), None)
            mock_warning.assert_called_with("Could not understand knxipframe")

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame()
        err_knxipframe.init(KNXIPServiceType.CONNECT_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            connect.response_rec_callback(err_knxipframe, HPAI(), None)
            mock_warning.assert_called_with(
                "Error: KNX bus responded to request of type '%s' with error in '%s': %s",
                type(connect).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame()
        res_knxipframe.init(KNXIPServiceType.CONNECT_RESPONSE)
        res_knxipframe.body.communication_channel = 23
        res_knxipframe.body.identifier = 7
        connect.response_rec_callback(res_knxipframe, HPAI(), None)
        assert connect.success
        assert connect.communication_channel == 23
        assert connect.identifier == 7
    def test_connect_request(self):
        """Test parsing and streaming connection request KNX/IP packet."""
        raw = (
            0x06,
            0x10,
            0x02,
            0x05,
            0x00,
            0x1A,
            0x08,
            0x01,
            0xC0,
            0xA8,
            0x2A,
            0x01,
            0x84,
            0x95,
            0x08,
            0x01,
            0xC0,
            0xA8,
            0x2A,
            0x01,
            0xCC,
            0xA9,
            0x04,
            0x04,
            0x02,
            0x00,
        )
        xknx = XKNX()
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, ConnectRequest))
        self.assertEqual(
            knxipframe.body.request_type, ConnectRequestType.TUNNEL_CONNECTION
        )
        self.assertEqual(
            knxipframe.body.control_endpoint, HPAI(ip_addr="192.168.42.1", port=33941)
        )
        self.assertEqual(
            knxipframe.body.data_endpoint, HPAI(ip_addr="192.168.42.1", port=52393)
        )

        connect_request = ConnectRequest(
            xknx,
            request_type=ConnectRequestType.TUNNEL_CONNECTION,
            control_endpoint=HPAI(ip_addr="192.168.42.1", port=33941),
            data_endpoint=HPAI(ip_addr="192.168.42.1", port=52393),
        )
        knxipframe2 = KNXIPFrame.init_from_body(connect_request)

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Exemple #8
0
 def create_knxipframe(self) -> KNXIPFrame:
     """Create KNX/IP Frame object to be sent to device."""
     (local_addr, local_port) = self.udp_client.getsockname()
     # set control_endpoint and data_endpoint to the same udp_connection
     endpoint = HPAI(ip_addr=local_addr, port=local_port)
     connect_request = ConnectRequest(
         self.xknx,
         request_type=ConnectRequestType.TUNNEL_CONNECTION,
         control_endpoint=endpoint,
         data_endpoint=endpoint,
     )
     return KNXIPFrame.init_from_body(connect_request)
Exemple #9
0
    def test_connect_request(self):
        """Test parsing and streaming connection request KNX/IP packet."""
        raw = bytes.fromhex("06 10 02 05 00 1A 08 01 C0 A8 2A 01 84 95 08 01"
                            "C0 A8 2A 01 CC A9 04 04 02 00")
        knxipframe = KNXIPFrame()
        knxipframe.from_knx(raw)

        assert isinstance(knxipframe.body, ConnectRequest)
        assert knxipframe.body.request_type == ConnectRequestType.TUNNEL_CONNECTION
        assert knxipframe.body.control_endpoint == HPAI(ip_addr="192.168.42.1",
                                                        port=33941)
        assert knxipframe.body.data_endpoint == HPAI(ip_addr="192.168.42.1",
                                                     port=52393)

        connect_request = ConnectRequest(
            request_type=ConnectRequestType.TUNNEL_CONNECTION,
            control_endpoint=HPAI(ip_addr="192.168.42.1", port=33941),
            data_endpoint=HPAI(ip_addr="192.168.42.1", port=52393),
        )
        knxipframe2 = KNXIPFrame.init_from_body(connect_request)

        assert knxipframe2.to_knx() == raw
Exemple #10
0
    async def test_tunnel_connect_send_disconnect(
        self, time_travel, route_back, data_endpoint_addr, local_endpoint
    ):
        """Test initiating a tunnelling connection."""
        local_addr = ("192.168.1.1", 12345)
        remote_addr = ("192.168.1.2", 3671)
        self.tunnel.route_back = route_back
        gateway_data_endpoint = (
            HPAI(*data_endpoint_addr) if data_endpoint_addr else HPAI()
        )
        self.tunnel.transport.connect = AsyncMock()
        self.tunnel.transport.getsockname = Mock(return_value=local_addr)
        self.tunnel.transport.send = Mock()
        self.tunnel.transport.stop = Mock()

        # Connect
        connect_request = ConnectRequest(
            control_endpoint=local_endpoint,
            data_endpoint=local_endpoint,
        )
        connect_frame = KNXIPFrame.init_from_body(connect_request)

        connection_task = asyncio.create_task(self.tunnel.connect())
        await time_travel(0)
        self.tunnel.transport.connect.assert_called_once()
        self.tunnel.transport.send.assert_called_once_with(connect_frame)

        connect_response_frame = KNXIPFrame.init_from_body(
            ConnectResponse(
                communication_channel=23,
                data_endpoint=gateway_data_endpoint,
                identifier=7,
            )
        )
        self.tunnel.transport.handle_knxipframe(connect_response_frame, remote_addr)
        await connection_task
        assert self.tunnel._data_endpoint_addr == data_endpoint_addr
        assert self.tunnel._src_address == IndividualAddress(7)

        # Send - use data endpoint
        self.tunnel.transport.send.reset_mock()
        test_telegram = Telegram(payload=GroupValueWrite(DPTArray((1,))))
        test_telegram_frame = KNXIPFrame.init_from_body(
            TunnellingRequest(
                communication_channel_id=23,
                sequence_counter=0,
                cemi=CEMIFrame.init_from_telegram(
                    test_telegram,
                    code=CEMIMessageCode.L_DATA_REQ,
                    src_addr=IndividualAddress(7),
                ),
            )
        )
        asyncio.create_task(self.tunnel.send_telegram(test_telegram))
        await time_travel(0)
        self.tunnel.transport.send.assert_called_once_with(
            test_telegram_frame, addr=data_endpoint_addr
        )
        # skip ack and confirmation

        # Disconnect
        self.tunnel.transport.send.reset_mock()
        disconnect_request = DisconnectRequest(
            communication_channel_id=23,
            control_endpoint=local_endpoint,
        )
        disconnect_frame = KNXIPFrame.init_from_body(disconnect_request)

        disconnection_task = asyncio.create_task(self.tunnel.disconnect())
        await time_travel(0)
        self.tunnel.transport.send.assert_called_once_with(disconnect_frame)

        disconnect_response_frame = KNXIPFrame.init_from_body(
            DisconnectResponse(communication_channel_id=23)
        )
        self.tunnel.transport.handle_knxipframe(disconnect_response_frame, remote_addr)
        await disconnection_task
        assert self.tunnel._data_endpoint_addr is None
        self.tunnel.transport.stop.assert_called_once()