def test_hpai(self): """Test parsing and streaming HPAI KNX/IP fragment.""" raw = ((0x08, 0x01, 0xc0, 0xa8, 0x2a, 0x01, 0x84, 0x95)) hpai = HPAI() self.assertEqual(hpai.from_knx(raw), 8) self.assertEqual(hpai.ip_addr, '192.168.42.1') self.assertEqual(hpai.port, 33941) hpai2 = HPAI(ip_addr='192.168.42.1', port=33941) self.assertEqual(hpai2.to_knx(), list(raw))
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" />')
def create_knxipframe(self): """Create KNX/IP Frame object to be sent to device.""" (local_addr, local_port) = self.udp_client.getsockname() knxipframe = KNXIPFrame(self.xknx) knxipframe.init(KNXIPServiceType.CONNECT_REQUEST) knxipframe.body.request_type = ConnectRequestType.TUNNEL_CONNECTION # set control_endpoint and data_endpoint to the same udp_connection knxipframe.body.control_endpoint = HPAI(ip_addr=local_addr, port=local_port) knxipframe.body.data_endpoint = HPAI(ip_addr=local_addr, port=local_port) return knxipframe
def create_knxipframe(self) -> KNXIPFrame: """Create KNX/IP Frame object to be sent to device.""" if self.route_back: endpoint = HPAI() else: (local_addr, local_port) = self.udpclient.getsockname() endpoint = HPAI(ip_addr=local_addr, port=local_port) connectionstate_request = ConnectionStateRequest( self.xknx, communication_channel_id=self.communication_channel_id, control_endpoint=endpoint, ) return KNXIPFrame.init_from_body(connectionstate_request)
def test_connect_request(self): """Test string representation of KNX/IP ConnectRequest.""" connect_request = ConnectRequest() 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="192.168.42.1:33941/udp" data_endpoint="192.168.42.2:33942/udp" ' 'request_type="ConnectRequestType.TUNNEL_CONNECTION" flags="0x2" />' )
def test_hpai(self): """Test string representation of HPAI.""" hpai_udp = HPAI(ip_addr="192.168.42.1", port=33941) assert str(hpai_udp) == "192.168.42.1:33941/udp" assert repr( hpai_udp) == "HPAI('192.168.42.1', 33941, HostProtocol.IPV4_UDP)" hpai_tcp = HPAI(ip_addr="10.1.4.1", port=3671, protocol=HostProtocol.IPV4_TCP) assert str(hpai_tcp) == "10.1.4.1:3671/tcp" assert repr( hpai_tcp) == "HPAI('10.1.4.1', 3671, HostProtocol.IPV4_TCP)"
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(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)
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) 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( 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) assert knxipframe2.to_knx() == list(raw)
def test_description_request(self): """Test parsing and streaming DescriptionRequest KNX/IP packet.""" raw = bytes.fromhex("06 10 02 03 00 0E 08 01 7F 00 00 02 0E 57") knxipframe = KNXIPFrame() knxipframe.from_knx(raw) assert isinstance(knxipframe.body, DescriptionRequest) assert knxipframe.body.control_endpoint == HPAI(ip_addr="127.0.0.2", port=3671) knxipframe2 = KNXIPFrame.init_from_body( DescriptionRequest( control_endpoint=HPAI(ip_addr="127.0.0.2", port=3671))) assert knxipframe2.to_knx() == raw
def create_knxipframe(self) -> KNXIPFrame: """Create KNX/IP Frame object to be sent to device.""" # set control_endpoint and data_endpoint to the same udp_connection if self.route_back: endpoint = HPAI() else: (local_addr, local_port) = self.udp_client.getsockname() 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)
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))
async def test_invalid_session_response( self, mock_super_connect, mock_super_send, _mock_generate, time_travel, ): """Test handling invalid session response.""" connect_task = asyncio.create_task(self.session.connect()) await time_travel(0) session_response_frame = KNXIPFrame.init_from_body( SessionResponse( secure_session_id=1, ecdh_server_public_key=self.mock_server_public_key, message_authentication_code=bytes.fromhex( "ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff" ), ) ) with pytest.raises(CommunicationError): self.session.handle_knxipframe( session_response_frame, HPAI(*self.mock_addr) ) await connect_task # only SessionRequest, no SessionAuthenticate mock_super_send.assert_called_once()
def test_connect_response_connection_error_gira(self): """ Test parsing and streaming connection response KNX/IP packet with error e_no_more_connections. HPAI and CRD normal. This was received from Gira devices (2020). """ raw = bytes.fromhex( "06 10 02 06 00 14 C0 24 08 01 0A 01 00 29 0E 57 04 04 00 00" ) knxipframe = KNXIPFrame() knxipframe.from_knx(raw) assert isinstance(knxipframe.body, ConnectResponse) assert knxipframe.body.status_code == ErrorCode.E_NO_MORE_CONNECTIONS assert knxipframe.body.communication_channel == 192 connect_response = ConnectResponse( communication_channel=192, status_code=ErrorCode.E_NO_MORE_CONNECTIONS, request_type=ConnectRequestType.TUNNEL_CONNECTION, data_endpoint=HPAI(ip_addr="10.1.0.41", port=3671), identifier=0, ) knxipframe2 = KNXIPFrame.init_from_body(connect_response) assert knxipframe2.to_knx() == raw
async def _search_interface(self, interface: str, ip_addr: str) -> None: """Send a search request on a specific interface.""" logger.debug("Searching on %s / %s", interface, ip_addr) udp_client = UDPClient( self.xknx, (ip_addr, 0), (self.xknx.multicast_group, self.xknx.multicast_port), multicast=True, ) udp_client.register_callback( partial(self._response_rec_callback, interface=interface), [KNXIPServiceType.SEARCH_RESPONSE], ) await udp_client.connect() self._udp_clients.append(udp_client) (local_addr, local_port) = udp_client.getsockname() discovery_endpoint = HPAI(ip_addr=local_addr, port=local_port) search_request = SearchRequest(self.xknx, discovery_endpoint=discovery_endpoint) udp_client.send(KNXIPFrame.init_from_body(search_request))
def test_session_request(self): """Test parsing and streaming session request KNX/IP packet.""" public_key = bytes.fromhex( "0a a2 27 b4 fd 7a 32 31" # Diffie-Hellman Client Public Value X "9b a9 96 0a c0 36 ce 0e" "5c 45 07 b5 ae 55 16 1f" "10 78 b1 dc fb 3c b6 31" ) raw = ( bytes.fromhex( "06 10 09 51 00 2e" # KNXnet/IP header "08 02 00 00 00 00 00 00" # HPAI TCPv4 ) + public_key ) knxipframe = KNXIPFrame() knxipframe.from_knx(raw) assert isinstance(knxipframe.body, SessionRequest) assert knxipframe.body.control_endpoint == HPAI(protocol=HostProtocol.IPV4_TCP) assert knxipframe.body.ecdh_client_public_key == public_key assert knxipframe.to_knx() == raw session_request = SessionRequest(ecdh_client_public_key=public_key) knxipframe2 = KNXIPFrame.init_from_body(session_request) assert knxipframe2.to_knx() == raw
async def test_send_search_requests( self, udp_transport_send_mock, udp_transport_connect_mock, ): """Test if both search requests are sent per interface.""" xknx = XKNX() gateway_scanner = GatewayScanner(xknx, timeout_in_seconds=0) with patch( "xknx.io.util.get_default_local_ip", return_value="10.1.1.2", ), patch( "xknx.io.util.get_local_interface_name", return_value="en_0123", ), patch( "xknx.io.gateway_scanner.UDPTransport.getsockname", return_value=("10.1.1.2", 56789), ): await gateway_scanner.scan() assert udp_transport_connect_mock.call_count == 1 assert udp_transport_send_mock.call_count == 2 frame_1 = udp_transport_send_mock.call_args_list[0].args[0] frame_2 = udp_transport_send_mock.call_args_list[1].args[0] assert isinstance(frame_1.body, SearchRequestExtended) assert isinstance(frame_2.body, SearchRequest) assert frame_1.body.discovery_endpoint == HPAI(ip_addr="10.1.1.2", port=56789)
def test_search_request(self): """Test parsing and streaming SearchRequest KNX/IP packet.""" raw = bytes.fromhex("06 10 02 01 00 0E 08 01 E0 00 17 0C 0E 57") knxipframe = KNXIPFrame() knxipframe.from_knx(raw) assert isinstance(knxipframe.body, SearchRequest) assert knxipframe.body.discovery_endpoint == HPAI( ip_addr="224.0.23.12", port=3671 ) knxipframe2 = KNXIPFrame.init_from_body( SearchRequest(discovery_endpoint=HPAI(ip_addr="224.0.23.12", port=3671)) ) assert knxipframe2.to_knx() == raw
def fake_router_search_response(xknx: XKNX) -> KNXIPFrame: """Return the KNXIPFrame of a KNX/IP Router with a SearchResponse body.""" 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 = IndividualAddress("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) return KNXIPFrame.init_from_body(frame_body)
def __init__( self, xknx: XKNX, telegram_received_callback: TelegramCallbackType | None = None, auto_reconnect: bool = True, auto_reconnect_wait: int = 3, ): """Initialize Tunnel class.""" self.xknx = xknx self.auto_reconnect = auto_reconnect self.auto_reconnect_wait = auto_reconnect_wait self.communication_channel: int | None = None self.local_hpai: HPAI = HPAI() self.sequence_number = 0 self.telegram_received_callback = telegram_received_callback self._data_endpoint_addr: tuple[str, int] | None = None self._heartbeat_task: asyncio.Task[None] | None = None self._initial_connection = True self._is_reconnecting = False self._reconnect_task: asyncio.Task[None] | None = None self._src_address = xknx.own_address self._tunnelling_request_confirmation_event = asyncio.Event() self._init_transport() self.transport.register_callback( self._request_received, [ KNXIPServiceType.TUNNELLING_REQUEST, KNXIPServiceType.DISCONNECT_REQUEST ], )
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() knxipframe = KNXIPFrame(xknx) knxipframe.from_knx(raw) assert isinstance(knxipframe.body, ConnectResponse) assert knxipframe.body.communication_channel == 1 assert knxipframe.body.status_code == ErrorCode.E_NO_ERROR assert knxipframe.body.control_endpoint == HPAI( ip_addr="192.168.42.10", port=3671) assert knxipframe.body.request_type == ConnectRequestType.TUNNEL_CONNECTION assert knxipframe.body.identifier == 4607 connect_response = ConnectResponse( xknx, communication_channel=1, status_code=ErrorCode.E_NO_ERROR, request_type=ConnectRequestType.TUNNEL_CONNECTION, control_endpoint=HPAI(ip_addr="192.168.42.10", port=3671), identifier=4607, ) knxipframe2 = KNXIPFrame.init_from_body(connect_response) assert knxipframe2.to_knx() == list(raw)
def test_disconnect_request(self): """Test string representation of KNX/IP DisconnectRequest.""" xknx = XKNX(loop=self.loop) disconnect_request = DisconnectRequest(xknx) disconnect_request.communication_channel_id = 13 disconnect_request.control_endpoint = HPAI(ip_addr='192.168.42.1', port=33941) self.assertEqual( str(disconnect_request), '<DisconnectRequest CommunicationChannelID="13" control_endpoint="<HPAI 192.168.42.1:33941 />" />')
def test_connectionstate_request(self): """Test string representation of KNX/IP ConnectionStateRequest.""" xknx = XKNX(loop=self.loop) connectionstate_request = ConnectionStateRequest(xknx) connectionstate_request.communication_channel_id = 23 connectionstate_request.control_endpoint = HPAI(ip_addr='192.168.42.1', port=33941) self.assertEqual( str(connectionstate_request), '<ConnectionStateRequest CommunicationChannelID="23", control_endpoint="<HPAI 192.168.42.1:33941 />" />')
def create_knxipframe(self) -> KNXIPFrame: """Create KNX/IP Frame object to be sent to device.""" (local_addr, local_port) = self.udpclient.getsockname() disconnect_request = DisconnectRequest( self.xknx, communication_channel_id=self.communication_channel_id, control_endpoint=HPAI(ip_addr=local_addr, port=local_port), ) return KNXIPFrame.init_from_body(disconnect_request)
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
def test_disconnect_request(self): """Test string representation of KNX/IP DisconnectRequest.""" disconnect_request = DisconnectRequest() disconnect_request.communication_channel_id = 13 disconnect_request.control_endpoint = HPAI(ip_addr="192.168.42.1", port=33941) assert ( str(disconnect_request) == '<DisconnectRequest communication_channel_id="13" control_endpoint="192.168.42.1:33941/udp" />' )
def test_connectionstate_request(self): """Test string representation of KNX/IP ConnectionStateRequest.""" connectionstate_request = ConnectionStateRequest() connectionstate_request.communication_channel_id = 23 connectionstate_request.control_endpoint = HPAI(ip_addr="192.168.42.1", port=33941) assert ( str(connectionstate_request) == '<ConnectionStateRequest communication_channel_id="23", control_endpoint="192.168.42.1:33941/udp" />' )
def test_connect_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))
def test_connection_state_request(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 B4") knxipframe = KNXIPFrame() knxipframe.from_knx(raw) assert isinstance(knxipframe.body, ConnectionStateRequest) assert knxipframe.body.communication_channel_id == 21 assert knxipframe.body.control_endpoint == HPAI( ip_addr="192.168.200.12", port=50100) connectionstate_request = ConnectionStateRequest( communication_channel_id=21, control_endpoint=HPAI(ip_addr="192.168.200.12", port=50100), ) knxipframe2 = KNXIPFrame.init_from_body(connectionstate_request) assert knxipframe2.to_knx() == raw
def create_knxipframe(self): (local_addr, local_port) = self.udpclient.getsockname() knxipframe = KNXIPFrame() knxipframe.init(KNXIPServiceType.CONNECTIONSTATE_REQUEST) knxipframe.body.communication_channel_id = \ self.communication_channel_id knxipframe.body.control_endpoint = HPAI( ip_addr=local_addr, port=local_port) return knxipframe
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))
def test_to_knx_wrong_ip(self): """Test serializing HPAI to KNV/IP with wrong ip type.""" hpai = HPAI(ip_addr=127001) with self.assertRaises(ConversionError): hpai.to_knx()