• 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 "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