Ejemplo n.º 1
0
 def test_from_knx_wrong_info(self):
     """Test parsing and streaming wrong ConnectionStateRequest."""
     raw = ((0x06, 0x10, 0x02, 0x07, 0x00, 0x010))
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
Ejemplo n.º 2
0
 def test_from_knx_wrong_length(self):
     """Test parsing and streaming wrong DisconnectResponse."""
     raw = ((0x06, 0x10, 0x02, 0x0A, 0x00, 0x08, 0x15))
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
Ejemplo n.º 3
0
 def test_from_knx_wrong_header2(self):
     """Test parsing and streaming wrong TunnellingRequest (wrong header length)."""
     raw = ((0x06, 0x10, 0x04, 0x20, 0x00, 0x15, 0x04))
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
Ejemplo n.º 4
0
 def test_from_knx_wrong_header(self):
     """Test parsing and streaming wrong ConnectionStateResponse (wrong header length)."""
     raw = ((0x06, 0x10, 0x02, 0x08, 0x00, 0x08, 0x15))
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
Ejemplo n.º 5
0
 def test_from_knx_wrong_ack_information2(self):
     """Test parsing and streaming wrong TunnellingAck (wrong length)."""
     raw = ((0x06, 0x10, 0x04, 0x21, 0x00, 0x0a, 0x04, 0x2a,
             0x17))
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
Ejemplo n.º 6
0
 def test_parsing_too_long_knxip(self):
     """Test parsing and streaming connection state request KNX/IP packet."""
     raw = ((0x06, 0x10, 0x02, 0x07, 0x00, 0x10, 0x15, 0x00,
             0x08, 0x01, 0xC0, 0xA8, 0xC8, 0x0C, 0xC3, 0xB4, 0x00))
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
Ejemplo n.º 7
0
 def send_ack(self, communication_channel_id, sequence_counter):
     """Send tunnelling ACK after tunnelling request received."""
     ack_knxipframe = KNXIPFrame(self.xknx)
     ack_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
     ack_knxipframe.body.communication_channel_id = communication_channel_id
     ack_knxipframe.body.sequence_counter = sequence_counter
     ack_knxipframe.normalize()
     self.udp_client.send(ack_knxipframe)
Ejemplo n.º 8
0
 def create_knxipframe(self):
     """Create KNX/IP Frame object to be sent to device."""
     knxipframe = KNXIPFrame(self.xknx)
     knxipframe.init(KNXIPServiceType.TUNNELLING_REQUEST)
     knxipframe.body.communication_channel_id = self.communication_channel_id
     knxipframe.body.cemi.telegram = self.telegram
     knxipframe.body.cemi.src_addr = self.src_address
     knxipframe.body.sequence_counter = self.sequence_counter
     return knxipframe
Ejemplo n.º 9
0
 async def send_telegram(self, telegram):
     """Send Telegram to routing connected device."""
     knxipframe = KNXIPFrame(self.xknx)
     knxipframe.init(KNXIPServiceType.ROUTING_INDICATION)
     knxipframe.body.src_addr = self.xknx.own_address
     knxipframe.body.telegram = telegram
     knxipframe.body.sender = self.xknx.own_address
     knxipframe.normalize()
     await self.send_knxipframe(knxipframe)
Ejemplo n.º 10
0
 def create_knxipframe(self):
     """Create KNX/IP Frame object to be sent to device."""
     (local_addr, local_port) = self.udpclient.getsockname()
     knxipframe = KNXIPFrame(self.xknx)
     knxipframe.init(KNXIPServiceType.DISCONNECT_REQUEST)
     knxipframe.body.communication_channel_id = \
         self.communication_channel_id
     knxipframe.body.control_endpoint = HPAI(
         ip_addr=local_addr, port=local_port)
     return knxipframe
Ejemplo n.º 11
0
 def test_knxip_frame(self):
     """Test string representation of KNX/IP Frame."""
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     knxipframe.init(KNXIPServiceType.SEARCH_REQUEST)
     self.assertEqual(
         str(knxipframe),
         '<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="KNXIPServiceType.SEARCH_REQUEST" Reserve="0" TotalLeng'
         'th="0" />\n'
         ' body="<SearchRequest discovery_endpoint="<HPAI 224.0.23.12:3671 />" />" />')
Ejemplo n.º 12
0
    def test_connect_request(self):
        """Test parsing and streaming connection tunneling request KNX/IP packet."""
        raw = ((0x06, 0x10, 0x04, 0x20, 0x00, 0x15, 0x04, 0x01,
                0x17, 0x00, 0x11, 0x00, 0xbc, 0xe0, 0x00, 0x00,
                0x48, 0x08, 0x01, 0x00, 0x81))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, TunnellingRequest))
        self.assertEqual(knxipframe.body.communication_channel_id, 1)
        self.assertEqual(knxipframe.body.sequence_counter, 23)
        self.assertTrue(isinstance(knxipframe.body.cemi, CEMIFrame))

        self.assertEqual(knxipframe.body.cemi.telegram,
                         Telegram(GroupAddress('9/0/8'), payload=DPTBinary(1)))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.TUNNELLING_REQUEST)
        knxipframe2.body.cemi.telegram = Telegram(
            GroupAddress('9/0/8'), payload=DPTBinary(1))
        knxipframe2.body.sequence_counter = 23
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 13
0
    async def _search_interface(self, interface, ip_addr):
        """Send a search request on a specific interface."""
        self.xknx.logger.debug("Searching on %s / %s", interface, ip_addr)

        udp_client = UDPClient(self.xknx,
                               (ip_addr, 0, interface),
                               (DEFAULT_MCAST_GRP, DEFAULT_MCAST_PORT),
                               multicast=True)

        udp_client.register_callback(
            self._response_rec_callback, [KNXIPServiceType.SEARCH_RESPONSE])
        await udp_client.connect()

        self._udp_clients.append(udp_client)

        (local_addr, local_port) = udp_client.getsockname()
        knx_ip_frame = KNXIPFrame(self.xknx)
        knx_ip_frame.init(KNXIPServiceType.SEARCH_REQUEST)
        knx_ip_frame.body.discovery_endpoint = \
            HPAI(ip_addr=local_addr, port=local_port)
        knx_ip_frame.normalize()
        udp_client.send(knx_ip_frame)
