• 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_ble_central_manager_callback.h"
16 
17 #include "bluetooth_log.h"
18 #include "napi_bluetooth_utils.h"
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace Bluetooth {
23 namespace {
24 struct SysBLEStartScanCallbackData {
25     napi_env env;
26     napi_ref callbackSuccess = nullptr;
27     napi_ref callbackFail = nullptr;
28     napi_ref callbackComplete = nullptr;
29     int32_t resultCode = 0;
30 };
31 
32 struct SysBLEDeviceFoundCallbackData {
33     napi_env env;
34     napi_ref callbackSuccess = nullptr;
35     napi_ref callbackFail = nullptr;
36     std::shared_ptr<BleScanResult> result;
37 };
ConvertScanResult(const std::vector<BleScanResult> & results,const napi_env & env,napi_value & scanResultArray,bool isSysInterface=false)38 void ConvertScanResult(const std::vector<BleScanResult> &results, const napi_env &env, napi_value &scanResultArray,
39     bool isSysInterface = false)
40 {
41     HILOGI("ConvertScanResult called");
42     napi_create_array(env, &scanResultArray);
43     size_t count = 0;
44     for (auto bleScanResult : results) {
45         napi_value result = nullptr;
46         napi_value value = nullptr;
47         napi_create_object(env, &result);
48         napi_create_string_utf8(
49             env, bleScanResult.GetPeripheralDevice().GetDeviceAddr().c_str(), NAPI_AUTO_LENGTH, &value);
50         std::string propertyName = "deviceId";
51         if (isSysInterface) {
52             propertyName = "addr";
53         }
54         napi_set_named_property(env, result, propertyName.c_str(), value);
55         napi_create_int32(env, bleScanResult.GetRssi(), &value);
56         napi_set_named_property(env, result, "rssi", value);
57         if (isSysInterface) {
58             HILOGI("ConvertScanResult isSysInterface");
59             napi_create_string_utf8(env, "random", NAPI_AUTO_LENGTH, &value);
60             napi_set_named_property(env, result, "addrType", value);
61             napi_create_int32(env, 1, &value);
62             napi_set_named_property(env, result, "txpower", value);
63         }
64         uint8_t *native = nullptr;
65         napi_value buffer = nullptr;
66         napi_create_arraybuffer(env, bleScanResult.GetPayload().size(), reinterpret_cast<void **>(&native), &buffer);
67         if (memcpy_s(native, bleScanResult.GetPayload().size(), bleScanResult.GetPayload().data(),
68             bleScanResult.GetPayload().size()) != EOK) {
69             HILOGE("ConvertScanResult memcpy_s fail");
70             return;
71         }
72         napi_create_typedarray(env, napi_uint8_array, bleScanResult.GetPayload().size(), buffer, 0, &value);
73         napi_set_named_property(env, result, "data", value);
74         napi_set_element(env, scanResultArray, count, result);
75         ++count;
76     }
77 }
78 
AfterWorkCallbackToSysBLEScan(uv_work_t * work,int status)79 void AfterWorkCallbackToSysBLEScan(uv_work_t *work, int status)
80 {
81     if (work == nullptr) {
82         return;
83     }
84 
85     std::unique_ptr<SysBLEStartScanCallbackData> data(static_cast<SysBLEStartScanCallbackData *>(work->data));
86 
87     const napi_env &env = data->env;
88 
89     napi_value funcComplete = nullptr;
90     napi_value callbackResult = nullptr;
91     napi_value undefine = nullptr;
92     napi_get_undefined(env, &undefine);
93     napi_get_reference_value(env, data->callbackComplete, &funcComplete);
94     if (data->resultCode == 0) {
95         napi_value funcSuccess = nullptr;
96         napi_get_reference_value(env, data->callbackSuccess, &funcSuccess);
97         napi_call_function(env, undefine, funcSuccess, 0, nullptr, &callbackResult);
98     } else {
99         napi_value funcFail = nullptr;
100         napi_get_reference_value(env, data->callbackFail, &funcFail);
101         napi_value callbackValue[] {nullptr, nullptr};
102         napi_create_string_utf8(env, "sys startBLEScan fail", NAPI_AUTO_LENGTH, &callbackValue[0]);
103         napi_create_int32(env, data->resultCode, &callbackValue[1]);
104         napi_call_function(env, undefine, funcFail, ARGS_SIZE_TWO, callbackValue, &callbackResult);
105     }
106     napi_call_function(env, undefine, funcComplete, 0, nullptr, &callbackResult);
107 }
108 
AfterWorkCallbackToSysBLEDeviceFound(uv_work_t * work,int status)109 void AfterWorkCallbackToSysBLEDeviceFound(uv_work_t *work, int status)
110 {
111     if (work == nullptr) {
112         return;
113     }
114 
115     std::unique_ptr<SysBLEDeviceFoundCallbackData> data(static_cast<SysBLEDeviceFoundCallbackData *>(work->data));
116     const napi_env &env = data->env;
117 
118     napi_value result = nullptr;
119     std::vector<BleScanResult> scanResults;
120     scanResults.push_back(*(data->result));
121     ConvertScanResult(scanResults, env, result, true);
122 
123     napi_value object = nullptr;
124     napi_create_object(env, &object);
125     napi_set_named_property(env, object, "devices", result);
126     napi_value callbackResult = nullptr;
127     napi_value undefine = nullptr;
128     napi_get_undefined(env, &undefine);
129     napi_value funcSuccess = nullptr;
130     napi_get_reference_value(env, data->callbackSuccess, &funcSuccess);
131     napi_call_function(env, undefine, funcSuccess, ARGS_SIZE_ONE, &object, &callbackResult);
132 }
133 
SysOnScanCallBack(sysBLEMap & observers,const BleScanResult & result)134 void SysOnScanCallBack(sysBLEMap &observers, const BleScanResult &result)
135 {
136     auto callbackInfos = observers[REGISTER_SYS_BLE_FIND_DEVICE_TYPE];
137     uv_loop_s *loop = nullptr;
138     napi_get_uv_event_loop(callbackInfos[PARAM0]->env_, &loop);
139     if (loop == nullptr) {
140         HILOGE("loop instance is nullptr");
141         return;
142     }
143     uv_work_t *work = new (std::nothrow) uv_work_t;
144     if (work == nullptr) {
145         HILOGE("create uv_work_t failed!");
146         return;
147     }
148 
149     SysBLEDeviceFoundCallbackData *data = new (std::nothrow) SysBLEDeviceFoundCallbackData();
150     if (data == nullptr) {
151         HILOGE("create SysBLECallbackData failed!");
152         delete work;
153         return;
154     }
155 
156     data->env = callbackInfos[PARAM0]->env_;
157     data->callbackSuccess = callbackInfos[PARAM0]->callback_;
158     data->callbackFail = callbackInfos[PARAM1]->callback_;
159     data->result = std::make_shared<BleScanResult>(result);
160     work->data = static_cast<void *>(data);
161     uv_queue_work(
162         loop, work, [](uv_work_t *work) {}, AfterWorkCallbackToSysBLEDeviceFound);
163 }
164 } // namespace
165 
UvQueueWorkOnScanCallback(uv_work_t * work,std::shared_ptr<BleScanResult> & result)166 void NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnScanCallback(
167     uv_work_t *work, std::shared_ptr<BleScanResult> &result)
168 {
169     HILOGI("OnScanCallback uv_work_t start");
170 
171     if (work == nullptr) {
172         HILOGE("work is null");
173         return;
174     }
175     auto callbackData = (AfterWorkCallbackData<NapiBluetoothBleCentralManagerCallback,
176         decltype(&NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnScanCallback),
177 	std::shared_ptr<BleScanResult>> *)work->data;
178     if (callbackData == nullptr) {
179         HILOGE("callbackData is null");
180         return;
181     }
182     napi_value napiResult = 0;
183     napi_value callback = 0;
184     napi_value undefined = 0;
185     napi_value callResult = 0;
186     napi_get_undefined(callbackData->env, &undefined);
187     std::vector<BleScanResult> results;
188     results.push_back(*result);
189     ConvertScanResult(results, callbackData->env, napiResult);
190     napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
191     napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &napiResult, &callResult);
192 }
193 
OnScanCallback(const BleScanResult & result)194 void NapiBluetoothBleCentralManagerCallback::OnScanCallback(const BleScanResult &result)
195 {
196     HILOGI("NapiBluetoothBleCentralManagerCallback::OnScanCallback called");
197     auto sysObservers = GetSysBLEObserver();
198     if (sysObservers.find(REGISTER_SYS_BLE_FIND_DEVICE_TYPE) != sysObservers.end()) {
199         SysOnScanCallBack(sysObservers, result);
200     }
201     std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> observers = GetObserver();
202     if (!observers[REGISTER_BLE_FIND_DEVICE_TYPE]) {
203         HILOGE("NapiBluetoothHostObserver::OnStateChanged: This callback is not registered by ability.");
204         return;
205     }
206     HILOGD("NapiBluetoothHostObserver::OnStateChanged: %{public}s is registered by ability",
207         REGISTER_BLE_FIND_DEVICE_TYPE.c_str());
208     std::shared_ptr<BluetoothCallbackInfo> callbackInfo = observers[REGISTER_BLE_FIND_DEVICE_TYPE];
209     uv_loop_s *loop = nullptr;
210     napi_get_uv_event_loop(callbackInfo->env_, &loop);
211     if (loop == nullptr) {
212         HILOGE("loop instance is nullptr");
213         return;
214     }
215 
216     auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothBleCentralManagerCallback,
217         decltype(&NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnScanCallback),
218         std::shared_ptr<BleScanResult>>();
219     if (callbackData == nullptr) {
220         HILOGE("new callbackData failed");
221         return;
222     }
223 
224     callbackData->object = this;
225     callbackData->function = &NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnScanCallback;
226     callbackData->env = callbackInfo->env_;
227     callbackData->callback = callbackInfo->callback_;
228     callbackData->data = std::make_shared<BleScanResult>(result);
229 
230     uv_work_t *work = new (std::nothrow) uv_work_t;
231     if (work == nullptr) {
232         HILOGE("new work failed");
233         delete callbackData;
234         callbackData = nullptr;
235         return;
236     }
237 
238     work->data = (void *)callbackData;
239 
240     int ret = uv_queue_work(
241         loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
242     if (ret != 0) {
243         delete callbackData;
244         callbackData = nullptr;
245         delete work;
246         work = nullptr;
247     }
248 }
249 
UvQueueWorkOnBleBatchScanResultsEvent(uv_work_t * work,const std::vector<BleScanResult> & results)250 void NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnBleBatchScanResultsEvent(
251     uv_work_t *work, const std::vector<BleScanResult> &results)
252 {
253     HILOGI("OnBleBatchScanResultsEvent uv_work_t start");
254 
255     if (work == nullptr) {
256         HILOGE("work is null");
257         return;
258     }
259     auto callbackData = (AfterWorkCallbackData<NapiBluetoothBleCentralManagerCallback,
260         decltype(&NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnBleBatchScanResultsEvent),
261         std::vector<BleScanResult>> *)work->data;
262     if (callbackData == nullptr) {
263         HILOGE("callbackData is null");
264         return;
265     }
266 
267     napi_value result = 0;
268     napi_value callback = 0;
269     napi_value undefined = 0;
270     napi_value callResult = 0;
271     napi_get_undefined(callbackData->env, &undefined);
272     ConvertScanResult(results, callbackData->env, result);
273     napi_get_reference_value(callbackData->env, callbackData->callback, &callback);
274     napi_call_function(callbackData->env, undefined, callback, ARGS_SIZE_ONE, &result, &callResult);
275 }
276 
OnBleBatchScanResultsEvent(const std::vector<BleScanResult> & results)277 void NapiBluetoothBleCentralManagerCallback::OnBleBatchScanResultsEvent(const std::vector<BleScanResult> &results)
278 {
279     HILOGI("NapiBluetoothBleCentralManagerCallback::OnBleBatchScanResultsEvent called");
280     std::map<std::string, std::shared_ptr<BluetoothCallbackInfo>> observers = GetObserver();
281     if (!observers[REGISTER_BLE_FIND_DEVICE_TYPE]) {
282         HILOGE("NapiBluetoothHostObserver::OnStateChanged: This callback is not registered by ability.");
283         return;
284     }
285     HILOGD("NapiBluetoothHostObserver::OnStateChanged: %{public}s is registered by ability",
286         REGISTER_BLE_FIND_DEVICE_TYPE.c_str());
287     std::shared_ptr<BluetoothCallbackInfo> callbackInfo = observers[REGISTER_BLE_FIND_DEVICE_TYPE];
288     uv_loop_s *loop = nullptr;
289     napi_get_uv_event_loop(callbackInfo->env_, &loop);
290     if (loop == nullptr) {
291         HILOGE("loop instance is nullptr");
292         return;
293     }
294 
295     auto callbackData = new (std::nothrow) AfterWorkCallbackData<NapiBluetoothBleCentralManagerCallback,
296         decltype(&NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnBleBatchScanResultsEvent),
297         std::vector<BleScanResult>>();
298     if (callbackData == nullptr) {
299         HILOGE("new callbackData failed");
300         return;
301     }
302 
303     callbackData->object = this;
304     callbackData->function = &NapiBluetoothBleCentralManagerCallback::UvQueueWorkOnBleBatchScanResultsEvent;
305     callbackData->env = callbackInfo->env_;
306     callbackData->callback = callbackInfo->callback_;
307     callbackData->data = results;
308 
309     uv_work_t *work = new (std::nothrow) uv_work_t;
310     if (work == nullptr) {
311         HILOGE("new work failed");
312         delete callbackData;
313         callbackData = nullptr;
314         return;
315     }
316 
317     work->data = (void *)callbackData;
318 
319     int ret = uv_queue_work(
320         loop, work, [](uv_work_t *work) {}, AfterWorkCallback<decltype(callbackData)>);
321     if (ret != 0) {
322         delete callbackData;
323         callbackData = nullptr;
324         delete work;
325         work = nullptr;
326     }
327 }
328 
OnStartScanFailed(int resultCode)329 void NapiBluetoothBleCentralManagerCallback::OnStartScanFailed(int resultCode)
330 {
331     HILOGI("NapiBluetoothBleCentralManagerCallback::OnStartScanFailed called, resultCode is %{public}d", resultCode);
332     auto observers = GetSysBLEObserver();
333     if (observers.find(REGISTER_SYS_BLE_SCAN_TYPE) == observers.end()) {
334         HILOGE("sys BEL callback is not registered by ability.");
335         return;
336     }
337     auto callbackInfos = observers[REGISTER_SYS_BLE_SCAN_TYPE];
338     uv_loop_s *loop = nullptr;
339     napi_get_uv_event_loop(callbackInfos[PARAM0]->env_, &loop);
340     if (loop == nullptr) {
341         HILOGE("loop instance is nullptr");
342         return;
343     }
344     uv_work_t *work = new (std::nothrow) uv_work_t;
345     if (work == nullptr) {
346         HILOGE("create uv_work_t failed!");
347         return;
348     }
349 
350     SysBLEStartScanCallbackData *data = new (std::nothrow) SysBLEStartScanCallbackData();
351     if (data == nullptr) {
352         HILOGE("create SysBLECallbackData failed!");
353         delete work;
354         return;
355     }
356 
357     data->resultCode = resultCode;
358     data->env = callbackInfos[PARAM0]->env_;
359     data->callbackSuccess = callbackInfos[PARAM0]->callback_;
360     data->callbackFail = callbackInfos[PARAM1]->callback_;
361     data->callbackComplete = callbackInfos[PARAM2]->callback_;
362     work->data = static_cast<void *>(data);
363     uv_queue_work(
364         loop, work, [](uv_work_t *work) {}, AfterWorkCallbackToSysBLEScan);
365 }
366 }  // namespace Bluetooth
367 }  // namespace OHOS
368