• 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 #include "napi_bluetooth_host_observer.h"
16 
17 #include "bluetooth_host.h"
18 #include "bluetooth_log.h"
19 #include "bluetooth_utils.h"
20 
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 #include "napi_bluetooth_host.h"
24 
25 #include <uv.h>
26 
27 namespace OHOS {
28 namespace Bluetooth {
UvQueueWorkOnStateChanged(uv_work_t * work,BluetoothState & state)29 void NapiBluetoothHostObserver::UvQueueWorkOnStateChanged(uv_work_t *work, BluetoothState &state)
30 {
31     HILOGI("start");
32 
33     if (work == nullptr) {
34         HILOGE("work is null");
35         return;
36     }
37     auto callbackData = (AfterWorkCallbackData<NapiBluetoothHostObserver,
38         decltype(&NapiBluetoothHostObserver::UvQueueWorkOnStateChanged),
39         BluetoothState> *)work->data;
40     if (callbackData == nullptr) {
41         HILOGE("callbackData is null");
42         return;
43     }
44 
45     napi_value result = 0;
46     napi_value callback = 0;
47     napi_value undefined = 0;
48     napi_value callResult = 0;
49 
50     napi_get_undefined(callbackData->env, &undefined);
51     HILOGD("state is %{public}d", state);
52     napi_create_int32(callbackData->env, static_cast<int32_t>(state), &result);
53     napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
54     napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
55 }
56 
OnStateChanged(const int transport,const int status)57 void NapiBluetoothHostObserver::OnStateChanged(const int transport, const int status)
58 {
59     HILOGD("start");
60     BluetoothState state = BluetoothState::STATE_OFF;
61     if (!DealStateChange(transport, status, state)) {
62         return;
63     }
64     std::shared_ptr<BluetoothCallbackInfo> callbackInfo = GetCallbackInfoByType(REGISTER_STATE_CHANGE_TYPE);
65     if (callbackInfo == nullptr) {
66         HILOGI("This callback is not registered by ability.");
67         return;
68     }
69     uv_loop_s *loop = nullptr;
70     napi_get_uv_event_loop(callbackInfo->env_, &loop);
71     if (loop == nullptr) {
72         HILOGE("loop instance is nullptr");
73         return;
74     }
75 
76     auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothHostObserver,
77         decltype(&NapiBluetoothHostObserver::UvQueueWorkOnStateChanged),
78         BluetoothState>();
79     if (callbackData == nullptr) {
80         HILOGE("new callbackData failed");
81         return;
82     }
83 
84     callbackData->object = this;
85     callbackData->function = &NapiBluetoothHostObserver::UvQueueWorkOnStateChanged;
86     callbackData->env = callbackInfo->env_;
87     callbackData->callback = callbackInfo->callback_;
88     callbackData->data = state;
89 
90     uv_work_t *work = new (std::nothrow) uv_work_t;
91     if (work == nullptr) {
92         HILOGE("new work failed");
93         delete callbackData;
94         callbackData = nullptr;
95         return;
96     }
97     work->data = (void *)callbackData;
98     int ret = uv_queue_work(
99         loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
100     if (ret != 0) {
101         delete callbackData;
102         callbackData = nullptr;
103         delete work;
104         work = nullptr;
105     }
106 }
107 
OnDiscoveryStateChanged(int status)108 void NapiBluetoothHostObserver::OnDiscoveryStateChanged(int status)
109 {
110     switch (status) {
111         case DISCOVERY_STARTED:
112             HILOGD("DISCOVERY_STARTED(1)");
113             break;
114         case DISCOVERYING:
115             HILOGD("DISCOVERYING(2)");
116             break;
117         case DISCOVERY_STOPED:
118             HILOGD("DISCOVERY_STOPED(3)");
119             break;
120         default:
121             HILOGE("invaild status is %{public}d", status);
122             break;
123     }
124 }
125 
UvQueueWorkOnDiscoveryResult(uv_work_t * work,std::shared_ptr<BluetoothRemoteDevice> & device)126 void NapiBluetoothHostObserver::UvQueueWorkOnDiscoveryResult(
127     uv_work_t *work, std::shared_ptr<BluetoothRemoteDevice> &device)
128 {
129     HILOGI("start");
130 
131     if (work == nullptr) {
132         HILOGE("work is null");
133         return;
134     }
135     auto callbackData = (AfterWorkCallbackData<NapiBluetoothHostObserver,
136         decltype(&NapiBluetoothHostObserver::UvQueueWorkOnDiscoveryResult),
137         std::shared_ptr<BluetoothRemoteDevice>> *)work->data;
138     if (callbackData == nullptr) {
139         HILOGE("callbackData is null");
140         return;
141     }
142 
143     napi_value result = 0;
144     napi_value value = 0;
145     napi_value callback = 0;
146     napi_value undefined = 0;
147     napi_value callResult = 0;
148     napi_get_undefined(callbackData->env, &undefined);
149     HILOGD("deviceId is %{public}s", GetEncryptAddr(device->GetDeviceAddr()).c_str());
150     napi_create_array(callbackData->env, &result);
151     napi_create_string_utf8(callbackData->env, device->GetDeviceAddr().c_str(), device->GetDeviceAddr().size(), &value);
152     napi_set_element(callbackData->env, result, 0, value);
153 
154     napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
155     napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
156 }
157 
OnDiscoveryResult(const BluetoothRemoteDevice & device)158 void NapiBluetoothHostObserver::OnDiscoveryResult(const BluetoothRemoteDevice &device)
159 {
160     HILOGI("start");
161     std::shared_ptr<BluetoothCallbackInfo> callbackInfo = GetCallbackInfoByType(REGISTER_DEVICE_FIND_TYPE);
162     if (callbackInfo == nullptr) {
163         HILOGI("This callback is not registered by ability.");
164         return;
165     }
166     uv_loop_s *loop = nullptr;
167     napi_get_uv_event_loop(callbackInfo->env_, &loop);
168     if (loop == nullptr) {
169         HILOGE("loop instance is nullptr");
170         return;
171     }
172 
173     auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothHostObserver,
174         decltype(&NapiBluetoothHostObserver::UvQueueWorkOnDiscoveryResult),
175         std::shared_ptr<BluetoothRemoteDevice>>();
176     if (callbackData == nullptr) {
177         HILOGE("new callbackData failed");
178         return;
179     }
180 
181     callbackData->object = this;
182     callbackData->function = &NapiBluetoothHostObserver::UvQueueWorkOnDiscoveryResult;
183     callbackData->env = callbackInfo->env_;
184     callbackData->callback = callbackInfo->callback_;
185     std::shared_ptr<BluetoothRemoteDevice> remoteDevice = std::make_shared<BluetoothRemoteDevice>(device);
186     callbackData->data = remoteDevice;
187 
188     AddDiscoveryDevice(remoteDevice);
189 
190     uv_work_t *work = new (std::nothrow) uv_work_t;
191     if (work == nullptr) {
192         HILOGE("new work failed");
193         delete callbackData;
194         callbackData = nullptr;
195         return;
196     }
197 
198     work->data = (void *)callbackData;
199 
200     int ret = uv_queue_work(
201         loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
202     if (ret != 0) {
203         delete callbackData;
204         callbackData = nullptr;
205         delete work;
206         work = nullptr;
207     }
208 }
209 
OnPairRequested(const BluetoothRemoteDevice & device)210 void NapiBluetoothHostObserver::OnPairRequested(const BluetoothRemoteDevice &device)
211 {
212     HILOGI("start");
213     BluetoothRemoteDevice remoteDevice;
214     if (device.GetTransportType() == BT_TRANSPORT_BREDR) {
215         remoteDevice = BluetoothHost::GetDefaultHost().GetRemoteDevice(device.GetDeviceAddr(), BT_TRANSPORT_BREDR);
216     } else if (device.GetTransportType() == BT_TRANSPORT_BLE) {
217         remoteDevice = BluetoothHost::GetDefaultHost().GetRemoteDevice(device.GetDeviceAddr(), BT_TRANSPORT_BLE);
218     }
219     remoteDevice.PairRequestReply(true);
220 }
221 
OnPairConfirmed(const BluetoothRemoteDevice & device,int reqType,int number)222 void NapiBluetoothHostObserver::OnPairConfirmed(const BluetoothRemoteDevice &device, int reqType, int number)
223 {
224     std::string remoteAddr = device.GetDeviceAddr();
225     int transportType = device.GetTransportType();
226     HILOGI("remote deviceId is %{public}s, transportType is %{public}d",
227         GetEncryptAddr(remoteAddr).c_str(), transportType);
228     if (transportType == BT_TRANSPORT_BREDR) {
229         DealBredrPairComfirmed(remoteAddr, reqType, number);
230     } else if (transportType == BT_TRANSPORT_BLE) {
231         DealBlePairComfirmed(remoteAddr, reqType, number);
232     }
233 }
234 
OnScanModeChanged(int mode)235 void NapiBluetoothHostObserver::OnScanModeChanged(int mode)
236 {
237     HILOGI("mode is %{public}d", mode);
238 }
239 
OnDeviceNameChanged(const std::string & deviceName)240 void NapiBluetoothHostObserver::OnDeviceNameChanged(const std::string &deviceName)
241 {
242     HILOGI("name is %{public}s", deviceName.c_str());
243 }
244 
OnDeviceAddrChanged(const std::string & address)245 void NapiBluetoothHostObserver::OnDeviceAddrChanged(const std::string &address)
246 {
247     HILOGI("address is %{public}s", GetEncryptAddr(address).c_str());
248 }
249 
EnableBt()250 void NapiBluetoothHostObserver::EnableBt()
251 {
252     HILOGI("start");
253     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
254     bool enabled = host->EnableBt();
255     if (!enabled) {
256         HILOGE("failed");
257     }
258     SetCurrentAppOperate(false);
259 }
260 
DisableBle()261 void NapiBluetoothHostObserver::DisableBle()
262 {
263     HILOGI("start");
264     BluetoothHost *host = &BluetoothHost::GetDefaultHost();
265     bool enabled = host->DisableBle();
266     if (!enabled) {
267         HILOGE("failed");
268     }
269     SetCurrentAppOperate(false);
270 }
271 
DealStateChange(const int transport,const int status,BluetoothState & state)272 bool NapiBluetoothHostObserver::DealStateChange(const int transport, const int status, BluetoothState &state)
273 {
274     HILOGD("transport is %{public}d, status is %{public}d", transport, status);
275     bool isCallback = true;
276     if (transport == BT_TRANSPORT_BREDR) {
277         switch (status) {
278             case BTStateID::STATE_TURNING_ON:
279                 HILOGD("STATE_TURNING_ON(1)");
280                 state = BluetoothState::STATE_TURNING_ON;
281                 break;
282             case BTStateID::STATE_TURN_ON:
283                 HILOGD("STATE_ON(2)");
284                 state = BluetoothState::STATE_ON;
285                 break;
286             case BTStateID::STATE_TURNING_OFF:
287                 HILOGD("STATE_TURNING_OFF(3)");
288                 state = BluetoothState::STATE_TURNING_OFF;
289                 break;
290             case BTStateID::STATE_TURN_OFF: {
291                 HILOGD("STATE_OFF(0)");
292                 isCallback = false;
293                 BluetoothHost *host = &BluetoothHost::GetDefaultHost();
294                 if (host->IsBleEnabled() && GetCurrentAppOperate()) {
295                     DisableBle();
296                 }
297                 break;
298             }
299             default:
300                 break;
301         }
302     } else if (transport == BT_TRANSPORT_BLE) {
303         switch (status) {
304             case BTStateID::STATE_TURNING_ON:
305                 HILOGD("STATE_BLE_TURNING_ON(4)");
306                 state = BluetoothState::STATE_BLE_TURNING_ON;
307                 break;
308             case BTStateID::STATE_TURN_ON:
309                 HILOGD("STATE_BLE_ON(5)");
310                 state = BluetoothState::STATE_BLE_ON;
311                 if (GetCurrentAppOperate()) {
312                     EnableBt();
313                 }
314                 break;
315             case BTStateID::STATE_TURNING_OFF:
316                 HILOGD("STATE_BLE_TURNING_OFF(6)");
317                 state = BluetoothState::STATE_BLE_TURNING_OFF;
318                 break;
319             case BTStateID::STATE_TURN_OFF:
320                 HILOGD("STATE_OFF(0)");
321                 state = BluetoothState::STATE_OFF;
322                 break;
323             default:
324                 break;
325         }
326     }
327     return isCallback;
328 }
329 
DealBredrPairComfirmed(const std::string & addr,const int reqType,const int number)330 void NapiBluetoothHostObserver::DealBredrPairComfirmed(const std::string &addr, const int reqType, const int number)
331 {
332     switch (reqType) {
333         case PAIR_CONFIRM_TYPE_PIN_CODE:
334             HILOGD("PAIR_CONFIRM_TYPE_PIN_CODE(1)");
335             break;
336         case PAIR_CONFIRM_TYPE_PASSKEY_DISPLAY:
337             HILOGD("PAIR_CONFIRM_TYPE_PASSKEY_DISPLAY(2)");
338             OnPairConfirmedCallBack(addr, number);
339             break;
340         case PAIR_CONFIRM_TYPE_PASSKEY_INPUT:
341             HILOGD("PAIR_CONFIRM_TYPE_PASSKEY_INPUT(3)");
342             break;
343         case PAIR_CONFIRM_TYPE_NUMERIC:
344             HILOGD("PAIR_CONFIRM_TYPE_NUMERIC(4)");
345             OnPairConfirmedCallBack(addr, number);
346             break;
347         case PAIR_CONFIRM_TYPE_CONSENT:
348             HILOGD("PAIR_CONFIRM_TYPE_CONSENT(5)");
349             OnPairConfirmedCallBack(addr, number);
350             break;
351         default:
352             HILOGE("Invalid reqType is %{public}d", reqType);
353             break;
354     }
355 }
356 
DealBlePairComfirmed(const std::string & addr,const int reqType,const int number)357 void NapiBluetoothHostObserver::DealBlePairComfirmed(const std::string &addr, const int reqType, const int number)
358 {
359     switch (reqType) {
360         case PAIR_CONFIRM_TYPE_PIN_CODE:
361             HILOGD("PAIR_CONFIRM_TYPE_PIN_CODE(1)");
362             break;
363         case PAIR_CONFIRM_TYPE_PASSKEY_DISPLAY:
364             HILOGD("PAIR_CONFIRM_TYPE_PASSKEY_DISPLAY(2)");
365             break;
366         case PAIR_CONFIRM_TYPE_PASSKEY_INPUT:
367             HILOGD("PAIR_CONFIRM_TYPE_PASSKEY_INPUT(3)");
368             break;
369         case PAIR_CONFIRM_TYPE_NUMERIC:
370             HILOGD("PAIR_CONFIRM_TYPE_NUMERIC(4)");
371             OnPairConfirmedCallBack(addr, number);
372             break;
373         default:
374             HILOGE("Invalid reqType is %{public}d", reqType);
375             break;
376     }
377 }
378 
UvQueueWorkOnPairConfirmedCallBack(uv_work_t * work,std::pair<std::string,int> & data)379 void NapiBluetoothHostObserver::UvQueueWorkOnPairConfirmedCallBack(uv_work_t *work, std::pair<std::string, int> &data)
380 {
381     HILOGI("start");
382     if (work == nullptr) {
383         HILOGE("work is null");
384         return;
385     }
386     auto callbackData = (AfterWorkCallbackData<NapiBluetoothHostObserver,
387         decltype(&NapiBluetoothHostObserver::UvQueueWorkOnPairConfirmedCallBack),
388         std::pair<std::string, int>> *)work->data;
389     if (callbackData == nullptr) {
390         HILOGE("callbackData is null");
391         return;
392     }
393 
394     napi_value result = 0;
395     napi_value callback = 0;
396     napi_value undefined = 0;
397     napi_value callResult = 0;
398     napi_get_undefined(callbackData->env, &undefined);
399     HILOGI("Addr is %{public}s", GetEncryptAddr(deviceAddr).c_str());
400     napi_create_object(callbackData->env, &result);
401     napi_value device = 0;
402     napi_create_string_utf8(
403         callbackData->env, callbackData->data.first.data(), callbackData->data.first.size(), &device);
404     napi_set_named_property(callbackData->env, result, "deviceId", device);
405     napi_value pinCode = 0;
406     napi_create_int32(callbackData->env, callbackData->data.second, &pinCode);
407     napi_set_named_property(callbackData->env, result, "pinCode", pinCode);
408 
409     napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
410     napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
411 }
412 
OnPairConfirmedCallBack(const std::string & deviceAddr,const int number)413 void NapiBluetoothHostObserver::OnPairConfirmedCallBack(const std::string &deviceAddr, const int number)
414 {
415     HILOGI("start");
416     std::shared_ptr<BluetoothCallbackInfo> callbackInfo = GetCallbackInfoByType(REGISTER_PIN_REQUEST_TYPE);
417     if (callbackInfo == nullptr) {
418         HILOGI("This callback is not registered by ability.");
419         return;
420     }
421     uv_loop_s *loop = nullptr;
422     napi_get_uv_event_loop(callbackInfo->env_, &loop);
423     if (loop == nullptr) {
424         HILOGE("loop instance is nullptr");
425         return;
426     }
427 
428     auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothHostObserver,
429         decltype(&NapiBluetoothHostObserver::UvQueueWorkOnPairConfirmedCallBack),
430         std::pair<std::string, int>>();
431     if (callbackData == nullptr) {
432         HILOGE("new callbackData failed");
433         return;
434     }
435 
436     callbackData->object = this;
437     callbackData->function = &NapiBluetoothHostObserver::UvQueueWorkOnPairConfirmedCallBack;
438     callbackData->env = callbackInfo->env_;
439     callbackData->callback = callbackInfo->callback_;
440     callbackData->data = std::pair<std::string, int>(deviceAddr, number);
441 
442     uv_work_t *work = new (std::nothrow) uv_work_t;
443     if (work == nullptr) {
444         HILOGE("new work failed");
445         delete callbackData;
446         callbackData = nullptr;
447         return;
448     }
449 
450     work->data = (void *)callbackData;
451 
452     int ret = uv_queue_work(
453         loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
454     if (ret != 0) {
455         delete callbackData;
456         callbackData = nullptr;
457         delete work;
458         work = nullptr;
459     }
460 }
461 }  // namespace Bluetooth
462 }  // namespace OHOS