Ejemplo n.º 14
0
    def test_search_response(self):
        """Test parsing and streaming SearchResponse KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x02, 0x00, 0x50, 0x08, 0x01,
                0xc0, 0xa8, 0x2a, 0x0a, 0x0e, 0x57, 0x36, 0x01,
                0x02, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x22,
                0x33, 0x44, 0x55, 0x66, 0xe0, 0x00, 0x17, 0x0c,
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x47, 0x69,
                0x72, 0x61, 0x20, 0x4b, 0x4e, 0x58, 0x2f, 0x49,
                0x50, 0x2d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x02, 0x01,
                0x03, 0x02, 0x04, 0x01, 0x05, 0x01, 0x07, 0x01))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        self.assertEqual(knxipframe.from_knx(raw), 80)
        self.assertEqual(knxipframe.to_knx(), list(raw))

        self.assertTrue(isinstance(knxipframe.body, SearchResponse))
        self.assertEqual(
            knxipframe.body.control_endpoint,
            HPAI("192.168.42.10", 3671))
        self.assertEqual(len(knxipframe.body.dibs), 2)
        # Specific testing of parsing and serializing of
        # DIBDeviceInformation and DIBSuppSVCFamilies is
        # done within knxip_dib_test.py
        self.assertTrue(isinstance(
            knxipframe.body.dibs[0], DIBDeviceInformation))
        self.assertTrue(isinstance(
            knxipframe.body.dibs[1], DIBSuppSVCFamilies))
        self.assertEqual(knxipframe.body.device_name, "Gira KNX/IP-Router")
        self.assertTrue(knxipframe.body.dibs[1].supports(DIBServiceFamily.ROUTING))
        self.assertTrue(knxipframe.body.dibs[1].supports(DIBServiceFamily.TUNNELING))
        self.assertFalse(knxipframe.body.dibs[1].supports(DIBServiceFamily.OBJECT_SERVER))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.SEARCH_RESPONSE)
        knxipframe2.body.control_endpoint = \
            HPAI(ip_addr="192.168.42.10", port=3671)
        knxipframe2.body.dibs.append(knxipframe.body.dibs[0])
        knxipframe2.body.dibs.append(knxipframe.body.dibs[1])
        knxipframe2.normalize()
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 15
0
    def test_search_request(self):
        """Test parsing and streaming SearchRequest KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x01, 0x00, 0x0e, 0x08, 0x01,
                0xe0, 0x00, 0x17, 0x0c, 0x0e, 0x57))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, SearchRequest))
        self.assertEqual(
            knxipframe.body.discovery_endpoint,
            HPAI(ip_addr="224.0.23.12", port=3671))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.SEARCH_REQUEST)
        knxipframe2.body.discovery_endpoint = \
            HPAI(ip_addr="224.0.23.12", port=3671)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 16
0
    def test_disconnect_response(self):
        """Test parsing and streaming connection state response KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x08, 0x00, 0x08, 0x15, 0x21))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, ConnectionStateResponse))

        self.assertEqual(
            knxipframe.body.communication_channel_id, 21)
        self.assertEqual(
            knxipframe.body.status_code, ErrorCode.E_CONNECTION_ID)

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        knxipframe2.body.communication_channel_id = 21
        knxipframe2.body.status_code = ErrorCode.E_CONNECTION_ID
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 17
0
    def test_connect_request(self):
        """Test parsing and streaming tunneling ACK KNX/IP packet."""
        raw = ((0x06, 0x10, 0x04, 0x21, 0x00, 0x0a, 0x04, 0x2a,
                0x17, 0x00))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, TunnellingAck))
        self.assertEqual(knxipframe.body.communication_channel_id, 42)
        self.assertEqual(knxipframe.body.sequence_counter, 23)
        self.assertEqual(
            knxipframe.body.status_code,
            ErrorCode.E_NO_ERROR)

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.TUNNELLING_ACK)
        knxipframe2.body.communication_channel_id = 42
        knxipframe2.body.sequence_counter = 23
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 18
0
    def test_disconnect_request(self):
        """Test parsing and streaming DisconnectRequest KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x09, 0x00, 0x10, 0x15, 0x00,
                0x08, 0x01, 0xC0, 0xA8, 0xC8, 0x0C, 0xC3, 0xB4))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, DisconnectRequest))

        self.assertEqual(
            knxipframe.body.communication_channel_id, 21)
        self.assertEqual(
            knxipframe.body.control_endpoint,
            HPAI(ip_addr='192.168.200.12', port=50100))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.DISCONNECT_REQUEST)
        knxipframe2.body.communication_channel_id = 21
        knxipframe2.body.control_endpoint = HPAI(
            ip_addr='192.168.200.12', port=50100)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 19
