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 "ohos_bt_gap.h"
17
18 #include <string.h>
19 #include "__config"
20 #include "bluetooth_def.h"
21 #include "bluetooth_host.h"
22 #include "bluetooth_log.h"
23 #include "bluetooth_remote_device.h"
24 #include "bluetooth_utils.h"
25 #include "iosfwd"
26 #include "ohos_bt_adapter_utils.h"
27 #include "ohos_bt_def.h"
28 #include "string"
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 using namespace std;
35
36 namespace OHOS {
37 namespace Bluetooth {
38 static BluetoothHost *g_BluetoothHost;
39 static BtGapCallBacks *g_GapCallback;
40
41 class BluetoothHostObserverWapper : public BluetoothHostObserver {
42 public:
43 /**
44 * @brief Adapter state change function.
45 *
46 * @param transport Transport type when state change.
47 * BTTransport::ADAPTER_BREDR : classic;
48 * BTTransport::ADAPTER_BLE : ble.
49 * @param state Change to the new state.
50 * BTStateID::STATE_TURNING_ON;
51 * BTStateID::STATE_TURN_ON;
52 * BTStateID::STATE_TURNING_OFF;
53 * BTStateID::STATE_TURN_OFF.
54 * @since 6
55 */
OnStateChanged(const int transport,const int status)56 NO_SANITIZE("cfi") void OnStateChanged(const int transport, const int status) {
57 int cvtTransport = OHOS_BT_TRANSPORT_LE;
58 if (transport == BTTransport::ADAPTER_BREDR) {
59 cvtTransport = OHOS_BT_TRANSPORT_BR_EDR;
60 }
61 HILOGI("transport: %{public}d, status: %{public}d", cvtTransport, status);
62 if (g_GapCallback != nullptr && g_GapCallback->stateChangeCallback != nullptr) {
63 g_GapCallback->stateChangeCallback(cvtTransport, status);
64 } else {
65 HILOGI("callback func is null!");
66 }
67 }
68
69 /**
70 * @brief Discovery state changed observer.
71 *
72 * @param status Device discovery status.
73 * @since 6
74 */
OnDiscoveryStateChanged(int status)75 void OnDiscoveryStateChanged(int status)
76 {
77 (void)status;
78 }
79
80 /**
81 * @brief Discovery result observer.
82 *
83 * @param device Remote device.
84 * @since 6
85 */
OnDiscoveryResult(const BluetoothRemoteDevice & device)86 void OnDiscoveryResult(const BluetoothRemoteDevice &device) {}
87
88 /**
89 * @brief Pair request observer.
90 *
91 * @param device Remote device.
92 * @since 6
93 */
OnPairRequested(const BluetoothRemoteDevice & device)94 NO_SANITIZE("cfi") void OnPairRequested(const BluetoothRemoteDevice &device)
95 {
96 BdAddr remoteAddr;
97 GetAddrFromString(device.GetDeviceAddr(), remoteAddr.addr);
98 int transport = device.GetTransportType();
99 if (transport == BT_TRANSPORT_BREDR) {
100 transport = OHOS_BT_TRANSPORT_BR_EDR;
101 } else if (transport == BT_TRANSPORT_BLE) {
102 transport = OHOS_BT_TRANSPORT_LE;
103 }
104 HILOGI("device: %{public}s, transport:%{public}d", GET_ENCRYPT_ADDR(device), transport);
105 if (g_GapCallback != nullptr && g_GapCallback->pairRequestedCallback != nullptr) {
106 g_GapCallback->pairRequestedCallback(&remoteAddr, transport);
107 } else {
108 HILOGW("callback func is null!");
109 }
110 }
111
112 /**
113 * @brief Pair confirmed observer.
114 *
115 * @param device Remote device.
116 * @param reqType Pair type.
117 * @param number Paired passkey.
118 * @since 6
119 */
OnPairConfirmed(const BluetoothRemoteDevice & device,int reqType,int number)120 NO_SANITIZE("cfi") void OnPairConfirmed(const BluetoothRemoteDevice &device, int reqType, int number)
121 {
122 int transport = device.GetTransportType();
123 HILOGI("reqType: %{public}d, number: %{public}d, transport: %{public}d",
124 reqType, number, transport);
125 BdAddr remoteAddr;
126 GetAddrFromString(device.GetDeviceAddr(), remoteAddr.addr);
127 HILOGI("device: %{public}s", GET_ENCRYPT_ADDR(device));
128 if (g_GapCallback == nullptr || g_GapCallback->pairConfiremedCallback == nullptr) {
129 HILOGW("callback func is null!");
130 return;
131 }
132 if (transport == BT_TRANSPORT_BREDR) {
133 if (reqType == PAIR_CONFIRM_TYPE_NUMERIC || reqType == PAIR_CONFIRM_TYPE_CONSENT) {
134 g_GapCallback->pairConfiremedCallback(&remoteAddr, OHOS_BT_TRANSPORT_BR_EDR, reqType, number);
135 }
136 } else if (transport == BT_TRANSPORT_BLE) {
137 if (reqType == PAIR_CONFIRM_TYPE_NUMERIC) {
138 g_GapCallback->pairConfiremedCallback(&remoteAddr, OHOS_BT_TRANSPORT_LE, reqType, number);
139 }
140 } else {
141 HILOGE("transport: %{public}d is invalid", transport);
142 }
143 };
144
145 /**
146 * @brief Scan mode changed observer.
147 *
148 * @param mode Device scan mode.
149 * @since 6
150 */
OnScanModeChanged(int mode)151 void OnScanModeChanged(int mode)
152 {
153 HILOGI("mode: %{public}d", mode);
154 if (g_GapCallback != nullptr && g_GapCallback->scanModeChangedCallback != nullptr) {
155 g_GapCallback->scanModeChangedCallback(mode);
156 } else {
157 HILOGW("mode: %{public}d, but callback is null!", mode);
158 }
159 };
160
161 /**
162 * @brief Device name changed observer.
163 *
164 * @param deviceName Device name.
165 * @since 6
166 */
OnDeviceNameChanged(const std::string & deviceName)167 void OnDeviceNameChanged(const std::string &deviceName)
168 {
169 (void)deviceName;
170 };
171
172 /**
173 * @brief Device address changed observer.
174 *
175 * @param address Device address.
176 * @since 6
177 */
OnDeviceAddrChanged(const std::string & address)178 void OnDeviceAddrChanged(const std::string &address)
179 {
180 (void)address;
181 };
182 };
183
184 static BluetoothHostObserverWapper g_hostObserver;
185
EnableBle(void)186 bool EnableBle(void)
187 {
188 HILOGI("enter");
189 if (g_BluetoothHost == nullptr) {
190 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
191 }
192
193 if (g_BluetoothHost->IsBleEnabled()) {
194 HILOGI("ble enabled already");
195 return true;
196 }
197 bool isEnabled = false;
198 int32_t ret = g_BluetoothHost->EnableBle();
199 HILOGI("result: %{public}d", ret);
200 if (ret == BT_SUCCESS) {
201 isEnabled = true;
202 }
203 return isEnabled;
204 }
205
DisableBle(void)206 bool DisableBle(void)
207 {
208 HILOGI("enter");
209 if (g_BluetoothHost == nullptr) {
210 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
211 }
212
213 if (!g_BluetoothHost->IsBleEnabled()) {
214 HILOGI("ble disabled already");
215 return true;
216 }
217 bool isEnabled = false;
218 int ret = g_BluetoothHost->DisableBle();
219 HILOGI("result: %{public}d", ret);
220 if (ret == BT_SUCCESS) {
221 isEnabled = true;
222 }
223 return isEnabled;
224 }
225
EnableBt(void)226 bool EnableBt(void)
227 {
228 HILOGI("enter");
229 if (g_BluetoothHost == nullptr) {
230 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
231 }
232
233 int state;
234 g_BluetoothHost->GetBtState(state);
235 if (state == BTStateID::STATE_TURNING_ON ||
236 state == BTStateID::STATE_TURN_ON) {
237 HILOGI("br state is %{public}d", state);
238 return true;
239 }
240 bool isEnabled = false;
241 int ret = g_BluetoothHost->EnableBt();
242 HILOGI("result: %{public}d", ret);
243 if (ret == BT_SUCCESS) {
244 isEnabled = true;
245 }
246 return isEnabled;
247 }
248
DisableBt(void)249 bool DisableBt(void)
250 {
251 HILOGI("enter");
252 if (g_BluetoothHost == nullptr) {
253 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
254 }
255
256 int state;
257 g_BluetoothHost->GetBtState(state);
258 if (state == BTStateID::STATE_TURNING_OFF ||
259 state == BTStateID::STATE_TURN_OFF) {
260 HILOGI("br state is %{public}d", state);
261 return true;
262 }
263 bool ret = g_BluetoothHost->DisableBt();
264 HILOGI("result: %{public}d", ret);
265 return ret;
266 }
267
GetBtState()268 int GetBtState()
269 {
270 HILOGI("enter");
271 if (g_BluetoothHost == nullptr) {
272 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
273 }
274
275 int state;
276 g_BluetoothHost->GetBtState(state);
277 HILOGI("br state: %{public}d", state);
278 return state;
279 }
280
IsBleEnabled()281 bool IsBleEnabled()
282 {
283 if (g_BluetoothHost == nullptr) {
284 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
285 }
286
287 bool ret = g_BluetoothHost->IsBleEnabled();
288 HILOGI("ble enable: %{public}d", ret);
289 return ret;
290 }
291
GetLocalAddr(unsigned char * mac,unsigned int len)292 bool GetLocalAddr(unsigned char *mac, unsigned int len)
293 {
294 HILOGI("enter");
295 if (mac == nullptr || len < OHOS_BD_ADDR_LEN) {
296 HILOGE("invalid param, len:%{public}d", len);
297 return false;
298 }
299 if (g_BluetoothHost == nullptr) {
300 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
301 }
302
303 string localAddress = g_BluetoothHost->GetLocalAddress();
304 GetAddrFromString(localAddress, mac);
305 HILOGI("device: %{public}s", GetEncryptAddr(localAddress).c_str());
306 return true;
307 }
308
SetLocalName(unsigned char * localName,unsigned char length)309 bool SetLocalName(unsigned char *localName, unsigned char length)
310 {
311 HILOGI("enter");
312 if (localName == nullptr) {
313 HILOGE("localName is null");
314 return false;
315 }
316
317 if (g_BluetoothHost == nullptr) {
318 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
319 }
320
321 string newName(reinterpret_cast<const char *>(localName));
322 bool isSuccess = false;
323 int ret = g_BluetoothHost->SetLocalName(newName);
324 if (ret == BT_SUCCESS) {
325 isSuccess = true;
326 }
327 HILOGI("result %{public}d: LocalName : %{public}s", ret, g_BluetoothHost->GetLocalName().c_str());
328 return isSuccess;
329 }
330
SetBtScanMode(int mode,int duration)331 bool SetBtScanMode(int mode, int duration)
332 {
333 HILOGI("mode: %{public}d, duration: %{public}d", mode, duration);
334 if (g_BluetoothHost == nullptr) {
335 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
336 }
337 bool isSuccess = false;
338 int ret = g_BluetoothHost->SetBtScanMode(mode, duration);
339 if (ret == BT_SUCCESS) {
340 isSuccess = true;
341 }
342 g_BluetoothHost->SetBondableMode(BT_TRANSPORT_BREDR, BONDABLE_MODE_ON);
343 return isSuccess;
344 }
345
PairRequestReply(const BdAddr * bdAddr,int transport,bool accept)346 bool PairRequestReply(const BdAddr *bdAddr, int transport, bool accept)
347 {
348 string strAddress;
349 ConvertAddr(bdAddr->addr, strAddress);
350 HILOGI("device: %{public}s", GetEncryptAddr(strAddress).c_str());
351 BluetoothRemoteDevice remoteDevice;
352 if (transport == OHOS_BT_TRANSPORT_BR_EDR) {
353 remoteDevice = g_BluetoothHost->GetRemoteDevice(strAddress, BT_TRANSPORT_BREDR);
354 } else if (transport == OHOS_BT_TRANSPORT_LE) {
355 remoteDevice = g_BluetoothHost->GetRemoteDevice(strAddress, BT_TRANSPORT_BLE);
356 } else {
357 HILOGE("transport: %{public}d is invalid", transport);
358 return false;
359 }
360 bool ret = remoteDevice.PairRequestReply(accept);
361 HILOGI("transport: %{public}d, accept: %{public}d, ret: %{public}d", transport, accept, ret);
362 return ret;
363 }
364
SetDevicePairingConfirmation(const BdAddr * bdAddr,int transport,bool accept)365 bool SetDevicePairingConfirmation(const BdAddr *bdAddr, int transport, bool accept)
366 {
367 string strAddress;
368 ConvertAddr(bdAddr->addr, strAddress);
369 HILOGI("device: %{public}s, accept: %{public}d", GetEncryptAddr(strAddress).c_str(), accept);
370 BluetoothRemoteDevice remoteDevice;
371 if (transport == OHOS_BT_TRANSPORT_BR_EDR) {
372 remoteDevice = g_BluetoothHost->GetRemoteDevice(strAddress, BT_TRANSPORT_BREDR);
373 } else if (transport == OHOS_BT_TRANSPORT_LE) {
374 remoteDevice = g_BluetoothHost->GetRemoteDevice(strAddress, BT_TRANSPORT_BLE);
375 } else {
376 HILOGE("transport: %{public}d is invalid", transport);
377 return false;
378 }
379 bool isSuccess = false;
380 int ret = remoteDevice.SetDevicePairingConfirmation(accept);
381 HILOGI("ret: %{public}d", ret);
382 if (ret == BT_SUCCESS) {
383 isSuccess = true;
384 }
385 return isSuccess;
386 }
387
GapRegisterCallbacks(BtGapCallBacks * func)388 int GapRegisterCallbacks(BtGapCallBacks *func)
389 {
390 HILOGI("enter");
391 if (func == nullptr) {
392 HILOGE("func is null.");
393 return OHOS_BT_STATUS_PARM_INVALID;
394 }
395 if (g_BluetoothHost == nullptr) {
396 g_BluetoothHost = &BluetoothHost::GetDefaultHost();
397 }
398 g_GapCallback = func;
399 g_BluetoothHost->RegisterObserver(g_hostObserver);
400 return OHOS_BT_STATUS_SUCCESS;
401 }
402 } // namespace Bluetooth
403 } // namespace OHOS
404 #ifdef __cplusplus
405 }
406 #endif
407