2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.velux.internal.bridge.slip.utils;
15 import java.util.Arrays;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
20 * Utility class for handling of packets i.e. array of bytes.
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>
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>
46 * @author Guenther Schreiner - Initial contribution.
52 * ===========================================================
56 private static final String BLANK = " ";
61 * ===========================================================
66 * Constructor: Create a {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet} out of a
70 * @param thisData Packet as Array of bytes.
72 public Packet(byte[] thisData) {
77 * ===========================================================
82 * Returns the length of the {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet}..
84 * @return <b>packetLength</b>
92 * Returns the complete {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet} as sequence of
95 * @return <b>packet</b>
96 * of type Array-of-byte.
98 public byte[] toByteArray() {
103 * Returns a part of the {@link org.openhab.binding.velux.internal.bridge.slip.utils.Packet Packet} as sequence of
105 * starting at position (n) up to the position (n+length-1).
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.
111 public byte[] getByteArray(int position, int length) {
112 return Arrays.copyOfRange(data, position, position + length);
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.
119 * @param separator as of Type String.
120 * @return <b>packetString</b> of type String.
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);
128 if (sb.lastIndexOf(separator) > 0) {
129 sb.deleteCharAt(sb.lastIndexOf(separator));
131 return (sb.toString());
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.
138 * @return <b>packetString</b> of type String.
141 public String toString() {
142 return this.toString(BLANK);
146 * Returns the value of the byte at (n)th position as int value for convenience.
148 * @param position Position (n) within the packet.
149 * @return <b>value</b> of type int.
151 public int getOneByteValue(int position) {
152 return (data[position] & 0xff);
156 * Modifies the value of the byte at (n)th position by setting it to the value passed as int.
158 * @param position Position (n) within the packet.
159 * @param value of type int.
161 public void setOneByteValue(int position, int value) {
162 data[position] = (byte) value;
166 * Returns the value of the bytes at the positions (n)th and (n+1) as int value for convenience.
168 * Note: Big-endian LSB-0 encoding.
171 * @param position Position (n) within the packet.
172 * @return <b>value</b> of type int.
174 public int getTwoByteValue(int position) {
175 return 0x00 << 24 | 0x00 << 16 | (data[position] & 0xff) << 8 | (data[position + 1] & 0xff);
179 * Modifies the value of the bytes at the positions (n) and (n+1) by setting it to the value passed as int.
181 * Note: Big-endian LSB-0 encoding.
184 * @param position Position (n) within the packet.
185 * @param value of type int.
187 public void setTwoByteValue(int position, int value) {
188 data[position] = (byte) ((value >>> 8) & 0xFF);
189 data[position + 1] = (byte) (value & 0xFF);
193 * Returns the value of the bytes at the positions (n)th to (n+3) as int value for convenience.
195 * Note: Big-endian LSB-0 encoding.
198 * @param position Position (n) within the packet.
199 * @return <b>value</b> of type int.
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);
207 * Modifies the value of the bytes at the positions (n) to (n+3) by setting it to the value passed as int.
209 * Note: Big-endian LSB-0 encoding.
212 * @param position Position (n) within the packet.
213 * @param value of type int.
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);
223 * Returns the char string converted byte-by-byte starting at the position (n) up to (n+length+1).
225 * Note: Any trailing null char will be eliminated.
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.
232 public String getString(int position, int length) {
233 return new String(Arrays.copyOfRange(data, position, position + length - 1)).replace("\0", "");
237 * Modifies the value of the bytes starting at the position (n) by setting it to the character values passed as
240 * Note: The trailing null char will not be stored.
243 * @param position Position (n) within the packet.
244 * @param text of type String.
246 public void setString(int position, String text) {
247 System.arraycopy(text, 0, data, 0, text.length());
251 * ===========================================================
256 * Returns the hex char string representing the byte.
258 * @param oneByte of type byte to be converted.
259 * @return <b>hexByteString</b> of type String.
261 static String shortToString(int oneByte) {
262 return String.format("%02X", oneByte);
265 static int byteArrayToInt(byte[] data) {
266 return data[0] << 24 | (data[1] & 0xff) << 16 | (data[2] & 0xff) << 8 | (data[3] & 0xff);
270 * Returns the dotted string representing an IP address.
272 * @param ipAddress of type int to be converted.
273 * @return <b>ipAddressString</b> of type String.
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));