0
def fake_router_search_response(xknx: XKNX) -> SearchResponse:
    """Return the SearchResponse of a KNX/IP Router."""
    _frame_header = KNXIPHeader(xknx)
    _frame_header.service_type_ident = KNXIPServiceType.SEARCH_RESPONSE
    _frame_body = SearchResponse(xknx)
    _frame_body.control_endpoint = HPAI(ip_addr="192.168.42.10", port=3671)

    _device_information = DIBDeviceInformation()
    _device_information.name = "Gira KNX/IP-Router"
    _device_information.serial_number = "11:22:33:44:55:66"
    _device_information.individual_address = PhysicalAddress("1.1.0")
    _device_information.mac_address = "01:02:03:04:05:06"

    _svc_families = DIBSuppSVCFamilies()
    _svc_families.families.append(
        DIBSuppSVCFamilies.Family(name=DIBServiceFamily.CORE,
                                  version=1))
    _svc_families.families.append(
        DIBSuppSVCFamilies.Family(name=DIBServiceFamily.DEVICE_MANAGEMENT,
                                  version=2))
    _svc_families.families.append(
        DIBSuppSVCFamilies.Family(name=DIBServiceFamily.TUNNELING,
                                  version=1))
    _svc_families.families.append(
        DIBSuppSVCFamilies.Family(name=DIBServiceFamily.ROUTING,
                                  version=1))
    _svc_families.families.append(
        DIBSuppSVCFamilies.Family(name=DIBServiceFamily.REMOTE_CONFIGURATION_DIAGNOSIS,
                                  version=1))

    _frame_body.dibs.append(_device_information)
    _frame_body.dibs.append(_svc_families)
    _frame_header.set_length(_frame_body)

    search_response = KNXIPFrame(xknx)
    search_response.init(KNXIPServiceType.SEARCH_RESPONSE)
    search_response.header = _frame_header
    search_response.body = _frame_body
    search_response.normalize()

    return search_response
