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