• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "bluetooth_address.h"
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <hdf_log.h>
22 #include <unistd.h>
23 #include <dlfcn.h>
24 #include "securec.h"
25 
26 namespace OHOS {
27 namespace HDI {
28 namespace Bluetooth {
29 namespace Hci {
30 namespace {
31 constexpr int ADDRESS_STR_LEN = 17;
32 constexpr int ADDRESS_SIZE = 6;
33 }  // namespace
34 
BluetoothAddress()35 BluetoothAddress::BluetoothAddress()
36 {
37     address_.resize(ADDRESS_SIZE);
38 }
39 
40 constexpr int START_POS = 6;
41 constexpr int END_POS = 13;
42 constexpr int ADDR_BYTE = 18;
GetEncryptAddr(std::string addr)43 std::string GetEncryptAddr(std::string addr)
44 {
45     if (addr.empty() || addr.length() != ADDRESS_STR_LEN) {
46         HDF_LOGE("addr is invalid.");
47         return std::string("");
48     }
49     std::string tmp = "**:**:**:**:**:**";
50     std::string out = addr;
51     for (int i = START_POS; i <= END_POS; i++) {
52         out[i] = tmp[i];
53     }
54     return out;
55 }
56 
ParseAddressToString(std::vector<uint8_t> & address,std::string & outString)57 void BluetoothAddress::ParseAddressToString(std::vector<uint8_t> &address, std::string &outString)
58 {
59     char temp[ADDR_BYTE] = {0};
60     int ret = sprintf_s(temp, sizeof(temp), "%02X:%02X:%02X:%02X:%02X:%02X",
61         address[0], address[1], address[2], address[3], address[4], address[5]);
62     if (ret == -1) {
63         HDF_LOGE("ConvertAddr sprintf_s return error, ret -1");
64     }
65     outString = temp;
66 }
67 
ParseAddressFromString(const std::string & string) const68 int BluetoothAddress::ParseAddressFromString(const std::string &string) const
69 {
70     size_t offset = 0;
71     int bytesIndex = 0;
72     int readCount = 0;
73     for (bytesIndex = 0; bytesIndex < ADDRESS_SIZE && offset < string.size(); bytesIndex++) {
74         readCount = 0;
75         if (sscanf_s(&string[offset], "%02hhx:%n", &address_[bytesIndex], &readCount) > 0) {
76             if (readCount == 0 && bytesIndex != ADDRESS_SIZE - 1) {
77                 return bytesIndex;
78             }
79             offset += readCount;
80         } else {
81             break;
82         }
83     }
84 
85     return bytesIndex;
86 }
87 
GetConstantAddress(char * address,int len)88 bool BluetoothAddress::GetConstantAddress(char *address, int len)
89 {
90     if (address == nullptr || len < ADDRESS_STR_LEN + 1) {
91         HDF_LOGE("GetConstantAddress buf error");
92         return false;
93     }
94 
95     void *libMac = dlopen(BT_MAC_LIB, RTLD_LAZY);
96     if (libMac == nullptr) {
97         HDF_LOGI("GetConstantAddress no mac lib ready for dlopen");
98         return false;
99     }
100 
101     using GetMacFun = int (*)(unsigned int, char*, int);
102     GetMacFun getMac = reinterpret_cast<GetMacFun>(dlsym(libMac, GET_BT_MAC_SYMBOL_NAME));
103     if (getMac == nullptr) {
104         HDF_LOGE("GetConstantAddress dlsym error");
105         dlclose(libMac);
106         return false;
107     }
108 
109     int ret = getMac(MAC_TYPE_BLUETOOTH, address, len);
110     HDF_LOGI("GetConstantAddress ret: %{public}d", ret);
111     dlclose(libMac);
112     return (ret == 0);
113 }
114 
GetDeviceAddress(const std::string & path)115 std::shared_ptr<BluetoothAddress> BluetoothAddress::GetDeviceAddress(const std::string &path)
116 {
117     const int bufsize = 256;
118     char buf[bufsize] = {0};
119     int addrFd = open(path.c_str(), O_RDONLY);
120     if (addrFd < 0) {
121         HDF_LOGI("GetDeviceAddress open %{public}s.", path.c_str());
122         int newFd = open(path.c_str(), O_RDWR | O_CREAT, 00644);
123         HDF_LOGI("GetDeviceAddress open newFd %{public}d.", newFd);
124         char addressStr[ADDRESS_STR_LEN + 1] = {"00:11:22:33:44:55"};
125         if (!GetConstantAddress(addressStr, ADDRESS_STR_LEN + 1)) {
126             auto tmpPtr = GenerateDeviceAddress();
127             std::string strAddress;
128             ParseAddressToString(tmpPtr->address_, strAddress);
129             HDF_LOGI("device mac addr: %{public}s", GetEncryptAddr(strAddress).c_str());
130             int ret = strcpy_s(addressStr, ADDRESS_STR_LEN + 1, strAddress.c_str());
131             if (ret != 0) {
132                 HDF_LOGI("ParseAddressToString strcpy_s err!");
133             }
134         }
135 
136         if (newFd >= 0) {
137             int fdRet = write(newFd, addressStr, ADDRESS_STR_LEN);
138             if (fdRet < 0) {
139                 strerror_r(errno, buf, sizeof(buf));
140                 HDF_LOGI("GetDeviceAddress addr write failed, err:%{public}s.", buf);
141             }
142             close(newFd);
143         }
144         auto ptr = std::make_shared<BluetoothAddress>();
145         if (ptr->ParseAddressFromString(addressStr) != ADDRESS_SIZE) {
146             return nullptr;
147         }
148         return ptr;
149     }
150 
151     char addressStr[ADDRESS_STR_LEN + 1] = {0};
152     if (read(addrFd, addressStr, ADDRESS_STR_LEN) != ADDRESS_STR_LEN) {
153         HDF_LOGE("read %{public}s failed.", path.c_str());
154         close(addrFd);
155         return nullptr;
156     }
157     close(addrFd);
158 
159     auto ptr = std::make_shared<BluetoothAddress>();
160     if (ptr->ParseAddressFromString(addressStr) != ADDRESS_SIZE) {
161         return nullptr;
162     }
163 
164     return ptr;
165 }
166 
GenerateDeviceAddress(const std::string & prefix)167 std::shared_ptr<BluetoothAddress> BluetoothAddress::GenerateDeviceAddress(const std::string &prefix)
168 {
169     const int bufsize = 256;
170     char buf[bufsize] = {0};
171     auto ptr = std::make_shared<BluetoothAddress>();
172     char addressStr[ADDRESS_STR_LEN + 1] = {"00:11:22:33:44:55"};
173     ptr->ParseAddressFromString(addressStr);
174     int prefixCount = ptr->ParseAddressFromString(prefix);
175     if (prefixCount < ADDRESS_SIZE) {
176         int fd = open("/dev/urandom", O_RDONLY);
177         if (fd < 0) {
178             strerror_r(errno, buf, sizeof(buf));
179             HDF_LOGE("open /dev/urandom failed err:%{public}s.", buf);
180             return ptr;
181         }
182         if (read(fd, &ptr->address_[prefixCount], ADDRESS_SIZE - prefixCount) != ADDRESS_SIZE - prefixCount) {
183             strerror_r(errno, buf, sizeof(buf));
184             HDF_LOGE("read /dev/urandom failed err:%{public}s.", buf);
185         }
186         close(fd);
187     }
188     return ptr;
189 }
190 
ReadAddress(std::vector<uint8_t> & address) const191 void BluetoothAddress::ReadAddress(std::vector<uint8_t> &address) const
192 {
193     address = address_;
194 }
195 
ReadAddress(std::string & address) const196 void BluetoothAddress::ReadAddress(std::string &address) const
197 {
198     address.resize(ADDRESS_STR_LEN + 1);
199 
200     int offset = 0;
201     for (int ii = 0; ii < ADDRESS_SIZE; ii++) {
202         int ret = snprintf_s(
203             &address[offset], (ADDRESS_STR_LEN + 1) - offset, ADDRESS_STR_LEN - offset, "%02x:", address_[ii]);
204         if (ret < 0) {
205             break;
206         }
207         offset += ret;
208     }
209 }
210 }  // namespace Hci
211 }  // namespace Bluetooth
212 }  // namespace HDI
213 }  // namespace OHOS
214