Ejemplo n.º 20
0
    def test_EndTOEnd_group_read(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, group read."""
        # State request
        raw = ((0x06, 0x10, 0x05, 0x30, 0x00, 0x11, 0x29, 0x00, 0xbc, 0xd0,
                0xff, 0xf9, 0x01, 0xb8, 0x01, 0x00, 0x00))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        telegram = knxipframe.body.cemi.telegram
        self.assertEqual(
            telegram, Telegram(GroupAddress("440"), TelegramType.GROUP_READ))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.ROUTING_INDICATION)
        knxipframe2.body.cemi.src_addr = PhysicalAddress("15.15.249")
        knxipframe2.body.cemi.telegram = telegram
        knxipframe2.body.cemi.set_hops(5)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.header.to_knx(), list(raw[0:6]))
        self.assertEqual(knxipframe2.body.to_knx(), list(raw[6:]))
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 21
0
    def test_connect_request(self):
        """Test parsing and streaming SearchResponse KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x02, 0x00, 0x50, 0x08, 0x01, 0xc0, 0xa8,
                0x2a, 0x0a, 0x0e, 0x57, 0x36, 0x01, 0x02, 0x00, 0x11, 0x00,
                0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xe0, 0x00,
                0x17, 0x0c, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x47, 0x69,
                0x72, 0x61, 0x20, 0x4b, 0x4e, 0x58, 0x2f, 0x49, 0x50, 0x2d,
                0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02,
                0x02, 0x01, 0x03, 0x02, 0x04, 0x01, 0x05, 0x01, 0x07, 0x01))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        self.assertEqual(knxipframe.from_knx(raw), 80)
        self.assertEqual(knxipframe.to_knx(), list(raw))

        self.assertTrue(isinstance(knxipframe.body, SearchResponse))
        self.assertEqual(knxipframe.body.control_endpoint,
                         HPAI("192.168.42.10", 3671))
        self.assertEqual(len(knxipframe.body.dibs), 2)
        # Specific testing of parsing and serializing of
        # DIBDeviceInformation and DIBSuppSVCFamilies is
        # done within knxip_dib_test.py
        self.assertTrue(
            isinstance(knxipframe.body.dibs[0], DIBDeviceInformation))
        self.assertTrue(isinstance(knxipframe.body.dibs[1],
                                   DIBSuppSVCFamilies))
        self.assertEqual(knxipframe.body.device_name, "Gira KNX/IP-Router")
        self.assertTrue(knxipframe.body.dibs[1].supports(
            DIBServiceFamily.ROUTING))
        self.assertTrue(knxipframe.body.dibs[1].supports(
            DIBServiceFamily.TUNNELING))
        self.assertFalse(knxipframe.body.dibs[1].supports(
            DIBServiceFamily.OBJECT_SERVER))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.SEARCH_RESPONSE)
        knxipframe2.body.control_endpoint = \
            HPAI(ip_addr="192.168.42.10", port=3671)
        knxipframe2.body.dibs.append(knxipframe.body.dibs[0])
        knxipframe2.body.dibs.append(knxipframe.body.dibs[1])
        knxipframe2.normalize()
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 22
0
    def test_EndTOEnd_group_response(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, group response."""
        # Incoming state
        raw = ((0x06, 0x10, 0x05, 0x30, 0x00, 0x11, 0x29, 0x00, 0xbc, 0xd0,
                0x13, 0x01, 0x01, 0x88, 0x01, 0x00, 0x41))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        telegram = knxipframe.body.cemi.telegram
        self.assertEqual(
            telegram,
            Telegram(GroupAddress("392"),
                     TelegramType.GROUP_RESPONSE,
                     payload=DPTBinary(1)))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.ROUTING_INDICATION)
        knxipframe2.body.cemi.src_addr = PhysicalAddress("1.3.1")
        knxipframe2.body.cemi.telegram = telegram
        knxipframe2.body.cemi.set_hops(5)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.header.to_knx(), list(raw[0:6]))
        self.assertEqual(knxipframe2.body.to_knx(), list(raw[6:]))
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 23
0
    async def test_tunnelling(self):
        """Test tunnelling from KNX bus."""
        communication_channel_id = 23
        data_endpoint = ("192.168.1.2", 4567)
        udp_transport = UDPTransport(("192.168.1.1", 0), ("192.168.1.2", 1234))
        telegram = Telegram(
            destination_address=GroupAddress("1/2/3"),
            payload=GroupValueWrite(DPTArray((0x1, 0x2, 0x3))),
        )
        sequence_counter = 42
        src_address = IndividualAddress("2.2.2")
        tunnelling = Tunnelling(
            udp_transport,
            data_endpoint,
            telegram,
            src_address,
            sequence_counter,
            communication_channel_id,
        )
        tunnelling.timeout_in_seconds = 0

        assert tunnelling.awaited_response_class == TunnellingAck
        assert tunnelling.communication_channel_id == communication_channel_id

        # Expected KNX/IP-Frame:
        tunnelling_request = TunnellingRequest(
            communication_channel_id=communication_channel_id,
            sequence_counter=sequence_counter,
        )
        tunnelling_request.cemi.telegram = telegram
        tunnelling_request.cemi.src_addr = src_address
        exp_knxipframe = KNXIPFrame.init_from_body(tunnelling_request)
        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 tunnelling.start()
            mock_udp_send.assert_called_with(exp_knxipframe,
                                             addr=data_endpoint)

        # Response KNX/IP-Frame with wrong type
        wrong_knxipframe = KNXIPFrame()
        wrong_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        with patch("logging.Logger.warning") as mock_warning:
            tunnelling.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.TUNNELLING_ACK)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            tunnelling.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(tunnelling).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame()
        res_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        tunnelling.response_rec_callback(res_knxipframe, HPAI(), None)
        assert tunnelling.success
Ejemplo n.º 24
0
    def test_search_request(self):
        """Test parsing and streaming SearchRequest KNX/IP packet."""
        raw = (
            0x06,
            0x10,
            0x02,
            0x01,
            0x00,
            0x0E,
            0x08,
            0x01,
            0xE0,
            0x00,
            0x17,
            0x0C,
            0x0E,
            0x57,
        )
        xknx = XKNX()
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, SearchRequest))
        self.assertEqual(knxipframe.body.discovery_endpoint,
                         HPAI(ip_addr="224.0.23.12", port=3671))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.SEARCH_REQUEST)
        knxipframe2.body.discovery_endpoint = HPAI(ip_addr="224.0.23.12",
                                                   port=3671)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 25
0
    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(loop=self.loop)
        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))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.CONNECT_REQUEST)
        knxipframe2.body.request_type = ConnectRequestType.TUNNEL_CONNECTION
        knxipframe2.body.control_endpoint = HPAI(ip_addr='192.168.42.1',
                                                 port=33941)
        knxipframe2.body.data_endpoint = HPAI(ip_addr='192.168.42.1',
                                              port=52393)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 26
0
    def test_EndTOEnd_group_write_1byte(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, dimm light in my kitchen."""
        # Dimm Kitchen L1 to 0x65
        raw = ((0x06, 0x10, 0x05, 0x30, 0x00, 0x12, 0x29, 0x00, 0xbc, 0xd0,
                0xff, 0xf9, 0x01, 0x4b, 0x02, 0x00, 0x80, 0x65))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        telegram = knxipframe.body.cemi.telegram
        self.assertEqual(telegram,
                         Telegram(GroupAddress("331"), payload=DPTArray(0x65)))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.ROUTING_INDICATION)
        knxipframe2.body.cemi.src_addr = PhysicalAddress("15.15.249")
        knxipframe2.body.cemi.telegram = telegram
        knxipframe2.body.cemi.set_hops(5)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.header.to_knx(), list(raw[0:6]))
        self.assertEqual(knxipframe2.body.to_knx(), list(raw[6:]))
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 27
0
 def test_parsing_too_short_knxip(self):
     """Test parsing and streaming connection state request KNX/IP packet."""
     raw = bytes.fromhex("06 10 02 07 00 10 15 00 08 01 C0 A8 C8 0C C3")
     knxipframe = KNXIPFrame()
     with pytest.raises(IncompleteKNXIPFrame):
         knxipframe.from_knx(raw)
