1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "bluetooth_address.h" 17094332d3Sopenharmony_ci#include <cerrno> 18094332d3Sopenharmony_ci#include <cstdio> 19094332d3Sopenharmony_ci#include <cstring> 20094332d3Sopenharmony_ci#include <fcntl.h> 21094332d3Sopenharmony_ci#include <hdf_log.h> 22094332d3Sopenharmony_ci#include <unistd.h> 23094332d3Sopenharmony_ci#include <dlfcn.h> 24094332d3Sopenharmony_ci#include "securec.h" 25094332d3Sopenharmony_ci 26094332d3Sopenharmony_ci#ifdef LOG_DOMAIN 27094332d3Sopenharmony_ci#undef LOG_DOMAIN 28094332d3Sopenharmony_ci#endif 29094332d3Sopenharmony_ci#define LOG_DOMAIN 0xD000105 30094332d3Sopenharmony_ci 31094332d3Sopenharmony_cinamespace OHOS { 32094332d3Sopenharmony_cinamespace HDI { 33094332d3Sopenharmony_cinamespace Bluetooth { 34094332d3Sopenharmony_cinamespace Hci { 35094332d3Sopenharmony_cinamespace { 36094332d3Sopenharmony_ciconstexpr int ADDRESS_STR_LEN = 17; 37094332d3Sopenharmony_ciconstexpr int ADDRESS_SIZE = 6; 38094332d3Sopenharmony_ci} // namespace 39094332d3Sopenharmony_ci 40094332d3Sopenharmony_ciBluetoothAddress::BluetoothAddress() 41094332d3Sopenharmony_ci{ 42094332d3Sopenharmony_ci address_.resize(ADDRESS_SIZE); 43094332d3Sopenharmony_ci} 44094332d3Sopenharmony_ci 45094332d3Sopenharmony_ciconstexpr int START_POS = 6; 46094332d3Sopenharmony_ciconstexpr int END_POS = 13; 47094332d3Sopenharmony_ciconstexpr int ADDR_BYTE = 18; 48094332d3Sopenharmony_cistd::string GetEncryptAddr(std::string addr) 49094332d3Sopenharmony_ci{ 50094332d3Sopenharmony_ci if (addr.empty() || addr.length() != ADDRESS_STR_LEN) { 51094332d3Sopenharmony_ci HDF_LOGE("addr is invalid."); 52094332d3Sopenharmony_ci return std::string(""); 53094332d3Sopenharmony_ci } 54094332d3Sopenharmony_ci std::string tmp = "**:**:**:**:**:**"; 55094332d3Sopenharmony_ci std::string out = addr; 56094332d3Sopenharmony_ci for (int i = START_POS; i <= END_POS; i++) { 57094332d3Sopenharmony_ci out[i] = tmp[i]; 58094332d3Sopenharmony_ci } 59094332d3Sopenharmony_ci return out; 60094332d3Sopenharmony_ci} 61094332d3Sopenharmony_ci 62094332d3Sopenharmony_civoid BluetoothAddress::ParseAddressToString(std::vector<uint8_t> &address, std::string &outString) 63094332d3Sopenharmony_ci{ 64094332d3Sopenharmony_ci char temp[ADDR_BYTE] = {0}; 65094332d3Sopenharmony_ci int ret = sprintf_s(temp, sizeof(temp), "%02X:%02X:%02X:%02X:%02X:%02X", 66094332d3Sopenharmony_ci address[0], address[1], address[2], address[3], address[4], address[5]); 67094332d3Sopenharmony_ci if (ret == -1) { 68094332d3Sopenharmony_ci HDF_LOGE("ConvertAddr sprintf_s return error, ret -1"); 69094332d3Sopenharmony_ci } 70094332d3Sopenharmony_ci outString = temp; 71094332d3Sopenharmony_ci} 72094332d3Sopenharmony_ci 73094332d3Sopenharmony_ciint BluetoothAddress::ParseAddressFromString(const std::string &string) const 74094332d3Sopenharmony_ci{ 75094332d3Sopenharmony_ci size_t offset = 0; 76094332d3Sopenharmony_ci int bytesIndex = 0; 77094332d3Sopenharmony_ci int readCount = 0; 78094332d3Sopenharmony_ci for (bytesIndex = 0; bytesIndex < ADDRESS_SIZE && offset < string.size(); bytesIndex++) { 79094332d3Sopenharmony_ci readCount = 0; 80094332d3Sopenharmony_ci if (sscanf_s(&string[offset], "%02hhx:%n", &address_[bytesIndex], &readCount) > 0) { 81094332d3Sopenharmony_ci if (readCount == 0 && bytesIndex != ADDRESS_SIZE - 1) { 82094332d3Sopenharmony_ci return bytesIndex; 83094332d3Sopenharmony_ci } 84094332d3Sopenharmony_ci offset += readCount; 85094332d3Sopenharmony_ci } else { 86094332d3Sopenharmony_ci break; 87094332d3Sopenharmony_ci } 88094332d3Sopenharmony_ci } 89094332d3Sopenharmony_ci 90094332d3Sopenharmony_ci return bytesIndex; 91094332d3Sopenharmony_ci} 92094332d3Sopenharmony_ci 93094332d3Sopenharmony_cibool BluetoothAddress::GetConstantAddress(char *address, int len) 94094332d3Sopenharmony_ci{ 95094332d3Sopenharmony_ci if (address == nullptr || len < ADDRESS_STR_LEN + 1) { 96094332d3Sopenharmony_ci HDF_LOGE("GetConstantAddress buf error"); 97094332d3Sopenharmony_ci return false; 98094332d3Sopenharmony_ci } 99094332d3Sopenharmony_ci 100094332d3Sopenharmony_ci void *libMac = dlopen(BT_MAC_LIB, RTLD_LAZY); 101094332d3Sopenharmony_ci if (libMac == nullptr) { 102094332d3Sopenharmony_ci HDF_LOGI("GetConstantAddress no mac lib ready for dlopen"); 103094332d3Sopenharmony_ci return false; 104094332d3Sopenharmony_ci } 105094332d3Sopenharmony_ci 106094332d3Sopenharmony_ci using GetMacFun = int (*)(unsigned int, char*, int); 107094332d3Sopenharmony_ci GetMacFun getMac = reinterpret_cast<GetMacFun>(dlsym(libMac, GET_BT_MAC_SYMBOL_NAME)); 108094332d3Sopenharmony_ci if (getMac == nullptr) { 109094332d3Sopenharmony_ci HDF_LOGE("GetConstantAddress dlsym error"); 110094332d3Sopenharmony_ci dlclose(libMac); 111094332d3Sopenharmony_ci return false; 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci 114094332d3Sopenharmony_ci int ret = getMac(MAC_TYPE_BLUETOOTH, address, len); 115094332d3Sopenharmony_ci HDF_LOGI("GetConstantAddress ret: %{public}d", ret); 116094332d3Sopenharmony_ci dlclose(libMac); 117094332d3Sopenharmony_ci return (ret == 0); 118094332d3Sopenharmony_ci} 119094332d3Sopenharmony_ci 120094332d3Sopenharmony_cistd::shared_ptr<BluetoothAddress> BluetoothAddress::GetDeviceAddress(const std::string &path) 121094332d3Sopenharmony_ci{ 122094332d3Sopenharmony_ci const int bufsize = 256; 123094332d3Sopenharmony_ci char buf[bufsize] = {0}; 124094332d3Sopenharmony_ci int addrFd = open(path.c_str(), O_RDONLY); 125094332d3Sopenharmony_ci if (addrFd < 0) { 126094332d3Sopenharmony_ci HDF_LOGI("GetDeviceAddress open %{public}s.", path.c_str()); 127094332d3Sopenharmony_ci int newFd = open(path.c_str(), O_RDWR | O_CREAT, 00644); 128094332d3Sopenharmony_ci HDF_LOGI("GetDeviceAddress open newFd %{public}d.", newFd); 129094332d3Sopenharmony_ci char addressStr[ADDRESS_STR_LEN + 1] = {"00:11:22:33:44:55"}; 130094332d3Sopenharmony_ci if (!GetConstantAddress(addressStr, ADDRESS_STR_LEN + 1)) { 131094332d3Sopenharmony_ci auto tmpPtr = GenerateDeviceAddress(); 132094332d3Sopenharmony_ci std::string strAddress; 133094332d3Sopenharmony_ci ParseAddressToString(tmpPtr->address_, strAddress); 134094332d3Sopenharmony_ci HDF_LOGI("device mac addr: %{public}s", GetEncryptAddr(strAddress).c_str()); 135094332d3Sopenharmony_ci int ret = strcpy_s(addressStr, ADDRESS_STR_LEN + 1, strAddress.c_str()); 136094332d3Sopenharmony_ci if (ret != 0) { 137094332d3Sopenharmony_ci HDF_LOGI("ParseAddressToString strcpy_s err!"); 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci } 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ci if (newFd >= 0) { 142094332d3Sopenharmony_ci int fdRet = write(newFd, addressStr, ADDRESS_STR_LEN); 143094332d3Sopenharmony_ci if (fdRet < 0) { 144094332d3Sopenharmony_ci strerror_r(errno, buf, sizeof(buf)); 145094332d3Sopenharmony_ci HDF_LOGI("GetDeviceAddress addr write failed, err:%{public}s.", buf); 146094332d3Sopenharmony_ci } 147094332d3Sopenharmony_ci close(newFd); 148094332d3Sopenharmony_ci } 149094332d3Sopenharmony_ci auto ptr = std::make_shared<BluetoothAddress>(); 150094332d3Sopenharmony_ci if (ptr->ParseAddressFromString(addressStr) != ADDRESS_SIZE) { 151094332d3Sopenharmony_ci return nullptr; 152094332d3Sopenharmony_ci } 153094332d3Sopenharmony_ci return ptr; 154094332d3Sopenharmony_ci } 155094332d3Sopenharmony_ci 156094332d3Sopenharmony_ci char addressStr[ADDRESS_STR_LEN + 1] = {0}; 157094332d3Sopenharmony_ci if (read(addrFd, addressStr, ADDRESS_STR_LEN) != ADDRESS_STR_LEN) { 158094332d3Sopenharmony_ci HDF_LOGE("read %{public}s failed.", path.c_str()); 159094332d3Sopenharmony_ci close(addrFd); 160094332d3Sopenharmony_ci return nullptr; 161094332d3Sopenharmony_ci } 162094332d3Sopenharmony_ci close(addrFd); 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ci auto ptr = std::make_shared<BluetoothAddress>(); 165094332d3Sopenharmony_ci if (ptr->ParseAddressFromString(addressStr) != ADDRESS_SIZE) { 166094332d3Sopenharmony_ci return nullptr; 167094332d3Sopenharmony_ci } 168094332d3Sopenharmony_ci 169094332d3Sopenharmony_ci return ptr; 170094332d3Sopenharmony_ci} 171094332d3Sopenharmony_ci 172094332d3Sopenharmony_cistd::shared_ptr<BluetoothAddress> BluetoothAddress::GenerateDeviceAddress(const std::string &prefix) 173094332d3Sopenharmony_ci{ 174094332d3Sopenharmony_ci const int bufsize = 256; 175094332d3Sopenharmony_ci char buf[bufsize] = {0}; 176094332d3Sopenharmony_ci auto ptr = std::make_shared<BluetoothAddress>(); 177094332d3Sopenharmony_ci char addressStr[ADDRESS_STR_LEN + 1] = {"00:11:22:33:44:55"}; 178094332d3Sopenharmony_ci ptr->ParseAddressFromString(addressStr); 179094332d3Sopenharmony_ci int prefixCount = ptr->ParseAddressFromString(prefix); 180094332d3Sopenharmony_ci if (prefixCount < ADDRESS_SIZE) { 181094332d3Sopenharmony_ci int fd = open("/dev/urandom", O_RDONLY); 182094332d3Sopenharmony_ci if (fd < 0) { 183094332d3Sopenharmony_ci strerror_r(errno, buf, sizeof(buf)); 184094332d3Sopenharmony_ci HDF_LOGE("open /dev/urandom failed err:%{public}s.", buf); 185094332d3Sopenharmony_ci return ptr; 186094332d3Sopenharmony_ci } 187094332d3Sopenharmony_ci if (read(fd, &ptr->address_[prefixCount], ADDRESS_SIZE - prefixCount) != ADDRESS_SIZE - prefixCount) { 188094332d3Sopenharmony_ci strerror_r(errno, buf, sizeof(buf)); 189094332d3Sopenharmony_ci HDF_LOGE("read /dev/urandom failed err:%{public}s.", buf); 190094332d3Sopenharmony_ci } 191094332d3Sopenharmony_ci close(fd); 192094332d3Sopenharmony_ci } 193094332d3Sopenharmony_ci return ptr; 194094332d3Sopenharmony_ci} 195094332d3Sopenharmony_ci 196094332d3Sopenharmony_civoid BluetoothAddress::ReadAddress(std::vector<uint8_t> &address) const 197094332d3Sopenharmony_ci{ 198094332d3Sopenharmony_ci address = address_; 199094332d3Sopenharmony_ci} 200094332d3Sopenharmony_ci 201094332d3Sopenharmony_civoid BluetoothAddress::ReadAddress(std::string &address) const 202094332d3Sopenharmony_ci{ 203094332d3Sopenharmony_ci address.resize(ADDRESS_STR_LEN + 1); 204094332d3Sopenharmony_ci 205094332d3Sopenharmony_ci int offset = 0; 206094332d3Sopenharmony_ci for (int ii = 0; ii < ADDRESS_SIZE; ii++) { 207094332d3Sopenharmony_ci int ret = snprintf_s( 208094332d3Sopenharmony_ci &address[offset], (ADDRESS_STR_LEN + 1) - offset, ADDRESS_STR_LEN - offset, "%02x:", address_[ii]); 209094332d3Sopenharmony_ci if (ret < 0) { 210094332d3Sopenharmony_ci break; 211094332d3Sopenharmony_ci } 212094332d3Sopenharmony_ci offset += ret; 213094332d3Sopenharmony_ci } 214094332d3Sopenharmony_ci} 215094332d3Sopenharmony_ci} // namespace Hci 216094332d3Sopenharmony_ci} // namespace Bluetooth 217094332d3Sopenharmony_ci} // namespace HDI 218094332d3Sopenharmony_ci} // namespace OHOS 219