]> git.basschouten.com Git - openhab-addons.git/blob
4881222ceaded7d20069b95b38d30d7cc219ee22
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.echonetlite.internal;
14
15 import java.net.SocketAddress;
16 import java.nio.ByteBuffer;
17 import java.nio.ByteOrder;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21
22 /**
23  * @author Michael Barker - Initial contribution
24  */
25 @NonNullByDefault
26 public class EchonetMessage {
27     public static final int TID_OFFSET = 2;
28     public static final int GROUP_OFFSET = 4;
29     public static final int CLASS_OFFSET = 5;
30     public static final int INSTANCE_OFFSET = 6;
31     public static final int ESV_OFFSET = 10;
32     public static final int OPC_OFFSET = 11;
33     public static final int PROPERTY_OFFSET = 12;
34
35     private final ByteBuffer messageData = ByteBuffer.allocateDirect(65536);
36     private final ByteBuffer propertyData = messageData.duplicate();
37     private int propertyCursor = 0;
38     private int currentProperty = -1;
39
40     @Nullable
41     private SocketAddress address;
42
43     public ByteBuffer bufferForRead() {
44         reset();
45         return messageData;
46     }
47
48     private void reset() {
49         messageData.clear();
50         messageData.order(ByteOrder.BIG_ENDIAN);
51         propertyCursor = 0;
52         currentProperty = -1;
53     }
54
55     public void sourceAddress(final SocketAddress address) {
56         this.address = address;
57     }
58
59     public @Nullable SocketAddress sourceAddress() {
60         return address;
61     }
62
63     public @Nullable EchonetClass sourceClass() {
64         return EchonetClassIndex.INSTANCE.lookup(messageData.get(GROUP_OFFSET), messageData.get(CLASS_OFFSET));
65     }
66
67     public byte instance() {
68         return messageData.get(INSTANCE_OFFSET);
69     }
70
71     public Esv esv() {
72         return Esv.forCode(messageData.get(ESV_OFFSET));
73     }
74
75     public int numProperties() {
76         return 0xFF & messageData.get(OPC_OFFSET);
77     }
78
79     public boolean moveNext() {
80         if (propertyCursor < numProperties()) {
81             propertyCursor++;
82             if (-1 == currentProperty) {
83                 currentProperty = PROPERTY_OFFSET;
84             } else {
85                 int pdc = 0xFF & messageData.get(currentProperty + 1);
86                 currentProperty = currentProperty + 2 + pdc;
87             }
88             return true;
89         }
90
91         return false;
92     }
93
94     public int currentEpc() {
95         return messageData.get(currentProperty) & 0xFF;
96     }
97
98     public int currentPdc() {
99         return messageData.get(currentProperty + 1) & 0xFF;
100     }
101
102     public ByteBuffer currentEdt() {
103         propertyData.clear();
104         propertyData.position(currentProperty + 2).limit(currentProperty + 2 + currentPdc());
105         return propertyData;
106     }
107
108     public short tid() {
109         return messageData.getShort(TID_OFFSET);
110     }
111
112     public String toDebug() {
113         return "EchonetMessage{" + "sourceAddress=" + sourceAddress() + ", class=" + sourceClass() + ", instance="
114                 + instance() + ", num properties=" + numProperties() + ", data=" + dumpData() + '}';
115     }
116
117     private String dumpData() {
118         final byte[] bs = new byte[messageData.limit()];
119         final ByteBuffer duplicate = messageData.duplicate();
120         duplicate.position(0).limit(messageData.limit());
121         duplicate.get(bs);
122
123         final StringBuilder sb = new StringBuilder();
124
125         sb.append('[');
126         for (byte b : bs) {
127             sb.append("0x").append(Integer.toHexString(0xFF & b)).append(", ");
128         }
129         sb.setLength(sb.length() - 2);
130         sb.append(']');
131
132         return sb.toString();
133     }
134 }