Ejemplo n.º 28
0
    async def test_connectionstate_route_back_true(self):
        """Test connectionstateing from KNX bus."""
        communication_channel_id = 23
        udp_transport = UDPTransport(("192.168.1.1", 0), ("192.168.1.2", 1234))
        local_hpai = HPAI()
        connectionstate = ConnectionState(udp_transport,
                                          communication_channel_id,
                                          local_hpai=local_hpai)
        connectionstate.timeout_in_seconds = 0

        assert connectionstate.awaited_response_class == ConnectionStateResponse
        assert connectionstate.communication_channel_id == communication_channel_id

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            ConnectionStateRequest(
                communication_channel_id=communication_channel_id, ))
        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 connectionstate.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:
            connectionstate.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.CONNECTIONSTATE_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            connectionstate.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(connectionstate).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame()
        res_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        connectionstate.response_rec_callback(res_knxipframe, HPAI(), None)
        assert connectionstate.success
    def test_connect_response(self):
        """Test parsing and streaming connection response KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x06, 0x00, 0x14, 0x01, 0x00, 0x08, 0x01,
                0xc0, 0xa8, 0x2a, 0x0a, 0x0e, 0x57, 0x04, 0x04, 0x11, 0xff))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        self.assertTrue(isinstance(knxipframe.body, ConnectResponse))
        self.assertEqual(knxipframe.body.communication_channel, 1)
        self.assertEqual(knxipframe.body.status_code, ErrorCode.E_NO_ERROR)
        self.assertEqual(knxipframe.body.control_endpoint,
                         HPAI(ip_addr='192.168.42.10', port=3671))
        self.assertEqual(knxipframe.body.request_type,
                         ConnectRequestType.TUNNEL_CONNECTION)
        self.assertEqual(knxipframe.body.identifier, 4607)

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.CONNECT_RESPONSE)
        knxipframe2.status_code = ErrorCode.E_NO_ERROR
        knxipframe2.body.communication_channel = 1
        knxipframe2.body.request_type = ConnectRequestType.TUNNEL_CONNECTION
        knxipframe2.body.control_endpoint = HPAI(ip_addr='192.168.42.10',
                                                 port=3671)
        knxipframe2.body.identifier = 4607
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 30
0
    def test_search_response(self):
        """Test parsing and streaming SearchResponse KNX/IP packet."""
        raw = (
            0x06,
            0x10,
            0x02,
            0x02,
            0x00,
            0x50,
            0x08,
            0x01,
            0xC0,
            0xA8,
            0x2A,
            0x0A,
            0x0E,
            0x57,
            0x36,
            0x01,
            0x02,
            0x00,
            0x11,
            0x00,
            0x00,
            0x00,
            0x11,
            0x22,
            0x33,
            0x44,
            0x55,
            0x66,
            0xE0,
            0x00,
            0x17,
            0x0C,
            0x01,
            0x02,
            0x03,
            0x04,
            0x05,
            0x06,
            0x47,
            0x69,
            0x72,
            0x61,
            0x20,
            0x4B,
            0x4E,
            0x58,
            0x2F,
            0x49,
            0x50,
            0x2D,
            0x52,
            0x6F,
            0x75,
            0x74,
            0x65,
            0x72,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x0C,
            0x02,
            0x02,
            0x01,
            0x03,
            0x02,
            0x04,
            0x01,
            0x05,
            0x01,
            0x07,
            0x01,
        )
        xknx = XKNX()
        knxipframe = KNXIPFrame(xknx)
        assert knxipframe.from_knx(raw) == 80
        assert knxipframe.to_knx() == list(raw)

        assert isinstance(knxipframe.body, SearchResponse)
        assert knxipframe.body.control_endpoint == HPAI("192.168.42.10", 3671)
        assert len(knxipframe.body.dibs) == 2
        # Specific testing of parsing and serializing of
        # DIBDeviceInformation and DIBSuppSVCFamilies is
        # done within knxip_dib_test.py
        assert isinstance(knxipframe.body.dibs[0], DIBDeviceInformation)
        assert isinstance(knxipframe.body.dibs[1], DIBSuppSVCFamilies)
        assert knxipframe.body.device_name == "Gira KNX/IP-Router"
        assert knxipframe.body.dibs[1].supports(DIBServiceFamily.ROUTING)
        assert knxipframe.body.dibs[1].supports(DIBServiceFamily.TUNNELING)
        assert not knxipframe.body.dibs[1].supports(DIBServiceFamily.OBJECT_SERVER)

        search_response = SearchResponse(
            xknx, control_endpoint=HPAI(ip_addr="192.168.42.10", port=3671)
        )
        search_response.dibs.append(knxipframe.body.dibs[0])
        search_response.dibs.append(knxipframe.body.dibs[1])
        knxipframe2 = KNXIPFrame.init_from_body(search_response)

        assert knxipframe2.to_knx() == list(raw)
Ejemplo n.º 31
0
    def test_connect_request(self):

        raw = ((0x06, 0x10, 0x04, 0x21, 0x00, 0x0a, 0x04, 0x2a, 0x17, 0x00))

        knxipframe = KNXIPFrame()
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, TunnellingAck))
        self.assertEqual(knxipframe.body.communication_channel_id, 42)
        self.assertEqual(knxipframe.body.sequence_counter, 23)
        self.assertEqual(knxipframe.body.status_code, ErrorCode.E_NO_ERROR)

        knxipframe2 = KNXIPFrame()
        knxipframe2.init(KNXIPServiceType.TUNNELLING_ACK)
        knxipframe2.body.communication_channel_id = 42
        knxipframe2.body.sequence_counter = 23
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 32
0
 def test_from_knx_wrong_length(self):
     """Test parsing and streaming wrong DisconnectRequest."""
     raw = bytes((0x06, 0x10, 0x02, 0x09, 0x00, 0x10))
     knxipframe = KNXIPFrame()
     with pytest.raises(CouldNotParseKNXIP):
         knxipframe.from_knx(raw)
    def test_disconnect_response(self):
        raw = ((0x06, 0x10, 0x02, 0x0A, 0x00, 0x08, 0x15, 0x25))

        knxipframe = KNXIPFrame()
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, DisconnectResponse))

        self.assertEqual(knxipframe.body.communication_channel_id, 21)
        self.assertEqual(knxipframe.body.status_code,
                         ErrorCode.E_NO_MORE_UNIQUE_CONNECTIONS)

        knxipframe2 = KNXIPFrame()
        knxipframe2.init(KNXIPServiceType.DISCONNECT_RESPONSE)
        knxipframe2.body.communication_channel_id = 21
        knxipframe2.body.status_code = ErrorCode.E_NO_MORE_UNIQUE_CONNECTIONS
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 34
0
    def test_connect_request(self):

        raw = ((0x06, 0x10, 0x02, 0x01, 0x00, 0x0e, 0x08, 0x01,
                0xe0, 0x00, 0x17, 0x0c, 0x0e, 0x57))

        knxipframe = KNXIPFrame()
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, SearchRequest))
        self.assertEqual(
            knxipframe.body.discovery_endpoint,
            HPAI(ip_addr="224.0.23.12", port=3671))

        knxipframe2 = KNXIPFrame()
        knxipframe2.init(KNXIPServiceType.SEARCH_REQUEST)
        knxipframe2.body.discovery_endpoint = \
            HPAI(ip_addr="224.0.23.12", port=3671)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 35
0
    def test_disconnect_request(self):
        """Test parsing and streaming DisconnectRequest KNX/IP packet."""
        raw = ((0x06, 0x10, 0x02, 0x09, 0x00, 0x10, 0x15, 0x00, 0x08, 0x01,
                0xC0, 0xA8, 0xC8, 0x0C, 0xC3, 0xB4))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, DisconnectRequest))

        self.assertEqual(knxipframe.body.communication_channel_id, 21)
        self.assertEqual(knxipframe.body.control_endpoint,
                         HPAI(ip_addr='192.168.200.12', port=50100))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.DISCONNECT_REQUEST)
        knxipframe2.body.communication_channel_id = 21
        knxipframe2.body.control_endpoint = HPAI(ip_addr='192.168.200.12',
                                                 port=50100)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 36
0
 def test_wrong_init(self):
     """Testing init method with wrong service_type_ident."""
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(TypeError):
         knxipframe.init(23)
Ejemplo n.º 37
0
 def test_to_knx_no_body(self):
     """Test to_knx method without body raises exception."""
     knxipframe = KNXIPFrame()
     with pytest.raises(CouldNotParseKNXIP):
         knxipframe.to_knx()
Ejemplo n.º 38
0
    def test_connect_response_connection_error(self):
        """Test parsing and streaming connection response KNX/IP packet with error."""
        raw = (0x06, 0x10, 0x02, 0x06, 0x00, 0x08, 0x00, 0x24)
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        self.assertTrue(isinstance(knxipframe.body, ConnectResponse))
        self.assertEqual(knxipframe.body.status_code, ErrorCode.E_NO_MORE_CONNECTIONS)
        self.assertEqual(knxipframe.body.communication_channel, 0)

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.CONNECT_RESPONSE)
        knxipframe2.body.status_code = ErrorCode.E_NO_MORE_CONNECTIONS
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 39
0
    def test_connect(self):
        """Test connecting from KNX bus."""
        xknx = XKNX(loop=self.loop)
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connect = Connect(xknx, udp_client)
        connect.timeout_in_seconds = 0

        self.assertEqual(connect.awaited_response_class, ConnectResponse)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.CONNECT_REQUEST)
        exp_knxipframe.body.control_endpoint = HPAI(ip_addr='192.168.1.3',
                                                    port=4321)
        exp_knxipframe.body.data_endpoint = HPAI(ip_addr='192.168.1.3',
                                                 port=4321)
        exp_knxipframe.body.request_type = ConnectRequestType.TUNNEL_CONNECTION
        exp_knxipframe.normalize()
        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(asyncio.Task(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('Cant 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.warning') 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)
Ejemplo n.º 40
0
    def test_disconnect_response(self):
        """Test parsing and streaming connection state response KNX/IP packet."""
        raw = (0x06, 0x10, 0x02, 0x08, 0x00, 0x08, 0x15, 0x21)
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, ConnectionStateResponse))

        self.assertEqual(knxipframe.body.communication_channel_id, 21)
        self.assertEqual(knxipframe.body.status_code,
                         ErrorCode.E_CONNECTION_ID)

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        knxipframe2.body.communication_channel_id = 21
        knxipframe2.body.status_code = ErrorCode.E_CONNECTION_ID
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 41
0
    def test_tunnelling(self):
        """Test tunnelling from KNX bus."""
        # pylint: disable=too-many-locals
        xknx = XKNX(loop=self.loop)
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        telegram = Telegram(GroupAddress('1/2/3'), payload=DPTArray((0x1, 0x2, 0x3)))
        sequence_counter = 42
        src_address = PhysicalAddress('2.2.2')
        tunnelling = Tunnelling(xknx, udp_client, telegram, src_address, sequence_counter, communication_channel_id)
        tunnelling.timeout_in_seconds = 0

        self.assertEqual(tunnelling.awaited_response_class, TunnellingAck)
        self.assertEqual(tunnelling.communication_channel_id, communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.TUNNELLING_REQUEST)
        exp_knxipframe.body.cemi.telegram = telegram
        exp_knxipframe.body.cemi.src_addr = src_address
        exp_knxipframe.body.communication_channel_id = communication_channel_id
        exp_knxipframe.body.sequence_counter = sequence_counter
        exp_knxipframe.normalize()
        print(exp_knxipframe)
        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(asyncio.Task(tunnelling.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:
            tunnelling.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with('Cant understand knxipframe')

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch('logging.Logger.warning') as mock_warning:
            tunnelling.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(tunnelling).__name__,
                                            type(err_knxipframe.body).__name__, ErrorCode.E_CONNECTION_ID)

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.TUNNELLING_ACK)
        with patch('logging.Logger.debug') as mock_debug:
            tunnelling.response_rec_callback(res_knxipframe, None)
            mock_debug.assert_called_with('Success: received correct answer from KNX bus: %s', ErrorCode.E_NO_ERROR)
            self.assertTrue(tunnelling.success)
Ejemplo n.º 42
0
    def test_connectionstate_route_back_true(self):
        """Test connectionstateing from KNX bus."""
        xknx = XKNX()
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connectionstate = ConnectionState(xknx,
                                          udp_client,
                                          communication_channel_id,
                                          route_back=True)
        connectionstate.timeout_in_seconds = 0

        self.assertEqual(connectionstate.awaited_response_class,
                         ConnectionStateResponse)
        self.assertEqual(connectionstate.communication_channel_id,
                         communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            ConnectionStateRequest(
                xknx,
                communication_channel_id=communication_channel_id,
            ))
        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(connectionstate.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:
            connectionstate.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.CONNECTIONSTATE_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch("logging.Logger.debug") as mock_warning:
            connectionstate.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(connectionstate).__name__,
                type(err_knxipframe.body).__name__,
                ErrorCode.E_CONNECTION_ID,
            )

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        connectionstate.response_rec_callback(res_knxipframe, None)
        self.assertTrue(connectionstate.success)
Ejemplo n.º 43
0
    def test_connect_request(self):
        """Test parsing and streaming tunneling ACK KNX/IP packet."""
        raw = (0x06, 0x10, 0x04, 0x21, 0x00, 0x0A, 0x04, 0x2A, 0x17, 0x00)
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, TunnellingAck))
        self.assertEqual(knxipframe.body.communication_channel_id, 42)
        self.assertEqual(knxipframe.body.sequence_counter, 23)
        self.assertEqual(knxipframe.body.status_code, ErrorCode.E_NO_ERROR)

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.TUNNELLING_ACK)
        knxipframe2.body.communication_channel_id = 42
        knxipframe2.body.sequence_counter = 23
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 44
0
    def test_maximum_apci(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, testing maximum APCI."""
        telegram = Telegram()
        telegram.group_address = GroupAddress(337)
        telegram.payload = DPTBinary(DPTBinary.APCI_MAX_VALUE)
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.init(KNXIPServiceType.ROUTING_INDICATION)
        knxipframe.body.cemi.src_addr = PhysicalAddress("1.3.1")
        knxipframe.body.cemi.telegram = telegram
        knxipframe.body.cemi.set_hops(5)
        knxipframe.normalize()

        raw = ((0x06, 0x10, 0x05, 0x30, 0x00, 0x11, 0x29, 0x00, 0xbc, 0xd0,
                0x13, 0x01, 0x01, 0x51, 0x01, 0x00, 0xbf))
        self.assertEqual(knxipframe.to_knx(), list(raw))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.ROUTING_INDICATION)
        knxipframe2.from_knx(knxipframe.to_knx())
        self.assertEqual(knxipframe2.body.cemi.telegram, telegram)
