]> git.basschouten.com Git - openhab-addons.git/blob
1624b9d2447c3c9b6772d0b351c2a0b6ffa56031
[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.paradoxalarm.internal.util;
14
15 import java.io.ByteArrayOutputStream;
16 import java.io.IOException;
17 import java.nio.ByteBuffer;
18 import java.nio.ByteOrder;
19 import java.nio.charset.StandardCharsets;
20
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * The {@link ParadoxUtil} Utility class for different calculations / manipulations of data in the model and
26  * communicators.
27  *
28  * @author Konstantin Polihronov - Initial contribution
29  */
30 public class ParadoxUtil {
31
32     private static final String SPACE_DELIMITER = " ";
33
34     private static final Logger LOGGER = LoggerFactory.getLogger(ParadoxUtil.class);
35
36     public static byte calculateChecksum(byte[] payload) {
37         int result = 0;
38         for (byte everyByte : payload) {
39             result += everyByte;
40         }
41
42         return (byte) (result % 256);
43     }
44
45     public static byte getBit(int value, int bitNumber) {
46         return (byte) ((value >> bitNumber) & 1);
47     }
48
49     public static boolean isBitSet(int value, int bitNumber) {
50         return ((value >> bitNumber) & 1) == 1;
51     }
52
53     public static void printPacket(String description, byte[] array) {
54         if (LOGGER.isTraceEnabled()) {
55             LOGGER.trace("Packet payload size: {}", array[1]);
56             printByteArray(description, array, array[1] + 16);
57         }
58     }
59
60     public static void printByteArray(String description, byte[] array) {
61         if (array == null) {
62             LOGGER.trace("Array is null");
63             return;
64         }
65         printByteArray(description, array, array.length);
66     }
67
68     public static void printByteArray(String description, byte[] array, int length) {
69         if (!LOGGER.isTraceEnabled()) {
70             return;
71         }
72
73         String result = byteArrayToString(array, length);
74         if (!result.isEmpty()) {
75             LOGGER.trace("{}", description + SPACE_DELIMITER + result);
76         }
77     }
78
79     public static String byteArrayToString(byte[] array) {
80         return byteArrayToString(array, array.length);
81     }
82
83     /**
84      *
85      * Returns passed array as HEX string. On every 8 bytes we put space for better readability. Example 16
86      * bytes array output: AA47000263000000 03EE00EEEEEEB727
87      *
88      * @param array
89      * @param length
90      * @return String
91      */
92     public static String byteArrayToString(byte[] array, int length) {
93         if (array == null) {
94             throw new IllegalArgumentException("Array must not be null.");
95         }
96         if (length > array.length) {
97             throw new IllegalArgumentException("Length should be lower than or equal to array length. Length=" + length
98                     + ". Array length=" + array.length);
99         }
100         StringBuilder sb = new StringBuilder();
101         for (int i = 0; i < length; i++) {
102             if (i != 0 && i % 8 == 0) {
103                 sb.append(SPACE_DELIMITER);
104             }
105             sb.append(String.format("%02X", array[i]));
106         }
107         return sb.toString();
108     }
109
110     public static byte setBit(byte byteValue, int i, int j) {
111         if (j == 1) {
112             return (byte) (byteValue | (1 << i));
113         } else {
114             return (byte) (byteValue & ~(1 << i));
115         }
116     }
117
118     public static byte getHighNibble(byte value) {
119         return (byte) ((value & 0xF0) >> 4);
120     }
121
122     public static byte getLowNibble(byte value) {
123         return (byte) (value & 0x0F);
124     }
125
126     public static byte[] mergeByteArrays(byte[]... arrays) {
127         try {
128             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
129             for (byte[] array : arrays) {
130                 outputStream.write(array);
131             }
132             byte[] byteArray = outputStream.toByteArray();
133             return byteArray;
134         } catch (IOException e) {
135             LOGGER.warn("Exception merging arrays:", e);
136             return new byte[0];
137         }
138     }
139
140     public static byte[] intToByteArray(int value) {
141         return ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).order(ByteOrder.BIG_ENDIAN).putInt(value).array();
142     }
143
144     public static byte[] shortToByteArray(short value) {
145         return ByteBuffer.allocate(Short.SIZE / Byte.SIZE).order(ByteOrder.BIG_ENDIAN).putShort(value).array();
146     }
147
148     public static byte[] stringToBCD(String pcPassword) {
149         return stringToBCD(pcPassword, 4);
150     }
151
152     public static byte[] stringToBCD(String pcPassword, int numberOfDigits) {
153         byte[] result = new byte[numberOfDigits / 2];
154         for (int i = 0, j = 0; i < 2; i++, j += 2) {
155             String substring = pcPassword.substring(j, j + 1);
156             int parseInt = Integer.parseInt(substring);
157             result[i] = (byte) ((parseInt & 0x0F) << 4);
158
159             substring = pcPassword.substring(j + 1, j + 2);
160             parseInt = Integer.parseInt(substring);
161             result[i] |= (byte) (parseInt & 0x0F);
162         }
163         return result;
164     }
165
166     /**
167      * This method fills array with 0xEE based on rate.
168      * Example: If input array length is 5 and rate is 8 the array will be extended with 3 more bytes filled with 0xEE
169      *
170      * @param inputArray
171      * @param rate
172      * @return byte[]
173      */
174     public static byte[] extendArray(byte[] inputArray, int rate) {
175         if (inputArray == null || inputArray.length % rate == 0) {
176             return inputArray;
177         }
178
179         final int newLength = inputArray.length + (rate - inputArray.length % rate);
180         byte[] result = new byte[newLength];
181         for (int i = 0; i < result.length; i++) {
182             if (i < inputArray.length) {
183                 result[i] = inputArray[i];
184             } else {
185                 result[i] = (byte) 0xEE;
186             }
187         }
188         return result;
189     }
190
191     /**
192      * Returns bytes from string with standard US_ASCII standard charset to ensure everywhere in the binding we use same
193      * charset.
194      *
195      * @param str
196      * @return byte[]
197      *
198      */
199     public static byte[] getBytesFromString(String str) {
200         if (str == null) {
201             throw new IllegalArgumentException("String must not be null !");
202         }
203
204         return str.getBytes(StandardCharsets.US_ASCII);
205     }
206
207     public static int[] toIntArray(byte[] input) {
208         if (input == null) {
209             throw new IllegalArgumentException("Input array must not be null");
210         }
211         int[] result = new int[input.length];
212         for (int i = 0; i < input.length; i++) {
213             result[i] = input[i] & 0xFF;
214         }
215
216         return result;
217     }
218
219     public static byte[] toByteArray(int[] input) {
220         if (input == null) {
221             throw new IllegalArgumentException("Input array must not be null");
222         }
223         byte[] result = new byte[input.length];
224         for (int i = 0; i < input.length; i++) {
225             result[i] = (byte) (input[i]);
226         }
227
228         return result;
229     }
230 }