Repository: XKNX/xknx

Issue:
Handle different Tunneling data and control endpoints correctly
KNX tunneling servers can have different data and control endpoints (eg. Calimero does).
`DisconnectRequest`s should be sent to the other device’s control endpoint instead of to the data endpoint. (see KNX specification 03_08_04 Tunneling §2.6 Frame confirmation)

I have not found an other usecase for the control endpoint for us yet.

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/XKNX/xknx/pull/832?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) Report
> Merging [#832](https://codecov.io/gh/XKNX/xknx/pull/832?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) (cdc64e8) into [main](https://codecov.io/gh/XKNX/xknx/commit/22ff74ac04fc1d4ac0310293cde2bd4ccd74fb7c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) (22ff74a) will **decrease** coverage by `0.06%`.
> The diff coverage is `66.66%`.

[![Impacted file tree graph](https://codecov.io/gh/XKNX/xknx/pull/832/graphs/tree.svg?width=650&height=150&src=pr&token=irWbIygS84&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX)](https://codecov.io/gh/XKNX/xknx/pull/832?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX)

```diff
@@            Coverage Diff             @@
##             main     #832      +/-   ##
==========================================
- Coverage   95.28%   95.21%   -0.07%     
==========================================
  Files         109      109              
  Lines        6764     6774      +10     
==========================================
+ Hits         6445     6450       +5     
- Misses        319      324       +5     
```


| [Impacted Files](https://codecov.io/gh/XKNX/xknx/pull/832?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) | Coverage Δ | |
|---|---|---|
| [xknx/io/udp\_client.py](https://codecov.io/gh/XKNX/xknx/pull/832/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby91ZHBfY2xpZW50LnB5) | `57.00% <25.00%> (-1.09%)` | :arrow_down: |
| [xknx/io/tunnel.py](https://codecov.io/gh/XKNX/xknx/pull/832/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby90dW5uZWwucHk=) | `48.86% <40.00%> (-0.56%)` | :arrow_down: |
| [xknx/io/request\_response/connect.py](https://codecov.io/gh/XKNX/xknx/pull/832/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby9yZXF1ZXN0X3Jlc3BvbnNlL2Nvbm5lY3QucHk=) | `100.00% <100.00%> (ø)` | |
| [xknx/io/request\_response/tunnelling.py](https://codecov.io/gh/XKNX/xknx/pull/832/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby9yZXF1ZXN0X3Jlc3BvbnNlL3R1bm5lbGxpbmcucHk=) | `100.00% <100.00%> (ø)` | |
| [xknx/knxip/connect\_response.py](https://codecov.io/gh/XKNX/xknx/pull/832/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9rbnhpcC9jb25uZWN0X3Jlc3BvbnNlLnB5) | `100.00% <100.00%> (ø)` | |

aschamberger: Cool. I would have tested it if I knew how to do it with Home Assisstant Docker on HA OS. 
I hope you merge it soon into the next regular version.
farmio: You can test it outside of HAOS. Just set up a test installation with HA container and mount a local directory into it via a volume - overwriting the default (pip installed) xknx (you'll just need to figure out the path). 
Or you mount it in a new path and set `PYTHONOATH` there when starting the container. See https://xknx.io/home_assistant.html

Or just do it without Docker - that's even easier. 

I'd prefer it to be tested not only on my own system before merging. 
marvin-w: I tested this PR locally with my HA installation. Everything is working as expected. However, my KNX IP device does have the same data and control endpoint (as mentioned in the other issue).

So I went a step further and cloned calimero-server, I checked out `v2.5` and ran `./gradlew run --args server-config.xml`.

My `server-config.xml` looks like this:

```
<?xml version="1.0" encoding="UTF-8"?>
<knxServer name="knx-server" friendlyName="Calimero KNX IP Server">
	<!-- KNXnet/IP search & discovery -->
	<discovery listenNetIf="all" outgoingNetIf="all" activate="false" />

	<!-- Provides the KNXnet/IP-side configuration for access to one KNX subnet -->
	<serviceContainer activate="true" routing="false" networkMonitoring="false"
		udpPort="3671" listenNetIf="any">
		<knxAddress type="individual">1.0.1</knxAddress>
		<knxSubnet type="ip">192.168.1.100:3671</knxSubnet>
		<groupAddressFilter>
		</groupAddressFilter>

		<!-- Additional KNX individual addresses assigned to client KNXnet/IP connections (optional) -->
		<additionalAddresses>
			<knxAddress type="individual">1.0.2</knxAddress>
			<knxAddress type="individual">1.0.3</knxAddress>
			<knxAddress type="individual">1.0.4</knxAddress>
			<knxAddress type="individual">1.0.5</knxAddress>
		</additionalAddresses>
	</serviceContainer>

	<!-- Add next service container (optional) -->
</knxServer>
```

When starting I'm presented with the following logs:

```
[main] INFO calimero.server.knx-server - Calimero KNX IP Server v2.5
[main] INFO calimero.server.knx-server - knx-server 'Calimero KNX IP Server' - 1 service container, discovery disabled
[main] INFO calimero.server.knx-server - 192.168.1.100:3671:
        listen on any (port 3671), KNX IP routing disabled
        ip 192.168.1.100:3671 connection: TP1 medium, device 1.1.0
type 'stop' to stop the gateway and shutdown the server
[knx-server] INFO calimero.knxnetip.KNXnet/IP Tunneling 192.168.1.100:3671 - connection established (data endpoint 192.168.1.100:3671, channel 105, tunneling address 1.0.3)
[knx-server] INFO calimero.knxnetip.KNXnet/IP DevMgmt 192.168.1.100:3671 - connection established (data endpoint 192.168.1.100:3671, channel 1)
[knx-server control endpoint 192.168.1.100:3671] INFO calimero.server.knx-server - 192.168.1.100:3671 secure mgmt/tunneling connections: optional/optional
[knx-server 192.168.1.100:3671 tcp service] INFO calimero.server.knx-server - knx-server 192.168.1.100:3671 tcp service (enp7s0 192.168.1.149:3671) is up and running
[knx-server control endpoint 192.168.1.100:3671] INFO calimero.server.knx-server - knx-server 192.168.1.100:3671 control endpoint (enp7s0 192.168.1.149:3671) is up and running
```

I went over to my HA instance that I started with this PR (by setting `PYTHONPATH` properly) and changed the tunneling address to `192.168.1.149` which is my local IP. The following errors/warnings arise in xknx:

```
2022-01-06 01:06:26 WARNING (MainThread) [xknx.log] L_DATA_CON Data Link Layer confirmation timed out for <Telegram direction="Outgoing" source_address="1.0.3" destination_address="6/0/0" payload="<GroupValueRead />" />
2022-01-06 01:06:29 WARNING (MainThread) [xknx.log] L_DATA_CON Data Link Layer confirmation timed out for <Telegram direction="Outgoing" source_address="1.0.3" destination_address="2/0/33" payload="<GroupValueRead />" />
2022-01-06 01:06:30 WARNING (MainThread) [xknx.log] Received DisconnectRequest from tunnelling sever.
2022-01-06 01:06:32 WARNING (MainThread) [xknx.log] L_DATA_CON Data Link Layer confirmation timed out for <Telegram direction="Outgoing" source_address="1.0.3" destination_address="2/0/32" payload="<GroupValueWrite value="<DPTBinary value="1" />" />" />
```

Calimero reports:

```
[knx-server subnet dispatcher] WARN calimero.server.gateway.knx-server - timeout sending to 3/1/3: no confirmation reply received for 1.0.2->3/1/3 L_Data.req, low priority hop count 5 repeat, tpdu 00 00
[knx-server subnet dispatcher] WARN calimero.knxnetip.KNXnet/IP Tunneling 192.168.1.100:3671 - response timeout waiting for confirmation
tuwien.auto.calimero.KNXTimeoutException: no confirmation reply received for 1.0.2->3/1/0 L_Data.req, low priority hop count 5 repeat, tpdu 00 00
        at tuwien.auto.calimero.knxnetip.ClientConnection.doExtraBlockingModes(ClientConnection.java:269)
        at tuwien.auto.calimero.knxnetip.ConnectionBase.send(ConnectionBase.java:261)
        at tuwien.auto.calimero.knxnetip.KNXnetIPTunnel.send(KNXnetIPTunnel.java:213)
        at tuwien.auto.calimero.link.KNXNetworkLinkIP.onSend(KNXNetworkLinkIP.java:423)
        at tuwien.auto.calimero.link.AbstractLink.send(AbstractLink.java:324)
        at tuwien.auto.calimero.link.Connector$Link.send(Connector.java:320)
        at tuwien.auto.calimero.server.gateway.KnxServerGateway.send(KnxServerGateway.java:1888)
        at tuwien.auto.calimero.server.gateway.KnxServerGateway.dispatchToSubnet(KnxServerGateway.java:1521)
        at tuwien.auto.calimero.server.gateway.KnxServerGateway.dispatchToOtherSubnets(KnxServerGateway.java:1476)
        at tuwien.auto.calimero.server.gateway.KnxServerGateway.dispatchToSubnets(KnxServerGateway.java:1485)
        at tuwien.auto.calimero.server.gateway.KnxServerGateway.onClientFrameReceived(KnxServerGateway.java:1258)
        at tuwien.auto.calimero.server.gateway.KnxServerGateway$1.run(KnxServerGateway.java:610)
```

Wireshark Dump:
[test-calimero-tunnel-control.zip](https://github.com/XKNX/xknx/files/7818496/test-calimero-tunnel-control.zip)

Maybe I've missed something, if so, please point me to the right direction then I can do a follow up test. What I'm confused about is that I see a ConnectReq and a ConnectResp between Calimero and my IP device but I do not see one from XKNX to Calimero (maybe because they are running on the same host?)

cc @aschamberger @farmio 
marvin-w: I ran another test with a Macbook in between:

Setup: My PC with xknx, MAC with calimero and, well, the KNX IP device.

This time I used this test script:

```
"""Example for Switch device."""
import asyncio
import logging

from xknx import XKNX
from xknx.devices import Switch
from xknx.io import ConnectionConfig, ConnectionType

logging.basicConfig(level=logging.DEBUG)

async def main():
    """Connect to KNX/IP device, switch on outlet, wait 2 seconds and switch of off again."""
    connection_config = ConnectionConfig(
        connection_type=ConnectionType.TUNNELING,
        gateway_ip="192.168.1.61", # ip of my mac where calimero is running
        # local_ip="10.1.0.123",
        # route_back=True,
    )
    xknx = XKNX(connection_config=connection_config)
    await xknx.start()
    switch = Switch(xknx, name="TestOutlet", group_address="1/0/34")
    await switch.set_off()
    await asyncio.sleep(3)
    await switch.set_on()
    await asyncio.sleep(3)
    await xknx.stop()


asyncio.run(main())
```

XKNX logs:

```
DEBUG:asyncio:Using selector: EpollSelector
INFO:xknx.log:XKNX v0.18.16-SNAPSHOT starting tunneling connection to KNX bus.
DEBUG:xknx.log:Could not find IPv4 address on interface enp6s0
DEBUG:xknx.log:Using interface: enp7s0
DEBUG:xknx.log:Starting tunnel from 192.168.1.149:0 to 192.168.1.61:3671
DEBUG:xknx.knx:Sending to 192.168.1.61:3671 at 1641429506.3543806:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="CONNECT_REQUEST" Reserve="0" TotalLength="26" />
 body="<ConnectRequest control_endpoint="192.168.1.149:57015" data_endpoint="192.168.1.149:57015" request_type="ConnectRequestType.TUNNEL_CONNECTION" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 3671): 06100206001404000801c0a8013dd12704041002
DEBUG:xknx.knx:Received from 192.168.1.61:3671 at 1641429506.4589117:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="CONNECT_RESPONSE" Reserve="0" TotalLength="20" />
 body="<ConnectResponse communication_channel="4" status_code="ErrorCode.E_NO_ERROR" data_endpoint="192.168.1.61:53543" request_type="ConnectRequestType.TUNNEL_CONNECTION" identifier="4098" />" />
DEBUG:xknx.log:Tunnel established communication_channel=4, id=4098
DEBUG:xknx.telegram:<Telegram direction="Outgoing" source_address="1.0.2" destination_address="1/0/34" payload="<GroupValueWrite value="<DPTBinary value="False" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429506.4593143:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="0" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.0.2")" DestinationAddress="GroupAddress("1/0/34")" Flags="1011110011100000" code="L_DATA_REQ" payload="<GroupValueWrite value="<DPTBinary value="False" />" />" />" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 06100421000a04040000
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429506.462712:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="0" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 061004200015040400002e00bce010020822010080
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429506.4632547:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="0" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.0.2")" DestinationAddress="GroupAddress("1/0/34")" Flags="1011110011100000" code="L_DATA_CON" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429506.463299:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="0" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 061004200015040401002900bcc010020822010080
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429506.4918895:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="1" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.0.2")" DestinationAddress="GroupAddress("1/0/34")" Flags="1011110011000000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429506.4919612:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="1" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.telegram:<Telegram direction="Incoming" source_address="1.0.2" destination_address="1/0/34" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 061004200015040402002900bcc011650830010080
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429506.5738747:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="2" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.101")" DestinationAddress="GroupAddress("1/0/48")" Flags="1011110011000000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429506.5739453:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="2" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.telegram:<Telegram direction="Incoming" source_address="1.1.101" destination_address="1/0/48" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />
DEBUG:xknx.telegram:<Telegram direction="Outgoing" source_address="1.0.2" destination_address="1/0/34" payload="<GroupValueWrite value="<DPTBinary value="True" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429509.4633853:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="1" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.0.2")" DestinationAddress="GroupAddress("1/0/34")" Flags="1011110011100000" code="L_DATA_REQ" payload="<GroupValueWrite value="<DPTBinary value="True" />" />" />" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 06100421000a04040100
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429509.4938684:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="1" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 061004200015040403002e00bce010020822010081
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429509.4944665:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="3" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.0.2")" DestinationAddress="GroupAddress("1/0/34")" Flags="1011110011100000" code="L_DATA_CON" payload="<GroupValueWrite value="<DPTBinary value="1" />" />" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429509.494542:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="3" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 061004200015040404002900bcc010020822010081
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429509.524881:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="4" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.0.2")" DestinationAddress="GroupAddress("1/0/34")" Flags="1011110011000000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTBinary value="1" />" />" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429509.5249536:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="4" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.telegram:<Telegram direction="Incoming" source_address="1.0.2" destination_address="1/0/34" payload="<GroupValueWrite value="<DPTBinary value="1" />" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 53543): 061004200015040405002900bcc011650830010081
DEBUG:xknx.knx:Received from 192.168.1.61:53543 at 1641429509.603084:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
 body="<TunnellingRequest communication_channel_id="4" sequence_counter="5" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.101")" DestinationAddress="GroupAddress("1/0/48")" Flags="1011110011000000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTBinary value="1" />" />" />" />" />
DEBUG:xknx.knx:Sending to 192.168.1.61:53543 at 1641429509.6031559:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
 body="<TunnellingAck communication_channel_id="4" sequence_counter="5" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.telegram:<Telegram direction="Incoming" source_address="1.1.101" destination_address="1/0/48" payload="<GroupValueWrite value="<DPTBinary value="1" />" />" />
DEBUG:xknx.state_updater:StateUpdater stopping
DEBUG:xknx.log:Stopping TelegramQueue
DEBUG:xknx.knx:Sending to 192.168.1.61:3671 at 1641429512.4666567:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="DISCONNECT_REQUEST" Reserve="0" TotalLength="16" />
 body="<DisconnectRequest CommunicationChannelID="4" control_endpoint="192.168.1.149:57015" />" />
DEBUG:xknx.raw_socket:Received from ('192.168.1.61', 3671): 0610020a00080400
DEBUG:xknx.knx:Received from 192.168.1.61:3671 at 1641429512.498731:
 <KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="DISCONNECT_RESPONSE" Reserve="0" TotalLength="8" />
 body="<DisconnectResponse CommunicationChannelID="4" status_code="ErrorCode.E_NO_ERROR" />" />
DEBUG:xknx.log:Tunnel disconnected (communication_channel: 4)
DEBUG:xknx.log:Closing transport.

Process finished with exit code 0
```

The light turned off and on again, so I assume it is "working". There is no warning in the log this time as well. Calimero however still reports "no confirmation reply received for 1.0.2->1/0/24 L_Data.req".

I took another wireshark capture on my mac (so we have both the traffic from calimero to the knx interface and the traffic from my PC to calimero).

farmio: > tuwien.auto.calimero.KNXTimeoutException: no confirmation reply received for 1.0.2->3/1/0 L_Data.req, low priority hop count 5 repeat, tpdu 00 00

This seems to indicate that the confirmation of the Weinzierl is not received by Calimero, isn't it? The wireshark dump would indicate the same.
aschamberger: I just tried. Took me some time to get there...

I had to copy and not symlink for Docker (@see: https://github.com/home-assistant/core/issues/57447):
`cp -r ~/xknx/home-assistant-plugin/custom_components/xknx ~/.homeassistant/custom_components/xknx`

My Docker Setup:
```
docker run -d \
  --name homeassistant \
  --privileged \
  --restart=unless-stopped \
  -e TZ=Europe/Berlin \
  -e PYTHONPATH=/xknx \
  -v /root/xknx:/xknx \
  -v /root/.homeassistant:/config \
  --network=host \
  ghcr.io/home-assistant/home-assistant:stable
docker exec -it homeassistant /bin/sh
rm -R /usr/local/lib/python3.9/site-packages/xknx*
```

Config:
```
xknx:
  tunneling:
    host: '192.168.178.72'
  binary_sensor:
    - name: "Haustür offen"
      state_address: "4/2/1"
      sync_state: "expire 10"
      device_class: "door"
      invert: true
```

HA restart from GUI and here is my log:
```
2022-01-06 13:33:47 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration xknx which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-01-06 13:33:51 INFO (MainThread) [xknx.log] XKNX v0.18.15 starting tunneling connection to KNX bus.
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.log] Could not find IPv4 address on interface dummy0
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.log] Could not find IPv4 address on interface sit0
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.log] Could not find IPv4 address on interface ip6tnl0
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.log] Using interface: eth0
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.log] Starting tunnel from 192.168.178.66:0 to 192.168.178.72:3671
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:3671 at 1641472431.4538724:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="CONNECT_REQUEST" Reserve="0" TotalLength="26" />
body="<ConnectRequest control_endpoint="192.168.178.66:52564" data_endpoint="192.168.178.66:52564" request_type="ConnectRequestType.TUNNEL_CONNECTION" />" />
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:3671 at 1641472431.489996:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="CONNECT_RESPONSE" Reserve="0" TotalLength="20" />
body="<ConnectResponse communication_channel="51" status_code="ErrorCode.E_NO_ERROR" data_endpoint="192.168.178.72:58937" request_type="ConnectRequestType.TUNNEL_CONNECTION" identifier="4453" />" />
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.log] Tunnel established communication_channel=51, id=4453
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Outgoing" source_address="1.1.101" destination_address="4/2/1" payload="<GroupValueRead />" />
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:58937 at 1641472431.8847308:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="51" sequence_counter="0" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.101")" DestinationAddress="GroupAddress("4/2/1")" Flags="1011110011100000" code="L_DATA_REQ" payload="<GroupValueRead />" />" />" />
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472431.8965337:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="51" sequence_counter="0" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472431.9075391:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="51" sequence_counter="0" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.101")" DestinationAddress="GroupAddress("4/2/1")" Flags="1011110011100000" code="L_DATA_CON" payload="<GroupValueRead />" />" />" />
2022-01-06 13:33:51 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:58937 at 1641472431.907956:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="51" sequence_counter="0" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:52 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472432.0992532:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="51" sequence_counter="1" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.81")" DestinationAddress="GroupAddress("4/2/1")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueResponse value="<DPTBinary value="0" />" />" />" />" />
2022-01-06 13:33:52 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:58937 at 1641472432.0996938:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="51" sequence_counter="1" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:52 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.81" destination_address="4/2/1" payload="<GroupValueResponse value="<DPTBinary value="0" />" />" />
2022-01-06 13:33:52 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472432.1126468:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="51" sequence_counter="2" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/4/10")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0xf]" />" />" />" />" />
2022-01-06 13:33:52 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:58937 at 1641472432.1130593:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="51" sequence_counter="2" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:52 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/4/10" payload="<GroupValueWrite value="<DPTArray value="[0xf]" />" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472435.846551:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="51" sequence_counter="3" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.65")" DestinationAddress="GroupAddress("7/4/0")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xe2]" />" />" />" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:58937 at 1641472435.847172:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="51" sequence_counter="3" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.65" destination_address="7/4/0" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xe2]" />" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472435.8626873:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="51" sequence_counter="3" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.65")" DestinationAddress="GroupAddress("7/4/0")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xe2]" />" />" />" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:58937 at 1641472435.863273:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="51" sequence_counter="3" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.65" destination_address="7/4/0" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xe2]" />" />" />
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:58937 at 1641472435.8932316:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="DISCONNECT_REQUEST" Reserve="0" TotalLength="16" />
body="<DisconnectRequest CommunicationChannelID="51" control_endpoint="192.168.178.72:3671" />" />
2022-01-06 13:33:55 WARNING (MainThread) [xknx.log] Received DisconnectRequest from tunnelling sever.
2022-01-06 13:33:55 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:3671 at 1641472435.8938537:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="DISCONNECT_RESPONSE" Reserve="0" TotalLength="8" />
body="<DisconnectResponse CommunicationChannelID="51" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:33:57 DEBUG (MainThread) [xknx.log] Closing transport.
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:3671 at 1641472440.6156733:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="CONNECT_REQUEST" Reserve="0" TotalLength="26" />
body="<ConnectRequest control_endpoint="192.168.178.66:51875" data_endpoint="192.168.178.66:51875" request_type="ConnectRequestType.TUNNEL_CONNECTION" />" />
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:3671 at 1641472440.6343336:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="CONNECT_RESPONSE" Reserve="0" TotalLength="20" />
body="<ConnectResponse communication_channel="52" status_code="ErrorCode.E_NO_ERROR" data_endpoint="192.168.178.72:33526" request_type="ConnectRequestType.TUNNEL_CONNECTION" identifier="4454" />" />
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.log] Tunnel established communication_channel=52, id=4454
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Outgoing" source_address="1.1.102" destination_address="4/2/1" payload="<GroupValueRead />" />
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472440.655279:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="0" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.102")" DestinationAddress="GroupAddress("4/2/1")" Flags="1011110011100000" code="L_DATA_REQ" payload="<GroupValueRead />" />" />" />
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472440.6594715:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="0" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472440.6601884:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="0" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.102")" DestinationAddress="GroupAddress("4/2/1")" Flags="1011110011100000" code="L_DATA_CON" payload="<GroupValueRead />" />" />" />
2022-01-06 13:34:00 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472440.660472:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="0" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:00 INFO (MainThread) [xknx.log] Successfully reconnected to KNX bus.
2022-01-06 13:34:02 WARNING (MainThread) [xknx.log] Error: KNX bus did not respond in time (2.0 secs) to GroupValueRead request for: 4/2/1
2022-01-06 13:34:02 WARNING (MainThread) [xknx.log] Could not sync group address '4/2/1' (Haustür offen - State)
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.7246861:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="1" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.72")" DestinationAddress="GroupAddress("7/5/1")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.7263253:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="1" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.72" destination_address="7/5/1" payload="<GroupValueWrite value="<DPTBinary value="0" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.7337642:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="2" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.65")" DestinationAddress="GroupAddress("7/4/0")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xea]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.73575:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="2" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.65" destination_address="7/4/0" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xea]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.7467122:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="3" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/3/12")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.756535:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="3" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/3/12" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.7731328:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="4" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/3/7")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.793943:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="4" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/3/7" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.8082829:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="5" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.65")" DestinationAddress="GroupAddress("7/4/0")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xf2]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.8103297:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="5" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.65" destination_address="7/4/0" payload="<GroupValueWrite value="<DPTArray value="[0x44,0xf2]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.8301942:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="6" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/3/13")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.8393252:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="6" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/3/13" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.854916:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="7" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/4/9")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x0]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.8640082:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="7" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/4/9" payload="<GroupValueWrite value="<DPTArray value="[0x0]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.8757823:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="8" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/3/9")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.8778586:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="8" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/3/9" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.887369:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="9" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/2/14")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0xc,0xb0]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.8972096:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="9" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/2/14" payload="<GroupValueWrite value="<DPTArray value="[0xc,0xb0]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.911337:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="10" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/3/14")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.91469:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="10" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/3/14" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.9353478:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="22" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="11" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.4")" DestinationAddress="GroupAddress("2/3/10")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.9372818:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="11" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.4" destination_address="2/3/10" payload="<GroupValueWrite value="<DPTArray value="[0x1]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.9443634:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="12" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.79")" DestinationAddress="GroupAddress("7/4/3")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x4f,0x29]" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.9463513:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="12" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.79" destination_address="7/4/3" payload="<GroupValueWrite value="<DPTArray value="[0x4f,0x29]" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472444.9549558:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="13" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.81")" DestinationAddress="GroupAddress("4/2/1")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueResponse value="<DPTBinary value="0" />" />" />" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472444.956786:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="13" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:04 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.81" destination_address="4/2/1" payload="<GroupValueResponse value="<DPTBinary value="0" />" />" />
2022-01-06 13:34:14 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:33526 at 1641472454.6802964:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="23" />
body="<TunnellingRequest communication_channel_id="52" sequence_counter="14" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.79")" DestinationAddress="GroupAddress("7/4/3")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueWrite value="<DPTArray value="[0x4e,0xfb]" />" />" />" />" />
2022-01-06 13:34:14 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:33526 at 1641472454.6841123:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="52" sequence_counter="14" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 13:34:14 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.79" destination_address="7/4/3" payload="<GroupValueWrite value="<DPTArray value="[0x4e,0xfb]" />" />" />
```

farmio: @aschamberger except for the one DisconnectRequest somewhere in the middle it looks fine. Did it work properly?
aschamberger: It works. I can send via knx.send and state is updated. 

However there is still on start:
`2022-01-06 13:34:02 WARNING (MainThread) [xknx.log] Error: KNX bus did not respond in time (2.0 secs) to GroupValueRead request for: 4/2/1`
`2022-01-06 13:34:02 WARNING (MainThread) [xknx.log] Could not sync group address '4/2/1' (Haustür offen - State)`

Btw. is there a way to get KNX connection state? If not, a boolean entity as for example the Fritzbox integration has for WAN status for would be nice.
aschamberger: Should I see a fired knx.read from the developer tools in developer-tools/event when I enter knx_event for listening?
In the logs I can see the result is processed:
```
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="54" sequence_counter="192" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.102")" DestinationAddress="GroupAddress("1/4/8")" Flags="1011110011100000" code="L_DATA_CON" payload="<GroupValueRead />" />" />" />
2022-01-06 18:05:55 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:47516 at 1641488755.3659217:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="54" sequence_counter="192" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 18:05:55 DEBUG (MainThread) [xknx.knx] Received from 192.168.178.72:47516 at 1641488755.5425508:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_REQUEST" Reserve="0" TotalLength="21" />
body="<TunnellingRequest communication_channel_id="54" sequence_counter="193" cemi="<CEMIFrame SourceAddress="IndividualAddress("1.1.9")" DestinationAddress="GroupAddress("1/4/8")" Flags="1011110011010000" code="L_DATA_IND" payload="<GroupValueResponse value="<DPTBinary value="0" />" />" />" />" />
2022-01-06 18:05:55 DEBUG (MainThread) [xknx.knx] Sending to 192.168.178.72:47516 at 1641488755.5459917:
<KNXIPFrame <KNXIPHeader HeaderLength="6" ProtocolVersion="16" KNXIPServiceType="TUNNELLING_ACK" Reserve="0" TotalLength="10" />
body="<TunnellingAck communication_channel_id="54" sequence_counter="193" status_code="ErrorCode.E_NO_ERROR" />" />
2022-01-06 18:05:55 DEBUG (MainThread) [xknx.telegram] <Telegram direction="Incoming" source_address="1.1.9" destination_address="1/4/8" payload="<GroupValueResponse value="<DPTBinary value="0" />" />" />
```
farmio: Entities get state "unavailable " when not connected. 
No, this would be a `call_service` event I think. 

Is the read-flag set for the GA you'd like to read?
aschamberger: > Entities get state "unavailable " when not connected.

This I know, but it's the same like you test for google.com availability vs. internet is available. Of course a test for different websites/"KNX GAs on different devices" would have the same/similar result.

> If the Telegram GA matches a filter defined in configuration.yaml it should trigger a `knx_event`.

Sorry, this I forgot in the test instance. I just tried that also with the right filter set up - so everything works :)

Patch:
diff --git a/changelog.md b/changelog.md
index e312e426..35e3c87c 100644
--- a/changelog.md
+++ b/changelog.md
@@ -4,7 +4,8 @@
 
 ### Connection
 
-- Fix rate limiter wait time. Don't add time waiting for ACK or L_DATA.con frames to the rate_limit.
+- Handle separate Tunneling control and data endpoints
+- Fix rate limiter wait time: don't add time waiting for ACK or L_DATA.con frames to the rate_limit
 
 ## Internals
 
diff --git a/xknx/io/request_response/connect.py b/xknx/io/request_response/connect.py
index ec97d58a..b5ae8696 100644
--- a/xknx/io/request_response/connect.py
+++ b/xknx/io/request_response/connect.py
@@ -27,6 +27,7 @@ class Connect(RequestResponse):
         self.route_back = route_back
         super().__init__(xknx, self.udp_client, ConnectResponse)
         self.communication_channel = 0
+        self.data_endpoint = HPAI()
         self.identifier = 0
 
     def create_knxipframe(self) -> KNXIPFrame:
@@ -48,6 +49,6 @@ class Connect(RequestResponse):
     def on_success_hook(self, knxipframe: KNXIPFrame) -> None:
         """Set communication channel and identifier after having received a valid answer."""
         assert isinstance(knxipframe.body, ConnectResponse)
-        assert isinstance(knxipframe.body.identifier, int)
         self.communication_channel = knxipframe.body.communication_channel
+        self.data_endpoint = knxipframe.body.data_endpoint
         self.identifier = knxipframe.body.identifier
diff --git a/xknx/io/request_response/tunnelling.py b/xknx/io/request_response/tunnelling.py
index 6a295bea..f7fc0e60 100644
--- a/xknx/io/request_response/tunnelling.py
+++ b/xknx/io/request_response/tunnelling.py
@@ -26,6 +26,7 @@ class Tunnelling(RequestResponse):
         self,
         xknx: XKNX,
         udp_client: UDPClient,
+        data_endpoint: tuple[str, int] | None,
         telegram: Telegram,
         src_address: IndividualAddress,
         sequence_counter: int,
@@ -34,6 +35,7 @@ class Tunnelling(RequestResponse):
         """Initialize Tunnelling class."""
         self.xknx = xknx
         self.udp_client = udp_client
+        self.data_endpoint_addr = data_endpoint
         self.src_address = src_address
 
         super().__init__(xknx, self.udp_client, TunnellingAck)
@@ -42,6 +44,10 @@ class Tunnelling(RequestResponse):
         self.sequence_counter = sequence_counter
         self.communication_channel_id = communication_channel_id
 
+    async def send_request(self) -> None:
+        """Build knxipframe (within derived class) and send via UDP."""
+        self.udpclient.send(self.create_knxipframe(), addr=self.data_endpoint_addr)
+
     def create_knxipframe(self) -> KNXIPFrame:
         """Create KNX/IP Frame object to be sent to device."""
         cemi = CEMIFrame.init_from_telegram(
diff --git a/xknx/io/tunnel.py b/xknx/io/tunnel.py
index 65752e0a..cd555a13 100644
--- a/xknx/io/tunnel.py
+++ b/xknx/io/tunnel.py
@@ -69,6 +69,7 @@ class Tunnel(Interface):
         self.init_udp_client()
 
         self._src_address = xknx.own_address
+        self._data_endpoint_addr: tuple[str, int] | None = None
         self.sequence_number = 0
         self.communication_channel: int | None = None
         self.number_heartbeat_failed = 0
@@ -144,6 +145,7 @@ class Tunnel(Interface):
             )
         )
         self.stop_heartbeat()
+        self._data_endpoint_addr = None
         if self.auto_reconnect:
             self._reconnect_task = asyncio.create_task(self._reconnect())
         else:
@@ -172,6 +174,7 @@ class Tunnel(Interface):
             XknxConnectionState.DISCONNECTED
         )
         self.stop_heartbeat()
+        self._data_endpoint_addr = None
         self._stop_reconnect()
         await self._disconnect_request(False)
         await self.udp_client.stop()
@@ -188,6 +191,11 @@ class Tunnel(Interface):
         await connect.start()
         if connect.success:
             self.communication_channel = connect.communication_channel
+            # assign data_endpoint received from server
+            self._data_endpoint_addr = (
+                connect.data_endpoint.ip_addr,
+                connect.data_endpoint.port,
+            )
             # Use the individual address provided by the tunnelling server
             self._src_address = IndividualAddress(connect.identifier)
             self.xknx.current_address = self._src_address
@@ -274,6 +282,7 @@ class Tunnel(Interface):
         tunnelling = Tunnelling(
             self.xknx,
             self.udp_client,
+            self._data_endpoint_addr,
             telegram,
             self._src_address,
             self.sequence_number,
@@ -355,7 +364,9 @@ class Tunnel(Interface):
             communication_channel_id=communication_channel_id,
             sequence_counter=sequence_counter,
         )
-        self.udp_client.send(KNXIPFrame.init_from_body(ack))
+        self.udp_client.send(
+            KNXIPFrame.init_from_body(ack), addr=self._data_endpoint_addr
+        )
 
     def _disconnect_request_received(
         self, disconnect_request: DisconnectRequest
diff --git a/xknx/io/udp_client.py b/xknx/io/udp_client.py
index 2637a73f..1aeee391 100644
--- a/xknx/io/udp_client.py
+++ b/xknx/io/udp_client.py
@@ -116,7 +116,7 @@ class UDPClient:
                 )
             else:
                 knx_logger.debug(
-                    "Received from %s:%s at %s:\n%s",
+                    "Received from %s:%s at %s:\n %s",
                     source[0],
                     source[1],
                     time.time(),
@@ -213,27 +213,28 @@ class UDPClient:
             (transport, _) = await loop.create_datagram_endpoint(
                 lambda: udp_client_factory,
                 local_addr=self.local_addr,
-                remote_addr=self.remote_addr,
             )
             # TODO: typing - remove cast - loop.create_datagram_endpoint should return a DatagramTransport
             self.transport = cast(asyncio.DatagramTransport, transport)
 
-    def send(self, knxipframe: KNXIPFrame) -> None:
+    def send(self, knxipframe: KNXIPFrame, addr: tuple[str, int] | None = None) -> None:
         """Send KNXIPFrame to socket."""
+        _addr = addr or self.remote_addr
         knx_logger.debug(
-            "Sending to %s:%s at %s:\n%s",
-            self.remote_addr[0],
-            self.remote_addr[1],
-            time.time(),
-            knxipframe,
+            "Sending to %s:%s at %s:\n %s", _addr[0], _addr[1], time.time(), knxipframe
         )
         if self.transport is None:
             raise XKNXException("Transport not connected")
 
         if self.multicast:
+            if addr is not None:
+                logger.warning(
+                    "Multicast send to specific address is invalid. %s",
+                    knxipframe,
+                )
             self.transport.sendto(bytes(knxipframe.to_knx()), self.remote_addr)
         else:
-            self.transport.sendto(bytes(knxipframe.to_knx()))
+            self.transport.sendto(bytes(knxipframe.to_knx()), addr=_addr)
 
     def getsockname(self) -> tuple[str, int]:
         """Return socket IP and port."""
diff --git a/xknx/knxip/connect_response.py b/xknx/knxip/connect_response.py
index 3f9c3835..865923ef 100644
--- a/xknx/knxip/connect_response.py
+++ b/xknx/knxip/connect_response.py
@@ -32,8 +32,8 @@ class ConnectResponse(KNXIPBodyResponse):
         communication_channel: int = 0,
         status_code: ErrorCode = ErrorCode.E_NO_ERROR,
         request_type: ConnectRequestType = ConnectRequestType.TUNNEL_CONNECTION,
-        control_endpoint: HPAI = HPAI(),
-        identifier: int | None = None,
+        data_endpoint: HPAI = HPAI(),
+        identifier: int = 0,
     ):
         """Initialize ConnectResponse class."""
         super().__init__(xknx)
@@ -41,7 +41,7 @@ class ConnectResponse(KNXIPBodyResponse):
         self.communication_channel = communication_channel
         self.status_code = status_code
         self.request_type = request_type
-        self.control_endpoint = control_endpoint
+        self.data_endpoint = data_endpoint
         # identifier shall contain KNX Individual Address assigned to this KNXnet/IP Tunnelling connection
         self.identifier = identifier
 
@@ -67,11 +67,11 @@ class ConnectResponse(KNXIPBodyResponse):
         pos = 2
 
         if self.status_code == ErrorCode.E_NO_ERROR:
-            pos += self.control_endpoint.from_knx(raw[pos:])
+            pos += self.data_endpoint.from_knx(raw[pos:])
             pos += crd_from_knx(raw[pos:])
         else:
             # do not parse HPAI and CRD in case of errors - just check length
-            pos += len(raw[pos:])
+            pos = len(raw)
         return pos
 
     def to_knx(self) -> list[int]:
@@ -91,7 +91,7 @@ class ConnectResponse(KNXIPBodyResponse):
         data = []
         data.append(self.communication_channel)
         data.append(self.status_code.value)
-        data.extend(self.control_endpoint.to_knx())
+        data.extend(self.data_endpoint.to_knx())
         data.extend(crd_to_knx())
 
         return data
@@ -102,7 +102,7 @@ class ConnectResponse(KNXIPBodyResponse):
             "<ConnectResponse "
             f'communication_channel="{self.communication_channel}" '
             f'status_code="{self.status_code}" '
-            f'control_endpoint="{self.control_endpoint}" '
+            f'data_endpoint="{self.data_endpoint}" '
             f'request_type="{self.request_type}" '
             f'identifier="{self.identifier}" />'
         )
diff --git a/xknx/knxip/knxip.py b/xknx/knxip/knxip.py
index b5425a86..ed333e0a 100644
--- a/xknx/knxip/knxip.py
+++ b/xknx/knxip/knxip.py
@@ -101,7 +101,7 @@ class KNXIPFrame:
         data.extend(self.body.to_knx())
         return data
 
-    def __str__(self) -> str:
+    def __repr__(self) -> str:
         """Return object as readable string."""
         return f'<KNXIPFrame {self.header}\n body="{self.body}" />'
 


Test patch:
diff --git a/test/io_tests/tunnel_test.py b/test/io_tests/tunnel_test.py
index 3615b9cd..d9d8aa48 100644
--- a/test/io_tests/tunnel_test.py
+++ b/test/io_tests/tunnel_test.py
@@ -1,14 +1,24 @@
 """Unit test for KNX/IP Tunnelling Request/Response."""
 import asyncio
-from unittest.mock import Mock, patch
+from unittest.mock import AsyncMock, Mock, patch
 
 import pytest
 from xknx import XKNX
 from xknx.dpt import DPTArray
 from xknx.io import Tunnel
-from xknx.knxip import HPAI, CEMIFrame, KNXIPFrame, TunnellingAck, TunnellingRequest
+from xknx.knxip import (
+    HPAI,
+    CEMIFrame,
+    ConnectRequest,
+    ConnectResponse,
+    DisconnectRequest,
+    DisconnectResponse,
+    KNXIPFrame,
+    TunnellingAck,
+    TunnellingRequest,
+)
 from xknx.knxip.knxip_enum import CEMIMessageCode
-from xknx.telegram import Telegram, TelegramDirection
+from xknx.telegram import IndividualAddress, Telegram, TelegramDirection
 from xknx.telegram.apci import GroupValueWrite
 
 
@@ -103,3 +113,88 @@ class TestTunnel:
         # one call for the outgoing request and one for the ACK for the confirmation
         assert self.tunnel.udp_client.send.call_count == 2
         await task
+
+    async def test_tunnel_connect_send_disconnect(self, time_travel):
+        """Test initiating a tunnelling connection."""
+        local_addr = ("192.168.1.1", 12345)
+        gateway_control_addr = ("192.168.1.2", 3671)
+        gateway_data_addr = ("192.168.1.2", 56789)
+        self.tunnel.udp_client.connect = AsyncMock()
+        self.tunnel.udp_client.getsockname = Mock(return_value=local_addr)
+        self.tunnel.udp_client.send = Mock()
+        self.tunnel.udp_client.stop = AsyncMock()
+
+        # Connect
+        connect_request = ConnectRequest(
+            self.xknx,
+            control_endpoint=HPAI(*local_addr),
+            data_endpoint=HPAI(*local_addr),
+        )
+        connect_frame = KNXIPFrame.init_from_body(connect_request)
+
+        connection_task = asyncio.create_task(self.tunnel.connect())
+        await time_travel(0)
+        self.tunnel.udp_client.connect.assert_called_once()
+        self.tunnel.udp_client.send.assert_called_once_with(connect_frame)
+
+        connect_response_frame = KNXIPFrame.init_from_body(
+            ConnectResponse(
+                self.xknx,
+                communication_channel=23,
+                data_endpoint=HPAI(*gateway_data_addr),
+                identifier=7,
+            )
+        )
+        self.tunnel.udp_client.handle_knxipframe(
+            connect_response_frame, gateway_control_addr
+        )
+        await connection_task
+        assert self.tunnel._data_endpoint_addr == gateway_data_addr
+        assert self.tunnel._src_address == IndividualAddress(7)
+
+        # Send - use data endpoint
+        self.tunnel.udp_client.send.reset_mock()
+        test_telegram = Telegram(payload=GroupValueWrite(DPTArray((1,))))
+        test_telegram_frame = KNXIPFrame.init_from_body(
+            TunnellingRequest(
+                self.xknx,
+                communication_channel_id=23,
+                sequence_counter=0,
+                cemi=CEMIFrame.init_from_telegram(
+                    self.xknx,
+                    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.udp_client.send.assert_called_once_with(
+            test_telegram_frame, addr=gateway_data_addr
+        )
+        # skip ack and confirmation
+
+        # Disconnect
+        self.tunnel.udp_client.send.reset_mock()
+        disconnect_request = DisconnectRequest(
+            self.xknx, communication_channel_id=23, control_endpoint=HPAI(*local_addr)
+        )
+        disconnect_frame = KNXIPFrame.init_from_body(disconnect_request)
+
+        disconnection_task = asyncio.create_task(self.tunnel.disconnect())
+        await time_travel(0)
+        self.tunnel.udp_client.send.assert_called_once_with(disconnect_frame)
+
+        disconnect_response_frame = KNXIPFrame.init_from_body(
+            DisconnectResponse(
+                self.xknx,
+                communication_channel_id=23,
+            )
+        )
+        self.tunnel.udp_client.handle_knxipframe(
+            disconnect_response_frame, gateway_control_addr
+        )
+        await disconnection_task
+        assert self.tunnel._data_endpoint_addr is None
+        self.tunnel.udp_client.stop.assert_called_once()
diff --git a/test/io_tests/tunnelling_test.py b/test/io_tests/tunnelling_test.py
index bfb4142c..b893e3cc 100644
--- a/test/io_tests/tunnelling_test.py
+++ b/test/io_tests/tunnelling_test.py
@@ -26,6 +26,7 @@ class TestTunnelling:
         """Test tunnelling from KNX bus."""
         xknx = XKNX()
         communication_channel_id = 23
+        data_endpoint = ("192.168.1.2", 4567)
         udp_client = UDPClient(xknx, ("192.168.1.1", 0), ("192.168.1.2", 1234))
         telegram = Telegram(
             destination_address=GroupAddress("1/2/3"),
@@ -36,6 +37,7 @@ class TestTunnelling:
         tunnelling = Tunnelling(
             xknx,
             udp_client,
+            data_endpoint,
             telegram,
             src_address,
             sequence_counter,
@@ -60,7 +62,7 @@ class TestTunnelling:
         ) 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)
+            mock_udp_send.assert_called_with(exp_knxipframe, addr=data_endpoint)
 
         # Response KNX/IP-Frame with wrong type
         wrong_knxipframe = KNXIPFrame(xknx)
diff --git a/test/knxip_tests/connect_response_test.py b/test/knxip_tests/connect_response_test.py
index 71f61a4c..3bd85054 100644
--- a/test/knxip_tests/connect_response_test.py
+++ b/test/knxip_tests/connect_response_test.py
@@ -38,9 +38,7 @@ class TestKNXIPConnectResponse:
         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.data_endpoint == HPAI(ip_addr="192.168.42.10", port=3671)
         assert knxipframe.body.request_type == ConnectRequestType.TUNNEL_CONNECTION
         assert knxipframe.body.identifier == 4607
 
@@ -49,7 +47,7 @@ class TestKNXIPConnectResponse:
             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),
+            data_endpoint=HPAI(ip_addr="192.168.42.10", port=3671),
             identifier=4607,
         )
         knxipframe2 = KNXIPFrame.init_from_body(connect_response)
@@ -151,7 +149,7 @@ class TestKNXIPConnectResponse:
             communication_channel=192,
             status_code=ErrorCode.E_NO_MORE_CONNECTIONS,
             request_type=ConnectRequestType.TUNNEL_CONNECTION,
-            control_endpoint=HPAI(ip_addr="10.1.0.41", port=3671),
+            data_endpoint=HPAI(ip_addr="10.1.0.41", port=3671),
             identifier=0,
         )
         knxipframe2 = KNXIPFrame.init_from_body(connect_response)
diff --git a/test/str_test.py b/test/str_test.py
index 72c9ef56..3d34719f 100644
--- a/test/str_test.py
+++ b/test/str_test.py
@@ -526,12 +526,12 @@ class TestStringRepresentations:
         connect_response = ConnectResponse(xknx)
         connect_response.communication_channel = 13
         connect_response.request_type = ConnectRequestType.TUNNEL_CONNECTION
-        connect_response.control_endpoint = HPAI(ip_addr="192.168.42.1", port=33941)
+        connect_response.data_endpoint = HPAI(ip_addr="192.168.42.1", port=33941)
         connect_response.identifier = 42
         assert (
             str(connect_response)
             == '<ConnectResponse communication_channel="13" status_code="ErrorCode.E_NO_ERROR" '
-            'control_endpoint="192.168.42.1:33941" '
+            'data_endpoint="192.168.42.1:33941" '
             'request_type="ConnectRequestType.TUNNEL_CONNECTION" identifier="42" />'
         )