Ejemplo n.º 45
0
    def test_connectionstate(self):
        """Test connectionstateing from KNX bus."""
        xknx = XKNX(loop=self.loop)
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connectionstate = ConnectionState(xknx, udp_client,
                                          communication_channel_id)
        connectionstate.timeout_in_seconds = 0

        self.assertEqual(connectionstate.awaited_response_class,
                         ConnectionStateResponse)
        self.assertEqual(connectionstate.communication_channel_id,
                         communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        exp_knxipframe.body.communication_channel_id = communication_channel_id
        exp_knxipframe.body.control_endpoint = HPAI(ip_addr='192.168.1.3',
                                                    port=4321)
        exp_knxipframe.normalize()
        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(asyncio.Task(connectionstate.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:
            connectionstate.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with('Cant understand knxipframe')

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch('logging.Logger.warning') as mock_warning:
            connectionstate.response_rec_callback(err_knxipframe, None)
            mock_warning.assert_called_with(
                'Error: reading rading group address from KNX bus failed: %s',
                ErrorCode.E_CONNECTION_ID)

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        with patch('logging.Logger.debug') as mock_debug:
            connectionstate.response_rec_callback(res_knxipframe, None)
            mock_debug.assert_called_with(
                'Success: received correct answer from KNX bus: %s',
                ErrorCode.E_NO_ERROR)
            self.assertTrue(connectionstate.success)
Ejemplo n.º 46
0
 def test_wrong_init(self):
     """Testing init method with wrong service_type_ident."""
     xknx = XKNX(loop=self.loop)
     knxipframe = KNXIPFrame(xknx)
     with self.assertRaises(TypeError):
         knxipframe.init(23)
Ejemplo n.º 47
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()
Ejemplo n.º 48
0
    def test_EndTOEnd_group_write_2bytes(self):
        """Test parsing and streaming CEMIFrame KNX/IP packet, setting value of thermostat."""
        # Incoming Temperature from thermostat
        raw = ((0x06, 0x10, 0x05, 0x30, 0x00, 0x13, 0x29, 0x00, 0xbc, 0xd0,
                0x14, 0x02, 0x08, 0x01, 0x03, 0x00, 0x80, 0x07, 0xc1))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)
        telegram = knxipframe.body.cemi.telegram
        self.assertEqual(
            telegram,
            Telegram(GroupAddress("2049"),
                     payload=DPTArray(DPTTemperature().to_knx(19.85))))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.ROUTING_INDICATION)
        knxipframe2.body.cemi.src_addr = PhysicalAddress("1.4.2")
        knxipframe2.body.cemi.telegram = telegram
        knxipframe2.body.cemi.set_hops(5)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.header.to_knx(), list(raw[0:6]))
        self.assertEqual(knxipframe2.body.to_knx(), list(raw[6:]))
        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 49
