195489c19Sopenharmony_ci/* 295489c19Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 395489c19Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 495489c19Sopenharmony_ci * you may not use this file except in compliance with the License. 595489c19Sopenharmony_ci * You may obtain a copy of the License at 695489c19Sopenharmony_ci * 795489c19Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 895489c19Sopenharmony_ci * 995489c19Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1095489c19Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1195489c19Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1295489c19Sopenharmony_ci * See the License for the specific language governing permissions and 1395489c19Sopenharmony_ci * limitations under the License. 1495489c19Sopenharmony_ci */ 1595489c19Sopenharmony_ci 1695489c19Sopenharmony_ci#include "bt_uuid.h" 1795489c19Sopenharmony_ci 1895489c19Sopenharmony_ci#include <sys/time.h> 1995489c19Sopenharmony_ci#include <algorithm> 2095489c19Sopenharmony_ci#include <cstdlib> 2195489c19Sopenharmony_ci#include "array" 2295489c19Sopenharmony_ci#include "securec.h" 2395489c19Sopenharmony_ci#include <cstdlib> 2495489c19Sopenharmony_ci#include "string" 2595489c19Sopenharmony_ci#include "sys/time.h" 2695489c19Sopenharmony_ci#include <ctime> 2795489c19Sopenharmony_ci 2895489c19Sopenharmony_cinamespace OHOS { 2995489c19Sopenharmony_cinamespace bluetooth { 3095489c19Sopenharmony_ciUuid Uuid::Random() 3195489c19Sopenharmony_ci{ 3295489c19Sopenharmony_ci Uuid random; 3395489c19Sopenharmony_ci 3495489c19Sopenharmony_ci struct timeval tv = {}; 3595489c19Sopenharmony_ci struct timezone tz = {}; 3695489c19Sopenharmony_ci struct tm randomTime = {}; 3795489c19Sopenharmony_ci unsigned int randNum = 0; 3895489c19Sopenharmony_ci unsigned long int tvUsec = 0; 3995489c19Sopenharmony_ci 4095489c19Sopenharmony_ci rand_r(&randNum); 4195489c19Sopenharmony_ci gettimeofday(&tv, &tz); 4295489c19Sopenharmony_ci localtime_r(&tv.tv_sec, &randomTime); 4395489c19Sopenharmony_ci 4495489c19Sopenharmony_ci tvUsec = static_cast<unsigned long int>(tv.tv_usec); 4595489c19Sopenharmony_ci 4695489c19Sopenharmony_ci random.uuid_[UUID_NODE_SIXTH_BYTE] = 4795489c19Sopenharmony_ci static_cast<uint8_t>(tvUsec & 0x00000000000000FF); 4895489c19Sopenharmony_ci random.uuid_[UUID_NODE_FIFTH_BYTE] = 4995489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0x000000000000FF00) >> BASE_BIT_OPT_SIZE); 5095489c19Sopenharmony_ci random.uuid_[UUID_NODE_FOURTH_BYTE] = 5195489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0x0000000000FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE); 5295489c19Sopenharmony_ci random.uuid_[UUID_NODE_THIRD_BYTE] = 5395489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0x00000000FF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE); 5495489c19Sopenharmony_ci random.uuid_[UUID_NODE_FIRST_BYTE] = 5595489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0x000000FF00000000) >> BIT_OPT_FOUR_BYTE * BASE_BIT_OPT_SIZE); 5695489c19Sopenharmony_ci random.uuid_[UUID_CLOCK_SEQ] = 5795489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0x0000FF0000000000) >> BIT_OPT_FIVE_BYTE * BASE_BIT_OPT_SIZE); 5895489c19Sopenharmony_ci random.uuid_[UUID_VARIANT] = 5995489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0x00FF000000000000) >> BIT_OPT_SIX_BYTE * BASE_BIT_OPT_SIZE); 6095489c19Sopenharmony_ci random.uuid_[UUID_TIME_HIGH] = 6195489c19Sopenharmony_ci static_cast<uint8_t>((tvUsec & 0xFF00000000000000) >> BIT_OPT_SEVEN_BYTE * BASE_BIT_OPT_SIZE); 6295489c19Sopenharmony_ci random.uuid_[UUID_VERSION] = 6395489c19Sopenharmony_ci static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_sec) + randNum) & 0xFF); 6495489c19Sopenharmony_ci random.uuid_[UUID_TIME_MID_SECEND_BYTE] = 6595489c19Sopenharmony_ci static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_min) + (randNum >> BASE_BIT_OPT_SIZE)) & 0xFF); 6695489c19Sopenharmony_ci random.uuid_[UUID_TIME_MID_FIRST_BYTE] = 6795489c19Sopenharmony_ci static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_hour) + 6895489c19Sopenharmony_ci (randNum >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF); 6995489c19Sopenharmony_ci random.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = 7095489c19Sopenharmony_ci static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_mday) + 7195489c19Sopenharmony_ci (randNum >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF); 7295489c19Sopenharmony_ci random.uuid_[UUID_TIME_LOW_THIRD_BYTE] = 7395489c19Sopenharmony_ci static_cast<uint8_t>(static_cast<unsigned int>(randomTime.tm_mon) & 0xFF); 7495489c19Sopenharmony_ci random.uuid_[UUID_TIME_LOW_SECEND_BYTE] = 7595489c19Sopenharmony_ci static_cast<uint8_t>(static_cast<unsigned int>(randomTime.tm_year) & 0xFF); 7695489c19Sopenharmony_ci random.uuid_[UUID_TIME_LOW_FIRST_BYTE] = 7795489c19Sopenharmony_ci static_cast<uint8_t>((static_cast<unsigned int>(randomTime.tm_year) & 0xFF00) >> BASE_BIT_OPT_SIZE); 7895489c19Sopenharmony_ci 7995489c19Sopenharmony_ci return random; 8095489c19Sopenharmony_ci} 8195489c19Sopenharmony_ci 8295489c19Sopenharmony_ciUuid Uuid::ConvertFromString(const std::string &name) 8395489c19Sopenharmony_ci{ 8495489c19Sopenharmony_ci Uuid ret; 8595489c19Sopenharmony_ci std::string tmp = name; 8695489c19Sopenharmony_ci std::size_t pos = tmp.find("-"); 8795489c19Sopenharmony_ci 8895489c19Sopenharmony_ci while (pos != std::string::npos) { 8995489c19Sopenharmony_ci tmp.replace(pos, 1, ""); 9095489c19Sopenharmony_ci pos = tmp.find("-"); 9195489c19Sopenharmony_ci } 9295489c19Sopenharmony_ci 9395489c19Sopenharmony_ci for (std::size_t i = 0; (i + 1) < tmp.length(); i += SIZE_STRING_TO_INT) { 9495489c19Sopenharmony_ci ret.uuid_[i / SIZE_STRING_TO_INT] = std::stoi(tmp.substr(i, SIZE_STRING_TO_INT), nullptr, UUID128_BYTES_TYPE); 9595489c19Sopenharmony_ci } 9695489c19Sopenharmony_ci 9795489c19Sopenharmony_ci return ret; 9895489c19Sopenharmony_ci} 9995489c19Sopenharmony_ci 10095489c19Sopenharmony_ciUuid Uuid::ConvertFrom16Bits(uint16_t uuid) 10195489c19Sopenharmony_ci{ 10295489c19Sopenharmony_ci Uuid tmp; 10395489c19Sopenharmony_ci tmp.uuid_[UUID_TIME_LOW_THIRD_BYTE] = static_cast<uint8_t>((uuid & 0xFF00) >> BASE_BIT_OPT_SIZE); 10495489c19Sopenharmony_ci tmp.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = static_cast<uint8_t>(uuid & 0x00FF); 10595489c19Sopenharmony_ci return tmp; 10695489c19Sopenharmony_ci} 10795489c19Sopenharmony_ci 10895489c19Sopenharmony_ciUuid Uuid::ConvertFrom32Bits(uint32_t uuid) 10995489c19Sopenharmony_ci{ 11095489c19Sopenharmony_ci Uuid tmp; 11195489c19Sopenharmony_ci tmp.uuid_[UUID_TIME_LOW_FIRST_BYTE] = 11295489c19Sopenharmony_ci static_cast<uint8_t>((uuid & 0xFF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE); 11395489c19Sopenharmony_ci tmp.uuid_[UUID_TIME_LOW_SECEND_BYTE] = 11495489c19Sopenharmony_ci static_cast<uint8_t>((uuid & 0x00FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE); 11595489c19Sopenharmony_ci tmp.uuid_[UUID_TIME_LOW_THIRD_BYTE] = 11695489c19Sopenharmony_ci static_cast<uint8_t>((uuid & 0x0000FF00) >> BASE_BIT_OPT_SIZE); 11795489c19Sopenharmony_ci tmp.uuid_[UUID_TIME_LOW_FOURTH_BYTE] = 11895489c19Sopenharmony_ci static_cast<uint8_t>(uuid & 0x000000FF); 11995489c19Sopenharmony_ci return tmp; 12095489c19Sopenharmony_ci} 12195489c19Sopenharmony_ci 12295489c19Sopenharmony_ciUuid Uuid::ConvertFromBytesLE(const uint8_t *uuid, const size_t size) 12395489c19Sopenharmony_ci{ 12495489c19Sopenharmony_ci Uuid leUuid; 12595489c19Sopenharmony_ci if (size < UUID128_BYTES_TYPE) { 12695489c19Sopenharmony_ci return leUuid; 12795489c19Sopenharmony_ci } 12895489c19Sopenharmony_ci UUID128Bit le; 12995489c19Sopenharmony_ci if (memcpy_s(le.data(), UUID128_BYTES_TYPE, uuid, UUID128_BYTES_TYPE) != EOK) { 13095489c19Sopenharmony_ci return leUuid; 13195489c19Sopenharmony_ci } 13295489c19Sopenharmony_ci std::reverse_copy(le.data(), le.data() + UUID128_BYTES_TYPE, leUuid.uuid_.begin()); 13395489c19Sopenharmony_ci return leUuid; 13495489c19Sopenharmony_ci} 13595489c19Sopenharmony_ci 13695489c19Sopenharmony_ciUuid Uuid::ConvertFromMostAndLeastBit(uint64_t mostSigBits, uint64_t leastSigBits) 13795489c19Sopenharmony_ci{ 13895489c19Sopenharmony_ci Uuid tmp; 13995489c19Sopenharmony_ci int division = UUID128_BYTES_TYPE / SIZE_STRING_TO_INT; 14095489c19Sopenharmony_ci 14195489c19Sopenharmony_ci for (int i = 0; i < division; i++) { 14295489c19Sopenharmony_ci tmp.uuid_[i] = (mostSigBits >> (BASE_BIT_OPT_SIZE * (division - i - 1))) & 0xFF; 14395489c19Sopenharmony_ci } 14495489c19Sopenharmony_ci 14595489c19Sopenharmony_ci for (int i = division; i < UUID128_BYTES_TYPE; i++) { 14695489c19Sopenharmony_ci tmp.uuid_[i] = (leastSigBits >> (BASE_BIT_OPT_SIZE * (2 * division - i - 1))) & 0xFF; // value of division * 2 14795489c19Sopenharmony_ci } 14895489c19Sopenharmony_ci 14995489c19Sopenharmony_ci return tmp; 15095489c19Sopenharmony_ci} 15195489c19Sopenharmony_ci 15295489c19Sopenharmony_ciUuid Uuid::ConvertFrom128Bits(const UUID128Bit &uuid) 15395489c19Sopenharmony_ci{ 15495489c19Sopenharmony_ci Uuid tmp; 15595489c19Sopenharmony_ci tmp.uuid_ = uuid; 15695489c19Sopenharmony_ci return tmp; 15795489c19Sopenharmony_ci} 15895489c19Sopenharmony_ci 15995489c19Sopenharmony_ciuint16_t Uuid::ConvertTo16Bits() const 16095489c19Sopenharmony_ci{ 16195489c19Sopenharmony_ci uint16_t ret = uuid_[UUID_TIME_LOW_THIRD_BYTE] & 0xFF; 16295489c19Sopenharmony_ci ret = (ret << BASE_BIT_OPT_SIZE) + uuid_[UUID_TIME_LOW_FOURTH_BYTE]; 16395489c19Sopenharmony_ci return ret; 16495489c19Sopenharmony_ci} 16595489c19Sopenharmony_ci 16695489c19Sopenharmony_ciuint32_t Uuid::ConvertTo32Bits() const 16795489c19Sopenharmony_ci{ 16895489c19Sopenharmony_ci uint32_t ret = 0; 16995489c19Sopenharmony_ci for (int i = 0; i < UUID32_BYTES_TYPE; i++) { 17095489c19Sopenharmony_ci ret = (ret << BASE_BIT_OPT_SIZE) + uuid_[i]; 17195489c19Sopenharmony_ci } 17295489c19Sopenharmony_ci return ret; 17395489c19Sopenharmony_ci} 17495489c19Sopenharmony_ci 17595489c19Sopenharmony_cibool Uuid::ConvertToBytesLE(uint8_t *value, const size_t size) const 17695489c19Sopenharmony_ci{ 17795489c19Sopenharmony_ci if (size < UUID128_BYTES_TYPE) { 17895489c19Sopenharmony_ci return false; 17995489c19Sopenharmony_ci } 18095489c19Sopenharmony_ci 18195489c19Sopenharmony_ci UUID128Bit le; 18295489c19Sopenharmony_ci std::reverse_copy(uuid_.data(), uuid_.data() + UUID128_BYTES_TYPE, le.begin()); 18395489c19Sopenharmony_ci if (memcpy_s(value, UUID128_BYTES_TYPE, le.data(), UUID128_BYTES_TYPE) != EOK) { 18495489c19Sopenharmony_ci return false; 18595489c19Sopenharmony_ci } 18695489c19Sopenharmony_ci return true; 18795489c19Sopenharmony_ci} 18895489c19Sopenharmony_ci 18995489c19Sopenharmony_ciUuid::UUID128Bit Uuid::ConvertTo128Bits() const 19095489c19Sopenharmony_ci{ 19195489c19Sopenharmony_ci return uuid_; 19295489c19Sopenharmony_ci} 19395489c19Sopenharmony_ci 19495489c19Sopenharmony_ciint Uuid::GetUuidType() const 19595489c19Sopenharmony_ci{ 19695489c19Sopenharmony_ci for (int i = UUID32_BYTES_TYPE; i < UUID128_BYTES_TYPE; i++) { 19795489c19Sopenharmony_ci if (BASE_UUID[i] != uuid_[i]) { 19895489c19Sopenharmony_ci return UUID128_BYTES_TYPE; 19995489c19Sopenharmony_ci } 20095489c19Sopenharmony_ci } 20195489c19Sopenharmony_ci 20295489c19Sopenharmony_ci if ((uuid_[0] == 0) && (uuid_[1] == 0)) { 20395489c19Sopenharmony_ci return UUID16_BYTES_TYPE; 20495489c19Sopenharmony_ci } 20595489c19Sopenharmony_ci 20695489c19Sopenharmony_ci return UUID32_BYTES_TYPE; 20795489c19Sopenharmony_ci} 20895489c19Sopenharmony_ci 20995489c19Sopenharmony_cibool Uuid::operator==(const Uuid &rhs) const 21095489c19Sopenharmony_ci{ 21195489c19Sopenharmony_ci return (uuid_ == rhs.uuid_); 21295489c19Sopenharmony_ci} 21395489c19Sopenharmony_ci 21495489c19Sopenharmony_cibool Uuid::operator!=(const Uuid &rhs) const 21595489c19Sopenharmony_ci{ 21695489c19Sopenharmony_ci return (uuid_ != rhs.uuid_); 21795489c19Sopenharmony_ci} 21895489c19Sopenharmony_ci} // namespace bluetooth 21995489c19Sopenharmony_ci} // namespace OHOS