]> git.basschouten.com Git - openhab-addons.git/blob
553827f7d1dd8074736910c0d259f5c699244898
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.knx.internal.client;
14
15 import java.util.HashSet;
16 import java.util.Set;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.core.util.HexUtils;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 import tuwien.auto.calimero.FrameEvent;
24 import tuwien.auto.calimero.IndividualAddress;
25 import tuwien.auto.calimero.KNXAddress;
26 import tuwien.auto.calimero.KNXTimeoutException;
27 import tuwien.auto.calimero.Priority;
28 import tuwien.auto.calimero.cemi.CEMILData;
29 import tuwien.auto.calimero.link.KNXLinkClosedException;
30 import tuwien.auto.calimero.link.KNXNetworkLink;
31 import tuwien.auto.calimero.link.NetworkLinkListener;
32 import tuwien.auto.calimero.link.medium.KNXMediumSettings;
33
34 /**
35  * This class provides a simulated KNXNetworkLink with test stubs for integration tests.
36  *
37  * See Calimero documentation, calimero-ng.pdf.
38  *
39  * Frames sent via {@link #sendRequest()} and {@link sendRequestWait()} will be looped back
40  * to all registered listeners. {@link #getLastFrame()} will return the binary data provided
41  * to the last send command.
42  *
43  * @author Holger Friedrich - Initial contribution
44  */
45 @NonNullByDefault({})
46 public class DummyKNXNetworkLink implements KNXNetworkLink {
47     public static final Logger LOGGER = LoggerFactory.getLogger(DummyKNXNetworkLink.class);
48     public static final int GROUP_WRITE = 0x80;
49
50     private byte[] lastFrame = new byte[0];
51     private Set<NetworkLinkListener> listeners = new HashSet<>();
52
53     public void setKNXMedium(KNXMediumSettings settings) {
54         LOGGER.warn(settings.toString());
55     }
56
57     public KNXMediumSettings getKNXMedium() {
58         return KNXMediumSettings.create(KNXMediumSettings.MEDIUM_TP1, new IndividualAddress(1, 2, 3));
59     }
60
61     public void addLinkListener(NetworkLinkListener l) {
62         listeners.add(l);
63     }
64
65     public void removeLinkListener(NetworkLinkListener l) {
66         listeners.remove(l);
67     }
68
69     public void setHopCount(int count) {
70     }
71
72     public int getHopCount() {
73         return 0;
74     }
75
76     public void sendRequest(KNXAddress dst, Priority p, byte[] nsdu)
77             throws KNXTimeoutException, KNXLinkClosedException {
78         sendRequestWait(dst, p, nsdu);
79     }
80
81     public void sendRequestWait(KNXAddress dst, Priority p, byte[] nsdu)
82             throws KNXTimeoutException, KNXLinkClosedException {
83         LOGGER.info("sendRequestWait() {} {} {}", dst, p, HexUtils.bytesToHex(nsdu, " "));
84
85         lastFrame = nsdu.clone();
86
87         // not we want to mimic a received frame by looping it back to all listeners
88
89         /*
90          * relevant steps to create a CEMI frame needed for triggering a frame event:
91          *
92          * final CEMILData f = (CEMILData) e.getFrame();
93          * final var apdu = f.getPayload();
94          * final int svc = DataUnitBuilder.getAPDUService(apdu);
95          * svc == GROUP_WRITE
96          * fireGroupReadWrite(f, DataUnitBuilder.extractASDU(apdu), svc, apdu.length <= 2);
97          * send(CEMILData.MC_LDATA_IND, dst, p, nsdu, true);
98          */
99         int service = GROUP_WRITE;
100         byte[] apdu = new byte[nsdu.length + 2];
101         apdu[0] = (byte) (service >> 8);
102         apdu[1] = (byte) service;
103         System.arraycopy(nsdu, 0, apdu, 2, nsdu.length);
104
105         final IndividualAddress src = new IndividualAddress(1, 1, 1);
106         final boolean repeat = false;
107         final int hopCount = 1;
108
109         FrameEvent f = new FrameEvent(this, new CEMILData(CEMILData.MC_LDATA_IND, src, dst, nsdu, p, repeat, hopCount));
110
111         listeners.forEach(listener -> {
112             listener.indication(f);
113         });
114     }
115
116     public void send(CEMILData msg, boolean waitForCon) throws KNXTimeoutException, KNXLinkClosedException {
117         LOGGER.warn("send() not implemented");
118     }
119
120     public String getName() {
121         return "dummy link";
122     }
123
124     public boolean isOpen() {
125         return true;
126     }
127
128     public void close() {
129     }
130
131     public byte[] getLastFrame() {
132         return lastFrame;
133     }
134 }