]> git.basschouten.com Git - openhab-addons.git/blob
ae1c1d4a7839e5c8e00fada7e793efd4e5d10ee9
[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.velux.internal.bridge.slip.utils;
14
15 import java.util.Arrays;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18
19 /**
20  * Utility class for handling of packets i.e. array of bytes.
21  *
22  * <P>
23  * Methods available:
24  * <UL>
25  * <LI>{@link #Packet(byte[])} creates a Packet object based on the array of bytes.</LI>
26  * <LI>{@link #length()} returns the number of bytes contained within this Packet.</LI>
27  * <LI>{@link #toByteArray} returns the complete Packet as array of bytes.</LI>
28  * <LI>{@link #getByteArray} returns the a range of bytes as array of bytes.</LI>
29  * <LI>{@link #toString} returns the complete packet as human-readable String.</LI>
30  * <LI>{@link #getOneByteValue} returns the value of one byte as int.</LI>
31  * <LI>{@link #setOneByteValue} sets the value of one byte within the Packet.</LI>
32  * <LI>{@link #getTwoByteValue} returns the value of two bytes as int.</LI>
33  * <LI>{@link #setTwoByteValue} sets the value of two bytes within the Packet.</LI>
34  * <LI>{@link #getFourByteValue(int)} returns the value of four bytes as int.</LI>
35  * <LI>{@link #setFourByteValue} sets the value of four bytes within the Packet.</LI>
36  * <LI>{@link #getString} returns the value of a range of bytes as String.</LI>
37  * <LI>{@link #setString} sets the value of a range of bytes within the Packet.</LI>
38  * </UL>
39  * Static methods are:
40  * <UL>
41  * <LI>{@link #shortToString} converts a byte into a human-readable hex-String.</LI>
42  * <LI>{@link #byteArrayToInt} converts a range of four bytes into an int.</LI>
43  * <LI>{@link #intToIPAddressString} converts an int into a String.</LI>
44  * </UL>
45  *
46  * @author Guenther Schreiner - Initial contribution.
47  */
48 @NonNullByDefault
49 public class Packet {
50
51     /*
52      * ===========================================================
53      * Internal Objects
54      */
55
56     private static final String BLANK = " ";
57
58     private byte[] data;
59
60     /*
61      * ===========================================================
62      * Constructor Method
63      */
64
65     /**
66      * Constructor: Create a {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet} out of a
67      * sequence of
68      * bytes.
69      *
70      * @param thisData Packet as Array of bytes.
71      */
72     public Packet(byte[] thisData) {
73         this.data = thisData;
74     }
75
76     /*
77      * ===========================================================
78      * Access Methods
79      */
80
81     /**
82      * Returns the length of the {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet}..
83      *
84      * @return <b>packetLength</b>
85      *         of type int.
86      */
87     public int length() {
88         return data.length;
89     }
90
91     /**
92      * Returns the complete {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet} as sequence of
93      * bytes.
94      *
95      * @return <b>packet</b>
96      *         of type Array-of-byte.
97      */
98     public byte[] toByteArray() {
99         return data;
100     }
101
102     /**
103      * Returns a part of the {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet} as sequence of
104      * bytes
105      * starting at position (n) up to the position (n+length-1).
106      *
107      * @param position Position (n) within the packet.
108      * @param length Length of the intended slice as int.
109      * @return <b>packet</b> of type Array-of-byte.
110      */
111     public byte[] getByteArray(int position, int length) {
112         return Arrays.copyOfRange(data, position, position + length);
113     }
114
115     /**
116      * Returns the complete {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet}
117      * as human-readable sequence of hex bytes each separated by the given separator.
118      *
119      * @param separator as of Type String.
120      * @return <b>packetString</b> of type String.
121      */
122     public String toString(String separator) {
123         StringBuilder sb = new StringBuilder();
124         for (byte b : this.data) {
125             sb.append(String.format("%02X", b));
126             sb.append(separator);
127         }
128         if (sb.lastIndexOf(separator) > 0) {
129             sb.deleteCharAt(sb.lastIndexOf(separator));
130         }
131         return (sb.toString());
132     }
133
134     /**
135      * Returns the complete {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet}
136      * as human-readable sequence of hex bytes each separated by a blank.
137      *
138      * @return <b>packetString</b> of type String.
139      */
140     @Override
141     public String toString() {
142         return this.toString(BLANK);
143     }
144
145     /**
146      * Returns the value of the byte at (n)th position as int value for convenience.
147      *
148      * @param position Position (n) within the packet.
149      * @return <b>value</b> of type int.
150      */
151     public int getOneByteValue(int position) {
152         return (data[position] & 0xff);
153     }
154
155     /**
156      * Modifies the value of the byte at (n)th position by setting it to the value passed as int.
157      *
158      * @param position Position (n) within the packet.
159      * @param value of type int.
160      */
161     public void setOneByteValue(int position, int value) {
162         data[position] = (byte) value;
163     }
164
165     /**
166      * Returns the value of the bytes at the positions (n)th and (n+1) as int value for convenience.
167      * <P>
168      * Note: Big-endian LSB-0 encoding.
169      * </P>
170      *
171      * @param position Position (n) within the packet.
172      * @return <b>value</b> of type int.
173      */
174     public int getTwoByteValue(int position) {
175         return 0x00 << 24 | 0x00 << 16 | (data[position] & 0xff) << 8 | (data[position + 1] & 0xff);
176     }
177
178     /**
179      * Modifies the value of the bytes at the positions (n) and (n+1) by setting it to the value passed as int.
180      * <P>
181      * Note: Big-endian LSB-0 encoding.
182      * </P>
183      *
184      * @param position Position (n) within the packet.
185      * @param value of type int.
186      */
187     public void setTwoByteValue(int position, int value) {
188         data[position] = (byte) ((value >>> 8) & 0xFF);
189         data[position + 1] = (byte) (value & 0xFF);
190     }
191
192     /**
193      * Returns the value of the bytes at the positions (n)th to (n+3) as int value for convenience.
194      * <P>
195      * Note: Big-endian LSB-0 encoding.
196      * </P>
197      *
198      * @param position Position (n) within the packet.
199      * @return <b>value</b> of type int.
200      */
201     public int getFourByteValue(int position) {
202         return data[position] << 24 | (data[position + 1] & 0xff) << 16 | (data[position + 2] & 0xff) << 8
203                 | (data[position + 3] & 0xff);
204     }
205
206     /**
207      * Modifies the value of the bytes at the positions (n) to (n+3) by setting it to the value passed as int.
208      * <P>
209      * Note: Big-endian LSB-0 encoding.
210      * </P>
211      *
212      * @param position Position (n) within the packet.
213      * @param value of type int.
214      */
215     public void setFourByteValue(int position, int value) {
216         data[position] = (byte) ((value >>> 24) & 0xFF);
217         data[position + 1] = (byte) ((value >>> 16) & 0xFF);
218         data[position + 2] = (byte) ((value >>> 8) & 0xFF);
219         data[position + 3] = (byte) (value & 0xFF);
220     }
221
222     /**
223      * Returns the char string converted byte-by-byte starting at the position (n) up to (n+length+1).
224      * <P>
225      * Note: Any trailing null char will be eliminated.
226      * </P>
227      *
228      * @param position Position (n) within the packet.
229      * @param length Length of the intended slice as int.
230      * @return <b>value</b> of type String.
231      */
232     public String getString(int position, int length) {
233         return new String(Arrays.copyOfRange(data, position, position + length - 1)).replace("\0", "");
234     }
235
236     /**
237      * Modifies the value of the bytes starting at the position (n) by setting it to the character values passed as
238      * String.
239      * <P>
240      * Note: The trailing null char will not be stored.
241      * </P>
242      *
243      * @param position Position (n) within the packet.
244      * @param text of type String.
245      */
246     public void setString(int position, String text) {
247         System.arraycopy(text, 0, data, 0, text.length());
248     }
249
250     /*
251      * ===========================================================
252      * Conversion Methods
253      */
254
255     /**
256      * Returns the hex char string representing the byte.
257      *
258      * @param oneByte of type byte to be converted.
259      * @return <b>hexByteString</b> of type String.
260      */
261     static String shortToString(int oneByte) {
262         return String.format("%02X", oneByte);
263     }
264
265     static int byteArrayToInt(byte[] data) {
266         return data[0] << 24 | (data[1] & 0xff) << 16 | (data[2] & 0xff) << 8 | (data[3] & 0xff);
267     }
268
269     /**
270      * Returns the dotted string representing an IP address.
271      *
272      * @param ipAddress of type int to be converted.
273      * @return <b>ipAddressString</b> of type String.
274      */
275     public static String intToIPAddressString(int ipAddress) {
276         return String.format("%d.%d.%d.%d", ((ipAddress >>> 24) & 0xFF), ((ipAddress >>> 16) & 0xFF),
277                 ((ipAddress >>> 8) & 0xFF), (ipAddress & 0xFF));
278     }
279 }