Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
BTUtils.java
Go to the documentation of this file.
1 /**
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  * Copyright (c) 2020 ZAFENA AB
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 package org.direct_bt;
26 
27 import java.io.PrintStream;
28 
29 public class BTUtils {
30  private static long t0;
31  static {
32  t0 = startupTimeMillisImpl();
33  }
34  private static native long startupTimeMillisImpl();
35 
36  /**
37  * Returns current monotonic time in milliseconds.
38  */
39  public static native long currentTimeMillis();
40 
41  /**
42  * Returns current wall-clock system `time of day` in seconds since Unix Epoch
43  * `00:00:00 UTC on 1 January 1970`.
44  */
45  public static native long wallClockSeconds();
46 
47  /**
48  * Returns the startup time in monotonic time in milliseconds of the native module.
49  */
50  public static long startupTimeMillis() { return t0; }
51 
52  /**
53  * Returns current elapsed monotonic time in milliseconds since module startup, see {@link #startupTimeMillis()}.
54  */
55  public static long elapsedTimeMillis() { return currentTimeMillis() - t0; }
56 
57  /**
58  * Returns elapsed monotonic time in milliseconds since module startup comparing against the given timestamp, see {@link #startupTimeMillis()}.
59  */
60  public static long elapsedTimeMillis(final long current_ts) { return current_ts - t0; }
61 
62  /**
63  * Convenient {@link PrintStream#printf(String, Object...)} invocation, prepending the {@link #elapsedTimeMillis()} timestamp.
64  * @param out the output stream
65  * @param format the format
66  * @param args the arguments
67  */
68  public static void fprintf_td(final PrintStream out, final String format, final Object ... args) {
69  out.printf("[%,9d] ", elapsedTimeMillis());
70  out.printf(format, args);
71  }
72  /**
73  * Convenient {@link PrintStream#println(String)} invocation, prepending the {@link #elapsedTimeMillis()} timestamp.
74  * @param out the output stream
75  * @param msg the string message
76  */
77  public static void println(final PrintStream out, final String msg) {
78  out.printf("[%,9d] %s%s", elapsedTimeMillis(), msg, System.lineSeparator());
79  }
80  /**
81  * Convenient {@link PrintStream#print(String)} invocation, prepending the {@link #elapsedTimeMillis()} timestamp.
82  * @param out the output stream
83  * @param msg the string message
84  */
85  public static void print(final PrintStream out, final String msg) {
86  out.printf("[%,9d] %s", elapsedTimeMillis(), msg);
87  }
88 
89  /**
90  * Defining the supervising timeout for LE connections to be a multiple of the maximum connection interval as follows:
91  * <pre>
92  * ( 1 + conn_latency ) * conn_interval_max_ms * max(2, multiplier) [ms]
93  * </pre>
94  * If above result is smaller than the given min_result_ms, min_result_ms/10 will be returned.
95  * @param conn_latency the connection latency
96  * @param conn_interval_max_ms the maximum connection interval in [ms]
97  * @param min_result_ms the minimum resulting supervisor timeout, defaults to 500ms.
98  * If above formula results in a smaller value, min_result_ms/10 will be returned.
99  * @param multiplier recommendation is 6, we use 10 as default for safety.
100  * @return the resulting supervising timeout in 1/10 [ms], suitable for the {@link BTDevice#connectLE(short, short, short, short, short, short)}.
101  * @see BTDevice#connectLE(short, short, short, short, short, short)
102  */
103  public static int getHCIConnSupervisorTimeout(final int conn_latency, final int conn_interval_max_ms,
104  final int min_result_ms, final int multiplier) {
105  return Math.max(min_result_ms,
106  ( 1 + conn_latency ) * conn_interval_max_ms * Math.max(2, multiplier)
107  ) / 10;
108  }
109 
110  /**
111  * Produce a lower-case hexadecimal string representation of the given byte values.
112  * <p>
113  * If lsbFirst is true, orders LSB left -> MSB right, usual for byte streams.<br>
114  * Otherwise orders MSB left -> LSB right, usual for readable integer values.
115  * </p>
116  * @param bytes the byte array to represent
117  * @param offset offset in byte array to the first byte to print.
118  * @param length number of bytes to print. If negative, will use {@code bytes.length - offset}.
119  * @param lsbFirst true having the least significant byte printed first (lowest addressed byte to highest),
120  * otherwise have the most significant byte printed first (highest addressed byte to lowest).
121  * @return the hex-string representation of the data
122  */
123  public static String bytesHexString(final byte[] bytes, final int offset, final int length,
124  final boolean lsbFirst)
125  {
126  final int byte_len = 0 <= length ? length : bytes.length - offset;
127  if( byte_len > ( bytes.length - offset ) ) {
128  throw new IllegalArgumentException("byte[] ( "+bytes.length+" - "+offset+" ) < "+length+" bytes");
129  }
130  // final char[] hex_array = lowerCase ? HEX_ARRAY_LOW : HEX_ARRAY_BIG;
131  final char[] hex_array = HEX_ARRAY_LOW;
132  final char[] hexChars;
133  final int char_offset;
134 
135  if( lsbFirst ) {
136  // LSB left -> MSB right, no leading `0x`
137  char_offset = 0;
138  hexChars = new char[byte_len * 2];
139  for (int j = 0; j < byte_len; j++) {
140  final int v = bytes[offset + j] & 0xFF;
141  hexChars[char_offset + j * 2] = hex_array[v >>> 4];
142  hexChars[char_offset + j * 2 + 1] = hex_array[v & 0x0F];
143  }
144  } else {
145  // MSB left -> LSB right, with leading `0x`
146  char_offset = 2;
147  hexChars = new char[2 + byte_len * 2];
148  hexChars[0] = '0';
149  hexChars[1] = 'x';
150  for (int j = byte_len-1; j >= 0; j--) {
151  final int v = bytes[offset + j] & 0xFF;
152  hexChars[char_offset + j * 2] = hex_array[v >>> 4];
153  hexChars[char_offset + j * 2 + 1] = hex_array[v & 0x0F];
154  }
155  }
156  return new String(hexChars);
157  }
158  private static final char[] HEX_ARRAY_LOW = "0123456789abcdef".toCharArray();
159  private static final char[] HEX_ARRAY_BIG = "0123456789ABCDEF".toCharArray();
160 
161  /**
162  * Produce a hexadecimal string representation of the given byte value.
163  * @param sb the StringBuilder destination to append
164  * @param value the byte value to represent
165  * @param lowerCase true to use lower case hex-chars, otherwise capital letters are being used.
166  * @return the given StringBuilder for chaining
167  */
168  public static StringBuilder byteHexString(final StringBuilder sb, final byte value, final boolean lowerCase)
169  {
170  final char[] hex_array = lowerCase ? HEX_ARRAY_LOW : HEX_ARRAY_BIG;
171  final int v = value & 0xFF;
172  sb.append(hex_array[v >>> 4]);
173  sb.append(hex_array[v & 0x0F]);
174  return sb;
175  }
176 
177  /**
178  * Returns all valid consecutive UTF-8 characters within buffer
179  * in the range offset -> size or until EOS.
180  * <p>
181  * In case a non UTF-8 character has been detected,
182  * the content will be cut off and the decoding loop ends.
183  * </p>
184  * <p>
185  * Method utilizes a finite state machine detecting variable length UTF-8 codes.
186  * See <a href="http://bjoern.hoehrmann.de/utf-8/decoder/dfa/">Bjoern Hoehrmann's site</a> for details.
187  * </p>
188  */
189  public static native String decodeUTF8String(final byte[] buffer, final int offset, final int size);
190 
191 }
org.direct_bt.BTUtils.getHCIConnSupervisorTimeout
static int getHCIConnSupervisorTimeout(final int conn_latency, final int conn_interval_max_ms, final int min_result_ms, final int multiplier)
Defining the supervising timeout for LE connections to be a multiple of the maximum connection interv...
Definition: BTUtils.java:103
org.direct_bt.BTUtils.fprintf_td
static void fprintf_td(final PrintStream out, final String format, final Object ... args)
Convenient PrintStream#printf(String, Object...) invocation, prepending the elapsedTimeMillis() times...
Definition: BTUtils.java:68
org.direct_bt.BTUtils.println
static void println(final PrintStream out, final String msg)
Convenient PrintStream#println(String) invocation, prepending the elapsedTimeMillis() timestamp.
Definition: BTUtils.java:77
org.direct_bt.BTUtils.currentTimeMillis
static native long currentTimeMillis()
Returns current monotonic time in milliseconds.
org.direct_bt.BTUtils.startupTimeMillis
static long startupTimeMillis()
Returns the startup time in monotonic time in milliseconds of the native module.
Definition: BTUtils.java:50
org.direct_bt.BTUtils.print
static void print(final PrintStream out, final String msg)
Convenient PrintStream#print(String) invocation, prepending the elapsedTimeMillis() timestamp.
Definition: BTUtils.java:85
org.direct_bt.BTUtils.elapsedTimeMillis
static long elapsedTimeMillis(final long current_ts)
Returns elapsed monotonic time in milliseconds since module startup comparing against the given times...
Definition: BTUtils.java:60
org.direct_bt.BTUtils.byteHexString
static StringBuilder byteHexString(final StringBuilder sb, final byte value, final boolean lowerCase)
Produce a hexadecimal string representation of the given byte value.
Definition: BTUtils.java:168
org.direct_bt.BTUtils
Definition: BTUtils.java:29
org.direct_bt.BTUtils.decodeUTF8String
static native String decodeUTF8String(final byte[] buffer, final int offset, final int size)
Returns all valid consecutive UTF-8 characters within buffer in the range offset -> size or until EOS...
org.direct_bt.BTUtils.elapsedTimeMillis
static long elapsedTimeMillis()
Returns current elapsed monotonic time in milliseconds since module startup, see startupTimeMillis().
Definition: BTUtils.java:55
org.direct_bt.BTUtils.wallClockSeconds
static native long wallClockSeconds()
Returns current wall-clock system time of day in seconds since Unix Epoch 00:00:00 UTC on 1 January 1...
org.direct_bt.BTUtils.bytesHexString
static String bytesHexString(final byte[] bytes, final int offset, final int length, final boolean lsbFirst)
Produce a lower-case hexadecimal string representation of the given byte values.
Definition: BTUtils.java:123