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 "ble_properties.h"
17 
18 #include "ble_defs.h"
19 
20 #include "bt_uuid.h"
21 #include "btstack.h"
22 #include "gap_if.h"
23 #include "log.h"
24 #include "raw_address.h"
25 #include "securec.h"
26 
27 namespace OHOS {
28 namespace bluetooth {
29 struct BleProperties::impl {
30     std::string deviceName_{BLE_DEFAULT_DEVICE_NAME};
31     BaseObserverList<IAdapterBleObserver> *observer_ = nullptr;
32     int ioCapability_ = BLE_DEFAULT_IO;
33     std::string passkey_{BLE_DEFAULT_LOCAL_PASSKEY};
34     int bondableMode_ = BLE_BONDABLE_MODE_NONE;
35     std::string macAddr_{BLE_INVALID_MAC_ADDRESS};
36 };
37 
GetInstance()38 BleProperties &BleProperties::GetInstance()
39 {
40     static BleProperties instance;
41     return instance;
42 }
43 
BleProperties()44 BleProperties::BleProperties() : pimpl(std::make_unique<BleProperties::impl>())
45 {}
46 
~BleProperties()47 BleProperties::~BleProperties()
48 {}
49 
GetLocalName() const50 std::string BleProperties::GetLocalName() const
51 {
52     LOG_DEBUG("[BleProperties] %{public}s", __func__);
53 
54     return pimpl->deviceName_;
55 }
56 
GetUTF8StringLength(const char firstByte) const57 int BleProperties::GetUTF8StringLength(const char firstByte) const
58 {
59     int length = UTF8_SINGLE_BYTE_LENGTH;
60     if ((firstByte & 0x80) == 0) {
61         length = UTF8_SINGLE_BYTE_LENGTH;
62     } else if ((firstByte & 0xE0) == 0xC0) {
63         length = UTF8_DOUBLE_BYTE_LENGTH;
64     } else if ((firstByte & 0xF0) == 0xE0) {
65         length = UTF8_TRIPLE_BYTE_LENGTH;
66     } else if ((firstByte & 0xF8) == 0xF0) {
67         length = UTF8_QUADRUPLE_BYTE_LENGTH;
68     }
69     return length;
70 }
71 
GetValidUTF8StringLength(const std::string & name) const72 int BleProperties::GetValidUTF8StringLength(const std::string &name) const
73 {
74     int byteCount = 0;
75     for (int i = 0; i < name.size();) {
76         int utf8Length = GetUTF8StringLength(name[i]);
77         if (byteCount + utf8Length > DEVICE_NAME_MAX_LEN) {
78             break;
79         }
80         byteCount += utf8Length;
81         if (byteCount == DEVICE_NAME_MAX_LEN) {
82             return byteCount;
83         }
84         i += utf8Length;
85     }
86     return byteCount;
87 }
88 
SetLocalName(const std::string & name) const89 bool BleProperties::SetLocalName(const std::string &name) const
90 {
91     LOG_DEBUG("[BleProperties] %{public}s", __func__);
92 
93     int length = name.length();
94     std::string newName = name;
95 
96     if (name.empty()) {
97         return false;
98     }
99 
100     if (length > DEVICE_NAME_MAX_LEN) {
101         length = GetValidUTF8StringLength(name);
102         newName = name.substr(0, length);
103     }
104 
105     pimpl->deviceName_ = BleConfig::GetInstance().GetLocalName();
106     if (newName != pimpl->deviceName_) {
107         pimpl->deviceName_ = newName;
108         int type = BLE_CONFIG_LOCAL_NAME;
109         UpdateConfig(type);
110     }
111     return true;
112 }
113 
GetLocalAddress() const114 std::string BleProperties::GetLocalAddress() const
115 {
116     LOG_DEBUG("[BleProperties] %{public}s", __func__);
117     return pimpl->macAddr_;
118 }
119 
GetBondableMode() const120 int BleProperties::GetBondableMode() const
121 {
122     LOG_DEBUG("[BleProperties] %{public}s", __func__);
123 
124     return pimpl->bondableMode_;
125 }
126 
SetBondableMode(int mode) const127 int BleProperties::SetBondableMode(int mode) const
128 {
129     LOG_DEBUG("[BleProperties] %{public}s", __func__);
130 
131     if (pimpl->bondableMode_ == mode) {
132         return BT_SUCCESS;
133     }
134     switch (mode) {
135         case BLE_BONDABLE_MODE_NONE:
136             pimpl->bondableMode_ = GAP_BONDABLE_MODE_NON;
137             break;
138         case BLE_BONDABLE_MODE_ON:
139             pimpl->bondableMode_ = GAP_BONDABLE_MODE;
140             break;
141         default:
142             pimpl->bondableMode_ = GAP_BONDABLE_MODE_NON;
143             break;
144     }
145     return GAPIF_LeSetBondMode(pimpl->bondableMode_);
146 }
147 
GetPasskey() const148 std::string BleProperties::GetPasskey() const
149 {
150     LOG_DEBUG("[BleProperties] %{public}s", __func__);
151 
152     return pimpl->passkey_;
153 }
154 
GetIoCapability() const155 int BleProperties::GetIoCapability() const
156 {
157     LOG_DEBUG("[BleProperties] %{public}s", __func__);
158 
159     return pimpl->ioCapability_;
160 }
161 
SetIoCapability(int ioCapability) const162 bool BleProperties::SetIoCapability(int ioCapability) const
163 {
164     LOG_DEBUG("[BleProperties] %{public}s", __func__);
165 
166     pimpl->ioCapability_ = ioCapability;
167     return true;
168 }
169 
GetAddrFromController() const170 bool BleProperties::GetAddrFromController() const
171 {
172     LOG_DEBUG("[BleProperties] %{public}s", __func__);
173 
174     BtAddr btAddr;
175     (void)memset_s(&btAddr, sizeof(btAddr), 0x00, sizeof(btAddr));
176     int ret = GAPIF_GetLocalAddr(&btAddr);
177     if (ret != BT_SUCCESS) {
178         LOG_ERROR("BleProperties::GAP_GetLocalAddr Failed");
179         return false;
180     }
181     RawAddress addr = RawAddress::ConvertToString(btAddr.addr);
182     pimpl->macAddr_ = addr.GetAddress();
183     return UpdateConfig(BLE_CONFIG_LOCAL_ADDRESS);
184 }
185 
UpdateConfig(int type) const186 bool BleProperties::UpdateConfig(int type) const
187 {
188     LOG_DEBUG("[BleProperties] %{public}s:Type = %{public}d", __func__, type);
189 
190     bool ret = BT_OPERATION_FAILED;
191     switch (type) {
192         case BLE_CONFIG_LOCAL_NAME:
193             ret = BleConfig::GetInstance().SetLocalName(pimpl->deviceName_);
194             if (pimpl->observer_ != nullptr) {
195                 std::string deviceName = pimpl->deviceName_;
196                 pimpl->observer_->ForEach(
197                     [deviceName](IAdapterBleObserver &observer) { observer.OnDeviceNameChanged(deviceName); });
198             }
199             break;
200         case BLE_CONFIG_LOCAL_ADDRESS:
201             BleConfig::GetInstance().SetLocalAddress(pimpl->macAddr_);
202             ret = BleConfig::GetInstance().SetBleLocalAddrType(BLE_ADDR_TYPE::BLE_ADDR_TYPE_PUBLIC);
203             if (pimpl->observer_ != nullptr) {
204                 std::string macAddr = pimpl->macAddr_;
205                 pimpl->observer_->ForEach(
206                     [macAddr](IAdapterBleObserver &observer) { observer.OnDeviceAddrChanged(macAddr); });
207             }
208             break;
209         default:
210             break;
211     }
212 
213     ret &= BleConfig::GetInstance().Save();
214     return ret;
215 }
216 
LoadBleConfigInfo() const217 bool BleProperties::LoadBleConfigInfo() const
218 {
219     LOG_DEBUG("[BleProperties] %{public}s", __func__);
220 
221     bool ret = BleConfig::GetInstance().LoadConfigInfo();
222     if (!ret) {
223         LOG_ERROR("[BleProperties] %{public}s:%{public}s", __func__, "Load device config file failed!");
224     }
225     ReadBleHostInfo();
226     return ret;
227 }
228 
ConfigBleProperties() const229 bool BleProperties::ConfigBleProperties() const
230 {
231     LOG_DEBUG("[BleProperties] %{public}s", __func__);
232 
233     return SetLocalName(pimpl->deviceName_);
234 }
235 
GetBleRoles()236 int BleProperties::GetBleRoles()
237 {
238     LOG_DEBUG("[BleProperties] %{public}s", __func__);
239 
240     return BleConfig::GetInstance().GetBleRoles();
241 }
242 
SetBleRoles(uint8_t roles)243 bool BleProperties::SetBleRoles(uint8_t roles)
244 {
245     LOG_DEBUG("[BleProperties] %{public}s:%u", __func__, roles);
246     int ret = GAPIF_LeSetRole(roles);
247     if (ret != BT_SUCCESS) {
248         LOG_ERROR("[BleProperties] %{public}s:%{public}s", __func__, "Set ble roles failed!");
249     }
250 
251     return BleConfig::GetInstance().SetBleRoles(roles);
252 }
253 
ReadBleHostInfo() const254 void BleProperties::ReadBleHostInfo() const
255 {
256     LOG_DEBUG("[BleProperties] %{public}s", __func__);
257 
258     pimpl->deviceName_ = BleConfig::GetInstance().GetLocalName();
259     pimpl->ioCapability_ = BleConfig::GetInstance().GetIoCapability();
260     pimpl->passkey_ = BleConfig::GetInstance().GetLoaclPasskey();
261 }
262 
GetAppearance()263 int BleProperties::GetAppearance()
264 {
265     LOG_DEBUG("[BleProperties] %{public}s", __func__);
266 
267     return BleConfig::GetInstance().GetAppearance();
268 }
269 
SetPasskey(const std::string & passkey)270 bool BleProperties::SetPasskey(const std::string &passkey)
271 {
272     LOG_DEBUG("[BleProperties] %{public}s:%{public}s", __func__, passkey.c_str());
273 
274     return BleConfig::GetInstance().SetPasskey(passkey);
275 }
276 
SetBleModel1Level(int level)277 bool BleProperties::SetBleModel1Level(int level)
278 {
279     LOG_DEBUG("[BleProperties] %{public}s:%{public}d", __func__, level);
280 
281     return BleConfig::GetInstance().SetBleModel1Level(level);
282 }
283 
SetBleModel2Level(int level)284 bool BleProperties::SetBleModel2Level(int level)
285 {
286     LOG_DEBUG("[BleProperties] %{public}s:%{public}d", __func__, level);
287 
288     return BleConfig::GetInstance().SetBleModel2Level(level);
289 }
290 
SetBleSecurity(bool security)291 bool BleProperties::SetBleSecurity(bool security)
292 {
293     LOG_DEBUG("[BleProperties] %{public}s:%{public}d", __func__, security);
294 
295     return BleConfig::GetInstance().SetBleSecurity(security);
296 }
297 
SetBleScanMode(int scanmode)298 bool BleProperties::SetBleScanMode(int scanmode)
299 {
300     LOG_DEBUG("[BleProperties] %{public}s:%{public}d", __func__, scanmode);
301 
302     return BleConfig::GetInstance().SetBleScanMode(scanmode);
303 }
304 
SaveDefaultValues() const305 bool BleProperties::SaveDefaultValues() const
306 {
307     LOG_DEBUG("[BleProperties] %{public}s", __func__);
308 
309     bool ret = SetLocalName(BLE_DEFAULT_DEVICE_NAME);
310     ret &= SetIoCapability(BLE_DEFAULT_IO);
311     ret &= SetPasskey(BLE_DEFAULT_LOCAL_PASSKEY);
312     ret &= SetBleRoles(BLE_DEFAULT_ROLES);
313     ret &= SetBleModel1Level(BLE_DEFAULT_MODEL1_LEVEL);
314     ret &= SetBleModel2Level(BLE_DEFAULT_MODEL2_LEVEL);
315     ret &= SetBleSecurity(BLE_DEFAULT_SECURITY);
316     ret &= SetBleScanMode(BLE_DEFAULT_SCAN_MODE);
317     ret &= BleConfig::GetInstance().Save();
318     return ret;
319 }
320 
RegisterBleAdapterObserver(BaseObserverList<IAdapterBleObserver> & observer) const321 void BleProperties::RegisterBleAdapterObserver(BaseObserverList<IAdapterBleObserver> &observer) const
322 {
323     LOG_DEBUG("[BleProperties] %{public}s", __func__);
324 
325     pimpl->observer_ = &observer;
326 }
327 
DeregisterBleAdapterObserver(IAdapterBleObserver & observer) const328 void BleProperties::DeregisterBleAdapterObserver(IAdapterBleObserver &observer) const
329 {
330     LOG_DEBUG("[BleProperties] %{public}s", __func__);
331 
332     pimpl->observer_->Deregister(observer);
333 }
334 }  // namespace bluetooth
335 }  // namespace OHOS
336