• 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 #ifdef LOG_DOMAIN
27 #undef LOG_DOMAIN
28 #endif
29 #define LOG_DOMAIN 0xD000105
30 
31 namespace OHOS {
32 namespace HDI {
33 namespace Bluetooth {
34 namespace Hci {
35 namespace {
36 constexpr int ADDRESS_STR_LEN = 17;
37 constexpr int ADDRESS_SIZE = 6;
38 }  // namespace
39 
BluetoothAddress()40 BluetoothAddress::BluetoothAddress()
41 {
42     address_.resize(ADDRESS_SIZE);
43 }
44 
45 constexpr int START_POS = 6;
46 constexpr int END_POS = 13;
47 constexpr int ADDR_BYTE = 18;
GetEncryptAddr(std::string addr)48 std::string GetEncryptAddr(std::string addr)
49 {
50     if (addr.empty() || addr.length() != ADDRESS_STR_LEN) {
51         HDF_LOGE("addr is invalid.");
52         return std::string("");
53     }
54     std::string tmp = "**:**:**:**:**:**";
55     std::string out = addr;
56     for (int i = START_POS; i <= END_POS; i++) {
57         out[i] = tmp[i];
58     }
59     return out;
60 }
61 
ParseAddressToString(std::vector<uint8_t> & address,std::string & outString)62 void BluetoothAddress::ParseAddressToString(std::vector<uint8_t> &address, std::string &outString)
63 {
64     char temp[ADDR_BYTE] = {0};
65     int ret = sprintf_s(temp, sizeof(temp), "%02X:%02X:%02X:%02X:%02X:%02X",
66         address[0], address[1], address[2], address[3], address[4], address[5]);
67     if (ret == -1) {
68         HDF_LOGE("ConvertAddr sprintf_s return error, ret -1");
69     }
70     outString = temp;
71 }
72 
ParseAddressFromString(const std::string & string) const73 int BluetoothAddress::ParseAddressFromString(const std::string &string) const
74 {
75     size_t offset = 0;
76     int bytesIndex = 0;
77     int readCount = 0;
78     for (bytesIndex = 0; bytesIndex < ADDRESS_SIZE && offset < string.size(); bytesIndex++) {
79         readCount = 0;
80         if (sscanf_s(&string[offset], "%02hhx:%n", &address_[bytesIndex], &readCount) > 0) {
81             if (readCount == 0 && bytesIndex != ADDRESS_SIZE - 1) {
82                 return bytesIndex;
83             }
84             offset += readCount;
85         } else {
86             break;
87         }
88     }
89 
90     return bytesIndex;
91 }
92 
GetConstantAddress(char * address,int len)93 bool BluetoothAddress::GetConstantAddress(char *address, int len)
94 {
95     if (address == nullptr || len < ADDRESS_STR_LEN + 1) {
96         HDF_LOGE("GetConstantAddress buf error");
97         return false;
98     }
99 
100     void *libMac = dlopen(BT_MAC_LIB, RTLD_LAZY);
101     if (libMac == nullptr) {
102         HDF_LOGI("GetConstantAddress no mac lib ready for dlopen");
103         return false;
104     }
105 
106     using GetMacFun = int (*)(unsigned int, char*, int);
107     GetMacFun getMac = reinterpret_cast<GetMacFun>(dlsym(libMac, GET_BT_MAC_SYMBOL_NAME));
108     if (getMac == nullptr) {
109         HDF_LOGE("GetConstantAddress dlsym error");
110         dlclose(libMac);
111         return false;
112     }
113 
114     int ret = getMac(MAC_TYPE_BLUETOOTH, address, len);
115     HDF_LOGI("GetConstantAddress ret: %{public}d", ret);
116     dlclose(libMac);
117     return (ret == 0);
118 }
119 
CheckAddress(char * address)120 bool BluetoothAddress::CheckAddress(char *address)
121 {
122     for (int index = 0; index < ADDRESS_STR_LEN; ++index) {
123         if (address[index] != 0) {
124             return true;
125         }
126     }
127     HDF_LOGI("Check bt address fail, address invailid!");
128     return false;
129 }
130 
131 #ifdef BT_MAC_UPDATE
132 // system boot less 2min, need ReadbtAddress from NV
NeedReloadAddress()133 bool BluetoothAddress::NeedReloadAddress()
134 {
135     const int64_t maxNeedReloadTime = 120000; // 120s
136     constexpr int64_t msPerSecond = 1000;
137     constexpr int64_t nsPerMs = 1000000;
138     struct timespec times = {0};
139     if (clock_gettime(CLOCK_MONOTONIC, &times) < 0) {
140         HDF_LOGE("Failed clock_gettime:%{public}s, needReloadAddress:false", strerror(errno));
141         return false;
142     }
143     int64_t relativeTime = ((times.tv_sec * msPerSecond) + (times.tv_nsec / nsPerMs));
144     HDF_LOGI("relativeTime:%{public}lu", relativeTime);
145     return relativeTime < maxNeedReloadTime;
146 }
147 #endif
148 
GetDeviceAddress(const std::string & path)149 std::shared_ptr<BluetoothAddress> BluetoothAddress::GetDeviceAddress(const std::string &path)
150 {
151 #ifdef BT_MAC_UPDATE
152     if (NeedReloadAddress()) {
153         return GenerateDeviceAddressFile();
154     }
155 #endif
156     int addrFd = open(path.c_str(), O_RDONLY);
157     if (addrFd < 0) {
158         HDF_LOGI("GetDeviceAddress open %{public}s.", path.c_str());
159         auto ptr = GenerateDeviceAddressFile();
160         if (ptr == nullptr) {
161             HDF_LOGE("GenerateDeviceAddressFile fail!");
162             return nullptr;
163         }
164         return ptr;
165     }
166 
167     char addressStr[ADDRESS_STR_LEN + 1] = {0};
168     if (read(addrFd, addressStr, ADDRESS_STR_LEN) != ADDRESS_STR_LEN || !CheckAddress(addressStr)) {
169         HDF_LOGE("read %{public}s failed.", path.c_str());
170         close(addrFd);
171         auto ptr = GenerateDeviceAddressFile();
172         if (ptr == nullptr) {
173             HDF_LOGE("RegenerateDeviceAddressFile fail!");
174             return nullptr;
175         }
176         return ptr;
177     }
178     close(addrFd);
179 
180     auto ptr = std::make_shared<BluetoothAddress>();
181     if (ptr->ParseAddressFromString(addressStr) != ADDRESS_SIZE) {
182         return nullptr;
183     }
184 
185     return ptr;
186 }
187 
GenerateDeviceAddress(const std::string & prefix)188 std::shared_ptr<BluetoothAddress> BluetoothAddress::GenerateDeviceAddress(const std::string &prefix)
189 {
190     const int bufsize = 256;
191     char buf[bufsize] = {0};
192     auto ptr = std::make_shared<BluetoothAddress>();
193     char addressStr[ADDRESS_STR_LEN + 1] = {"00:11:22:33:44:55"};
194     ptr->ParseAddressFromString(addressStr);
195     int prefixCount = ptr->ParseAddressFromString(prefix);
196     if (prefixCount < ADDRESS_SIZE) {
197         int fd = open("/dev/urandom", O_RDONLY);
198         if (fd < 0) {
199             strerror_r(errno, buf, sizeof(buf));
200             HDF_LOGE("open /dev/urandom failed err:%{public}s.", buf);
201             return ptr;
202         }
203         if (read(fd, &ptr->address_[prefixCount], ADDRESS_SIZE - prefixCount) != ADDRESS_SIZE - prefixCount) {
204             strerror_r(errno, buf, sizeof(buf));
205             HDF_LOGE("read /dev/urandom failed err:%{public}s.", buf);
206         }
207         close(fd);
208     }
209     return ptr;
210 }
211 
GenerateDeviceAddressFile(const std::string & path)212 std::shared_ptr<BluetoothAddress> BluetoothAddress::GenerateDeviceAddressFile(const std::string &path)
213 {
214     if (path.compare(BT_DEVICE_ADDRESS_PATH)) {
215         HDF_LOGE("Address file path error.");
216         return nullptr;
217     }
218     const int bufsize = 256;
219     char buf[bufsize] = {0};
220     char addressStr[ADDRESS_STR_LEN + 1] = {"00:11:22:33:44:55"};
221     int newFd = open(path.c_str(), O_RDWR | O_CREAT, 00644);
222     HDF_LOGI("GetDeviceAddress open newFd %{public}d.", newFd);
223 
224     if (!GetConstantAddress(addressStr, ADDRESS_STR_LEN + 1)) {
225         auto tmpPtr = GenerateDeviceAddress();
226         std::string strAddress;
227         ParseAddressToString(tmpPtr->address_, strAddress);
228         HDF_LOGI("device mac addr: %{public}s", GetEncryptAddr(strAddress).c_str());
229         int ret = strcpy_s(addressStr, ADDRESS_STR_LEN + 1, strAddress.c_str());
230         if (ret != 0) {
231             HDF_LOGI("ParseAddressToString strcpy_s err!");
232         }
233     }
234 
235     if (newFd >= 0) {
236         int fdRet = write(newFd, addressStr, ADDRESS_STR_LEN);
237         if (fdRet < 0) {
238             strerror_r(errno, buf, sizeof(buf));
239             HDF_LOGI("GetDeviceAddress addr write failed, err:%{public}s.", buf);
240         }
241         close(newFd);
242     }
243     auto ptr = std::make_shared<BluetoothAddress>();
244     if (ptr->ParseAddressFromString(addressStr) != ADDRESS_SIZE) {
245         return nullptr;
246     }
247     return ptr;
248 }
249 
ReadAddress(std::vector<uint8_t> & address) const250 void BluetoothAddress::ReadAddress(std::vector<uint8_t> &address) const
251 {
252     address = address_;
253 }
254 
ReadAddress(std::string & address) const255 void BluetoothAddress::ReadAddress(std::string &address) const
256 {
257     address.resize(ADDRESS_STR_LEN + 1);
258 
259     int offset = 0;
260     for (int ii = 0; ii < ADDRESS_SIZE; ii++) {
261         int ret = snprintf_s(
262             &address[offset], (ADDRESS_STR_LEN + 1) - offset, ADDRESS_STR_LEN - offset, "%02x:", address_[ii]);
263         if (ret < 0) {
264             break;
265         }
266         offset += ret;
267     }
268 }
269 }  // namespace Hci
270 }  // namespace Bluetooth
271 }  // namespace HDI
272 }  // namespace OHOS
273