1 package eu.javaexperience.electronic.uartbus;
3 import java.lang.reflect.Proxy;
4 import java.math.BigInteger;
5 import java.util.Arrays;
18 protected static final Logger LOG = JavaExperienceLoggingFacility.getLogger(
new Loggable(
"UartbusTools"));
22 public static byte crc8(byte[] data)
24 return crc8(data, data.length);
27 public static byte crc8(byte[] data,
int length)
35 v = (byte) ((data[i] ^ crc) & 0xff);
58 public static byte[] parseColonData(String data)
60 String[] ns = StringTools.plainSplit(data,
":");
61 byte[] ret =
new byte[ns.length];
62 for(
int i=0;i<ns.length;++i)
64 ret[i] = (byte) (Integer.parseInt(ns[i]) & 0xff);
69 public static String formatColonData(byte[] e)
71 StringBuilder sb =
new StringBuilder();
72 for(
int i=0;i<e.length;++i)
78 sb.append(0xff & e[i]);
83 public static String formatColonDataWithValidation(byte[] e)
87 return "!"+formatColonData(e);
89 return formatColonData(e);
92 public static enum PacketFormattingMode
95 RAW_COLON_WITH_VERIFY,
99 public static String formatPacketWithMode(PacketFormattingMode mode, byte[] data)
110 return formatColonDataWithValidation(data);
114 return formatColonData(data);
116 case RAW_COLON_WITH_VERIFY:
117 return formatColonDataWithValidation(data);
123 public static int packValue(
boolean signed,
int value, byte[] dst,
int startIndex)
125 return packValue(
signed, BigInteger.valueOf(value), dst, startIndex);
128 public static int packValue(
boolean signed,
long value, byte[] dst,
int startIndex)
130 return packValue(
signed, BigInteger.valueOf(value), dst, startIndex);
133 public static int packValue(
boolean signed, BigInteger value, byte[] dst,
int startIndex)
135 Boolean negative = null;
136 if(!
signed && value.signum() < 0)
138 throw new RuntimeException(
"Value must be unsigned: "+value);
143 if(value.signum() < 0)
145 value = value.negate().subtract(BigInteger.ONE);
154 byte[] re = value.toByteArray();
157 re = Arrays.copyOfRange(re, 1, re.length);
160 return packValue(negative, re, dst, startIndex);
163 public static int calcPackReqBytes(
boolean signed, BigInteger value)
165 if(
signed && value.signum() < 0)
167 value = value.negate();
169 return calcPackReqBytes(
signed, value.toByteArray());
172 public static int calcPackReqBytes(
boolean signed, byte[] value)
174 int sReq = 9*(value.length-1) + (value.length-1)/7;
176 int lst = 0xff & value[0];
178 boolean msb = (lst & 0x80) == 0x80;
218 public static int packValue(Boolean negative, byte[] value, byte[] dst,
int startIndex)
220 if(0 == value.length)
222 if(Boolean.TRUE == negative)
224 dst[startIndex] = 0x40;
233 int sReq = calcPackReqBytes(null != negative, value);
236 int index = value.length-1;
238 for(
int i = sReq-1;i >=0;--i,--index)
247 val = (0xff & value[index+1]) >> (8-off);
250 val |= (0xff & value[index]) << off;
267 if(Boolean.TRUE == negative && i == 0)
272 dst[startIndex+i] = (byte) val;
278 public static byte[] packInt(
boolean signed,
int value)
280 byte[] ret =
new byte[5];
281 int r = packValue(
signed, value, ret, 0);
282 return Arrays.copyOf(ret, r);
285 public static BigInteger unpackValue(
boolean signed, byte[] data,
int startIndex)
287 return unpackValue(
signed, data, startIndex, null);
290 public static BigInteger unpackValue(
boolean signed, byte[] data,
int startIndex,
int[] usedBytes)
295 while((data[startIndex+ahead] & 0x80) > 0)
300 catch(ArrayIndexOutOfBoundsException out)
302 throw new RuntimeException(
"Incomplete value in the buffer.");
305 final int used = ahead;
306 BigInteger ret = null;
308 int cut = 0xff & ~((
signed?0x40:0x00) | 0x80);
310 final byte cut_first = 0x7f;
312 int req = ((ahead+1)*7)/8+1;
314 byte[] num =
new byte[req];
317 for(
int index = num.length-1;index >= 0&& ahead >= 0;--index, --ahead)
326 int val = ((index != startIndex?cut_first:cut) & data[startIndex+ahead]) >>> off;
330 int prev = ((cut_first & data[startIndex+ahead-1]) << (7-off));
340 num[index] = (byte) val;
345 ret =
new BigInteger(num);
348 if(
signed && (data[startIndex] & 0x40) > 0)
350 ret = ret.negate().subtract(BigInteger.ONE);
353 if(null != usedBytes && usedBytes.length > 0)
355 usedBytes[0] = used+1;
361 public static byte[] getValidPacket(byte[] e)
363 if(e.length > 0 &&
UartbusTools.crc8(e, e.length-1) == e[e.length-1])
365 return Arrays.copyOf(e, e.length-1);
371 public static boolean isPacketCrc8Valid(byte[] data)
377 return UartbusTools.crc8(data, data.length-1) == data[data.length-1];
380 public static void printPacketStdout(byte[] data)
384 boolean valid =
UartbusTools.crc8(data, data.length-1) == data[data.length-1];
385 System.out.println((valid?
"":
"!")+
UartbusTools.formatColonData(data));
403 if(Proxy.isProxyClass(conn.getClass()))
405 str =
"Proxy: "+System.identityHashCode(conn);
407 LoggingTools.tryLogFormatException
412 "Exception while calling `%s`.call(). This might happened beacuse you connect to and older version of connection implementation.",