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