1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.uwb.util;
17 // TODO: deprecated UwbUtil, consider to use com.android.server.uwb.util.Hex
18 // and com.android.server.uwb.util.DataTypeConversionUtil
19 public final class UwbUtil {
20     private static final char[] HEXCHARS = {'0', '1', '2', '3', '4', '5', '6', '7',
21             '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
22 
toHexString(byte b)23     public static String toHexString(byte b) {
24         StringBuffer sb = new StringBuffer(2);
25         sb.append(HEXCHARS[(b >> 4) & 0xF]);
26         sb.append(HEXCHARS[b & 0xF]);
27         return sb.toString();
28     }
29 
toHexString(byte[] data)30     public static String toHexString(byte[] data) {
31         StringBuffer sb = new StringBuffer();
32         if (data == null) {
33             return null;
34         }
35         for (int i = 0; i != data.length; i++) {
36             int b = data[i] & 0xff;
37             sb.append(HEXCHARS[(b >> 4) & 0xF]);
38             sb.append(HEXCHARS[b & 0xF]);
39         }
40         return sb.toString();
41     }
42 
43     /** Convert the given int to a 4-byte hex-string */
toHexString(int var)44     public static String toHexString(int var) {
45         byte[] byteArray = new byte[4];
46         byteArray[0] = (byte) (var & 0xff);
47         byteArray[1] = (byte) ((var >> 8) & 0xff);
48         byteArray[2] = (byte) ((var >> 16) & 0xff);
49         byteArray[3] = (byte) ((var >> 24) & 0xff);
50         StringBuilder sb = new StringBuilder();
51         for (byte b : byteArray) {
52             sb.append(HEXCHARS[(b >> 4) & 0xF]);
53             sb.append(HEXCHARS[b & 0xF]);
54         }
55         return sb.toString();
56     }
57 
58     /** Convert the given long to an 8-byte hex-string */
toHexString(long var)59     public static String toHexString(long var) {
60         byte[] byteArray = new byte[8];
61         byteArray[0] = (byte) (var & 0xff);
62         byteArray[1] = (byte) ((var >> 8) & 0xff);
63         byteArray[2] = (byte) ((var >> 16) & 0xff);
64         byteArray[3] = (byte) ((var >> 24) & 0xff);
65         byteArray[4] = (byte) ((var >> 32) & 0xff);
66         byteArray[5] = (byte) ((var >> 40) & 0xff);
67         byteArray[6] = (byte) ((var >> 48) & 0xff);
68         byteArray[7] = (byte) ((var >> 56) & 0xff);
69 
70         StringBuilder sb = new StringBuilder();
71         for (byte b : byteArray) {
72             sb.append(HEXCHARS[(b >> 4) & 0xF]);
73             sb.append(HEXCHARS[b & 0xF]);
74         }
75         return sb.toString();
76     }
77 
getByteArray(String valueString)78     public static byte[] getByteArray(String valueString) {
79         int len = valueString.length();
80         byte[] data = new byte[len / 2];
81         for (int i = 0; i < len; i += 2) {
82             data[i / 2] = (byte) ((Character.digit(valueString.charAt(i), 16) << 4)
83                     + Character.digit(valueString.charAt(i + 1), 16));
84         }
85         return data;
86     }
87 
degreeToRadian(float angleInDegrees)88     public static float degreeToRadian(float angleInDegrees) {
89         return (float) ((angleInDegrees) * Math.PI / 180.0);
90     }
91 
radianTodegree(double angleInRadians)92     public static float radianTodegree(double angleInRadians) {
93         return (float) ((angleInRadians) * 180 / Math.PI);
94     }
95 
96     /**
97      * Fixed point Q format to float conversion. In Q format  Fixed point integer,
98      * integer and fractional bits are specified together.
99      * Q10.6 format = > 10 bits integer and 6 bits fractional
100      *
101      * @param qIn    Integer in Qformat
102      * @param nInts  number of integer bits
103      * @param nFracs number of fractional bits
104      * @return converted float value
105      */
convertQFormatToFloat(int qIn, int nInts, int nFracs)106     public static float convertQFormatToFloat(int qIn, int nInts, int nFracs) {
107         int intPart = (qIn >> nFracs); // extract integer part
108         double fracPart = qIn & ((1 << nFracs) - 1); //extract fractional part
109         fracPart = Math.pow(2, -nFracs) * fracPart; //convert fractional bits to float
110         return (float) ((float) intPart + fracPart);
111     }
112 
toSignedFloat(int nInput, int nBits, int nDivider)113     public static float toSignedFloat(int nInput, int nBits, int nDivider) {
114         float value = 0;
115         if (nDivider > 0) {
116             value = (float) (nInput - nBits) / nDivider;
117         } else {
118             value = (float) nInput;
119         }
120         return value;
121     }
122 
123     /**
124      * Get Two's complement of a number for signed conversion
125      *
126      * @param nInput Integer
127      * @param nBits  number of bits an number
128      * @return two complement of given number value
129      */
twos_compliment(int nInput, int nBits)130     public static int twos_compliment(int nInput, int nBits) {
131         if ((nInput & (1 << (nBits - 1))) != 0)  { // if sign bit is set, Eg- nInput=1111, nBits=4
132             nInput -= 1 << nBits;                  // compute negative value ,0b1111-0b10000= -1
133         }
134         return nInput;                             // return positive value as is
135     }
136 
137     /**
138      * Fixed point float to Q format conversion. In Q format Fixed point integer,
139      * integer and fractional bits are specified together.
140      * Q10.6 format = > 10 bits integer and 6 bits fractional
141      *
142      * @param in     signed Float
143      * @param nInts  number of integer bits
144      * @param nFracs number of fractional bits
145      * @return converted Q format value
146      */
convertFloatToQFormat(float in, int nInts, int nFracs)147     public static int convertFloatToQFormat(float in, int nInts, int nFracs) {
148         int qInt, qFracs, inputStream;
149         if (in >= 0) {
150             qInt = (int) in;
151             qFracs = (int) ((in - qInt) * (1 << (nFracs)));
152             inputStream = (qInt << nFracs) + qFracs;
153         } else {
154             qInt = (int) Math.floor(in);
155             qFracs = (int) ((in - qInt) * (1 << (nFracs)));
156             inputStream = (((1 << (nInts + 1)) + qInt) << nFracs) + qFracs;
157         }
158 
159         return inputStream;
160     }
161 
isBitSet(int flags, int mask)162     public static boolean isBitSet(int flags, int mask) {
163         return (flags & mask) != 0;
164     }
165 }
166