0
    def test_connectionstate(self):
        """Test connectionstateing from KNX bus."""
        xknx = XKNX(loop=self.loop)
        communication_channel_id = 23
        udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
        connectionstate = ConnectionState(xknx, udp_client, communication_channel_id)
        connectionstate.timeout_in_seconds = 0

        self.assertEqual(connectionstate.awaited_response_class, ConnectionStateResponse)
        self.assertEqual(connectionstate.communication_channel_id, communication_channel_id)

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame(xknx)
        exp_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        exp_knxipframe.body.communication_channel_id = communication_channel_id
        exp_knxipframe.body.control_endpoint = HPAI(
            ip_addr='192.168.1.3', port=4321)
        exp_knxipframe.normalize()
        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(asyncio.Task(connectionstate.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:
            connectionstate.response_rec_callback(wrong_knxipframe, None)
            mock_warning.assert_called_with('Cant understand knxipframe')

        # Response KNX/IP-Frame with error:
        err_knxipframe = KNXIPFrame(xknx)
        err_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        err_knxipframe.body.status_code = ErrorCode.E_CONNECTION_ID
        with patch('logging.Logger.warning') as mock_warning:
            connectionstate.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(connectionstate).__name__,
                                            type(err_knxipframe.body).__name__, ErrorCode.E_CONNECTION_ID)

        # Correct Response KNX/IP-Frame:
        res_knxipframe = KNXIPFrame(xknx)
        res_knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_RESPONSE)
        with patch('logging.Logger.debug') as mock_debug:
            connectionstate.response_rec_callback(res_knxipframe, None)
            mock_debug.assert_called_with('Success: received correct answer from KNX bus: %s', ErrorCode.E_NO_ERROR)
            self.assertTrue(connectionstate.success)
