1/* 2 * Copyright (C) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "bt_uuid.h" 17 18#include <sys/time.h> 19#include <algorithm> 20#include <cstdlib> 21#include "array" 22#include "securec.h" 23#include <cstdlib> 24#include "string" 25#include "sys/time.h" 26#include <ctime> 27 28namespace OHOS { 29namespace bluetooth { 30Uuid Uuid::Random() 31{ 32 Uuid random; 33 34 struct timeval tv = {}; 35 struct timezone tz = {}; 36 struct tm randomTime = {}; 37 unsigned int randNum = 0; 38 unsigned long int tvUsec = 0; 39 40 rand_r(&randNum); 41 gettimeofday(&tv, &tz); 42 localtime_r(&tv.tv_sec, &randomTime); 43 44 tvUsec = static_cast<unsigned long int>(tv.tv_usec); 45 46 random.uuid_[UUID_NODE_SIXTH_BYTE] = 47 static_cast<uint8_t>(tvUsec & 0x00000000000000FF); 48 random.uuid_[UUID_NODE_FIFTH_BYTE] = 49 static_cast<uint8_t>((tvUsec & 0x000000000000FF00) >> BASE_BIT_OPT_SIZE); 50 random.uuid_[UUID_NODE_FOURTH_BYTE] = 51 static_cast<uint8_t>((tvUsec & 0x0000000000FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE); 52 random.uuid_[UUID_NODE_THIRD_BYTE] = 53 static_cast<uint8_t>((tvUsec & 0x00000000FF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE); 54 random.uuid_[UUID_NODE_FIRST_BYTE] = 55 static_cast<uint8_t>((tvUsec & 0x000000FF00000000) >> BIT_OPT_FOUR_BYTE * BASE_BIT_OPT_SIZE); 56 random.uuid_[UUID_CLOCK_SEQ] = 57 static_cast<uint8_t>((tvUsec & 0x0000FF0000000000) >> BIT_OPT_FIVE_BYTE * BASE_BIT_OPT_SIZE); 58 random.uuid_[UUID_VARIANT] = 59 static_cast<uint8_t>((tvUsec & 0x00FF000000000000) >> BIT_OPT_SIX_BYTE * BASE_BIT_OPT_SIZE); 60 random.uuid_[UUID_TIME_HIGH] = 61 static_cast<uint8_t>((tvUsec & 0xFF00000000000000) >> BIT_OPT_SEVEN_BYTE * BASE_BIT_OPT_SIZE); 62 random.uuid_[UUID_VERSION] = 63 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_sec) + randNum) & 0xFF); 64 random.uuid_[UUID_TIME_MID_SECEND_BYTE] = 65 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_min) + (randNum >> BASE_BIT_OPT_SIZE)) & 0xFF); 66 random.uuid_[UUID_TIME_MID_FIRST_BYTE] = 67 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_hour) + 68 (randNum >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF); 69 random.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = 70 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_mday) + 71 (randNum >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF); 72 random.uuid_[UUID_TIME_LOW_THIRD_BYTE] = 73 static_cast<uint8_t>(static_cast<unsigned int>(randomTime.tm_mon) & 0xFF); 74 random.uuid_[UUID_TIME_LOW_SECEND_BYTE] = 75 static_cast<uint8_t>(static_cast<unsigned int>(randomTime.tm_year) & 0xFF); 76 random.uuid_[UUID_TIME_LOW_FIRST_BYTE] = 77 static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_year) & 0xFF00) >> BASE_BIT_OPT_SIZE); 78 79 return random; 80} 81 82Uuid Uuid::ConvertFromString(const std::string &name) 83{ 84 Uuid ret; 85 std::string tmp = name; 86 std::size_t pos = tmp.find("-"); 87 88 while (pos != std::string::npos) { 89 tmp.replace(pos, 1, ""); 90 pos = tmp.find("-"); 91 } 92 93 for (std::size_t i = 0; (i + 1) < tmp.length(); i += SIZE_STRING_TO_INT) { 94 ret.uuid_[i / SIZE_STRING_TO_INT] = std::stoi(tmp.substr(i, SIZE_STRING_TO_INT), nullptr, UUID128_BYTES_TYPE); 95 } 96 97 return ret; 98} 99 100Uuid Uuid::ConvertFrom16Bits(uint16_t uuid) 101{ 102 Uuid tmp; 103 tmp.uuid_[UUID_TIME_LOW_THIRD_BYTE] = static_cast<uint8_t>((uuid & 0xFF00) >> BASE_BIT_OPT_SIZE); 104 tmp.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = static_cast<uint8_t>(uuid & 0x00FF); 105 return tmp; 106} 107 108Uuid Uuid::ConvertFrom32Bits(uint32_t uuid) 109{ 110 Uuid tmp; 111 tmp.uuid_[UUID_TIME_LOW_FIRST_BYTE] = 112 static_cast<uint8_t>((uuid & 0xFF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE); 113 tmp.uuid_[UUID_TIME_LOW_SECEND_BYTE] = 114 static_cast<uint8_t>((uuid & 0x00FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE); 115 tmp.uuid_[UUID_TIME_LOW_THIRD_BYTE] = 116 static_cast<uint8_t>((uuid & 0x0000FF00) >> BASE_BIT_OPT_SIZE); 117 tmp.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = 118 static_cast<uint8_t>(uuid & 0x000000FF); 119 return tmp; 120} 121 122Uuid Uuid::ConvertFromBytesLE(const uint8_t *uuid, const size_t size) 123{ 124 Uuid leUuid; 125 if (size < UUID128_BYTES_TYPE) { 126 return leUuid; 127 } 128 UUID128Bit le; 129 if (memcpy_s(le.data(), UUID128_BYTES_TYPE, uuid, UUID128_BYTES_TYPE) != EOK) { 130 return leUuid; 131 } 132 std::reverse_copy(le.data(), le.data() + UUID128_BYTES_TYPE, leUuid.uuid_.begin()); 133 return leUuid; 134} 135 136Uuid Uuid::ConvertFromMostAndLeastBit(uint64_t mostSigBits, uint64_t leastSigBits) 137{ 138 Uuid tmp; 139 int division = UUID128_BYTES_TYPE / SIZE_STRING_TO_INT; 140 141 for (int i = 0; i < division; i++) { 142 tmp.uuid_[i] = (mostSigBits >> (BASE_BIT_OPT_SIZE * (division - i - 1))) & 0xFF; 143 } 144 145 for (int i = division; i < UUID128_BYTES_TYPE; i++) { 146 tmp.uuid_[i] = (leastSigBits >> (BASE_BIT_OPT_SIZE * (2 * division - i - 1))) & 0xFF; // value of division * 2 147 } 148 149 return tmp; 150} 151 152Uuid Uuid::ConvertFrom128Bits(const UUID128Bit &uuid) 153{ 154 Uuid tmp; 155 tmp.uuid_ = uuid; 156 return tmp; 157} 158 159uint16_t Uuid::ConvertTo16Bits() const 160{ 161 uint16_t ret = uuid_[UUID_TIME_LOW_THIRD_BYTE] & 0xFF; 162 ret = (ret << BASE_BIT_OPT_SIZE) + uuid_[UUID_TIME_LOW_FOURTH_BYTE]; 163 return ret; 164} 165 166uint32_t Uuid::ConvertTo32Bits() const 167{ 168 uint32_t ret = 0; 169 for (int i = 0; i < UUID32_BYTES_TYPE; i++) { 170 ret = (ret << BASE_BIT_OPT_SIZE) + uuid_[i]; 171 } 172 return ret; 173} 174 175bool Uuid::ConvertToBytesLE(uint8_t *value, const size_t size) const 176{ 177 if (size < UUID128_BYTES_TYPE) { 178 return false; 179 } 180 181 UUID128Bit le; 182 std::reverse_copy(uuid_.data(), uuid_.data() + UUID128_BYTES_TYPE, le.begin()); 183 if (memcpy_s(value, UUID128_BYTES_TYPE, le.data(), UUID128_BYTES_TYPE) != EOK) { 184 return false; 185 } 186 return true; 187} 188 189Uuid::UUID128Bit Uuid::ConvertTo128Bits() const 190{ 191 return uuid_; 192} 193 194int Uuid::GetUuidType() const 195{ 196 for (int i = UUID32_BYTES_TYPE; i < UUID128_BYTES_TYPE; i++) { 197 if (BASE_UUID[i] != uuid_[i]) { 198 return UUID128_BYTES_TYPE; 199 } 200 } 201 202 if ((uuid_[0] == 0) && (uuid_[1] == 0)) { 203 return UUID16_BYTES_TYPE; 204 } 205 206 return UUID32_BYTES_TYPE; 207} 208 209bool Uuid::operator==(const Uuid &rhs) const 210{ 211 return (uuid_ == rhs.uuid_); 212} 213 214bool Uuid::operator!=(const Uuid &rhs) const 215{ 216 return (uuid_ != rhs.uuid_); 217} 218} // namespace bluetooth 219} // namespace OHOS