Ejemplo n.º 50
0
    def test_connect_request(self):
        """Test parsing and streaming connection tunneling request KNX/IP packet."""
        raw = ((0x06, 0x10, 0x04, 0x20, 0x00, 0x15, 0x04, 0x01,
                0x17, 0x00, 0x11, 0x00, 0xbc, 0xe0, 0x00, 0x00,
                0x48, 0x08, 0x01, 0x00, 0x81))
        xknx = XKNX(loop=self.loop)
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, TunnellingRequest))
        self.assertEqual(knxipframe.body.communication_channel_id, 1)
        self.assertEqual(knxipframe.body.sequence_counter, 23)
        self.assertTrue(isinstance(knxipframe.body.cemi, CEMIFrame))

        self.assertEqual(knxipframe.body.cemi.telegram,
                         Telegram(GroupAddress('9/0/8'), payload=DPTBinary(1)))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.TUNNELLING_REQUEST)
        knxipframe2.body.cemi.telegram = Telegram(
            GroupAddress('9/0/8'), payload=DPTBinary(1))
        knxipframe2.body.sequence_counter = 23
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 51
0
    def test_connection_state_request(self):
        """Test parsing and streaming connection state request KNX/IP packet."""
        raw = (
            0x06,
            0x10,
            0x02,
            0x07,
            0x00,
            0x10,
            0x15,
            0x00,
            0x08,
            0x01,
            0xC0,
            0xA8,
            0xC8,
            0x0C,
            0xC3,
            0xB4,
        )
        xknx = XKNX()
        knxipframe = KNXIPFrame(xknx)
        knxipframe.from_knx(raw)

        self.assertTrue(isinstance(knxipframe.body, ConnectionStateRequest))

        self.assertEqual(knxipframe.body.communication_channel_id, 21)
        self.assertEqual(knxipframe.body.control_endpoint,
                         HPAI(ip_addr="192.168.200.12", port=50100))

        knxipframe2 = KNXIPFrame(xknx)
        knxipframe2.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST)
        knxipframe2.body.communication_channel_id = 21
        knxipframe2.body.control_endpoint = HPAI(ip_addr="192.168.200.12",
                                                 port=50100)
        knxipframe2.normalize()

        self.assertEqual(knxipframe2.to_knx(), list(raw))
Ejemplo n.º 52
0
    async def test_connect_route_back_true(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=True)
        connect.timeout_in_seconds = 0

        assert connect.awaited_response_class == ConnectResponse

        # Expected KNX/IP-Frame:
        exp_knxipframe = KNXIPFrame.init_from_body(
            ConnectRequest(xknx,
                           request_type=ConnectRequestType.TUNNEL_CONNECTION))
        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)
            await 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)
        assert connect.success
        assert connect.communication_channel == 23
        assert connect.identifier == 7