• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "bt_napi_ble_scanner"
17 #endif
18 
19 #include "napi_bluetooth_ble_scanner.h"
20 #include "bluetooth_log.h"
21 #include "bluetooth_errorcode.h"
22 #include "napi_bluetooth_utils.h"
23 #include "napi_bluetooth_error.h"
24 
25 namespace OHOS {
26 namespace Bluetooth {
27 
28 thread_local napi_ref NapiBleScanner::consRef_ = nullptr;
29 
DefineBleScannerJSClass(napi_env env)30 void NapiBleScanner::DefineBleScannerJSClass(napi_env env)
31 {
32     napi_property_descriptor properties[] = {
33         DECLARE_NAPI_FUNCTION("startScan", StartScan),
34         DECLARE_NAPI_FUNCTION("stopScan", StopScan),
35         DECLARE_NAPI_FUNCTION("on", On),
36         DECLARE_NAPI_FUNCTION("off", Off),
37     };
38 
39     napi_value constructor = nullptr;
40     napi_define_class(env, "BleScanner", NAPI_AUTO_LENGTH, BleScannerConstructor, nullptr,
41         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
42     napi_create_reference(env, constructor, 1, &consRef_);
43 }
44 
BleScannerConstructor(napi_env env,napi_callback_info info)45 napi_value NapiBleScanner::BleScannerConstructor(napi_env env, napi_callback_info info)
46 {
47     napi_value thisVar = nullptr;
48     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
49     NapiBleScanner* bleScanner = new NapiBleScanner();
50 
51     auto status = napi_wrap(
52         env, thisVar, bleScanner,
53         [](napi_env env, void* data, void* hint) {
54             NapiBleScanner* scanner = static_cast<NapiBleScanner*>(data);
55             if (scanner) {
56                 delete scanner;
57                 scanner = nullptr;
58             }
59         },
60         nullptr,
61         nullptr);
62     if (status != napi_ok) {
63         HILOGE("napi_wrap failed");
64         delete bleScanner;
65         bleScanner = nullptr;
66     }
67 
68     return thisVar;
69 }
70 
CreateBleScanner(napi_env env,napi_callback_info info)71 napi_value NapiBleScanner::CreateBleScanner(napi_env env, napi_callback_info info)
72 {
73     HILOGI("enter");
74     napi_value result;
75     napi_value constructor = nullptr;
76     napi_get_reference_value(env, consRef_, &constructor);
77     napi_new_instance(env, constructor, 0, nullptr, &result);
78     return result;
79 }
80 
NapiGetBleScanner(napi_env env,napi_callback_info info)81 static NapiBleScanner *NapiGetBleScanner(napi_env env, napi_callback_info info)
82 {
83     size_t argc = 0;
84     napi_value thisVar = nullptr;
85     if (napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr) != napi_ok) {
86         return nullptr;
87     }
88 
89     NapiBleScanner *bleScanner = nullptr;
90     auto status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&bleScanner));
91     if (status != napi_ok) {
92         return nullptr;
93     }
94     return bleScanner;
95 }
96 
StartScan(napi_env env,napi_callback_info info)97 napi_value NapiBleScanner::StartScan(napi_env env, napi_callback_info info)
98 {
99     HILOGI("enter");
100     std::vector<BleScanFilter> scanFilters;
101     BleScanSettings settings;
102     auto status = CheckBleScanParams(env, info, scanFilters, settings);
103     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
104 
105     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
106     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner != nullptr, BT_ERR_INVALID_PARAM);
107     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner->GetBleCentralManager() != nullptr, BT_ERR_INVALID_PARAM);
108     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner->GetCallback() != nullptr, BT_ERR_INVALID_PARAM);
109 
110     auto func = [napiBleScanner, settings, scanFilters]() {
111         napiBleScanner->GetBleCentralManager()->SetNewApiFlag();
112         int ret = napiBleScanner->GetBleCentralManager()->StartScan(settings, scanFilters);
113         return NapiAsyncWorkRet(ret);
114     };
115 
116     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NEED_CALLBACK);
117     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
118     bool success =
119         napiBleScanner->GetCallback()->asyncWorkMap_.TryPush(NapiAsyncType::BLE_START_SCAN, asyncWork);
120     NAPI_BT_ASSERT_RETURN_UNDEF(env, success, BT_ERR_INTERNAL_ERROR);
121 
122     asyncWork->Run();
123     return asyncWork->GetRet();
124 }
125 
StopScan(napi_env env,napi_callback_info info)126 napi_value NapiBleScanner::StopScan(napi_env env, napi_callback_info info)
127 {
128     HILOGI("enter");
129     auto status = CheckEmptyParam(env, info);
130     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
131 
132     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
133     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner != nullptr, BT_ERR_INVALID_PARAM);
134     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner->GetBleCentralManager() != nullptr, BT_ERR_INVALID_PARAM);
135     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner->GetCallback() != nullptr, BT_ERR_INVALID_PARAM);
136 
137     auto func = [napiBleScanner]() {
138         int ret = napiBleScanner->GetBleCentralManager()->StopScan();
139         return NapiAsyncWorkRet(ret);
140     };
141 
142     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NEED_CALLBACK);
143     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
144     bool success =
145         napiBleScanner->GetCallback()->asyncWorkMap_.TryPush(NapiAsyncType::BLE_STOP_SCAN, asyncWork);
146     NAPI_BT_ASSERT_RETURN_UNDEF(env, success, BT_ERR_INTERNAL_ERROR);
147 
148     asyncWork->Run();
149     return asyncWork->GetRet();
150 }
151 
On(napi_env env,napi_callback_info info)152 napi_value NapiBleScanner::On(napi_env env, napi_callback_info info)
153 {
154     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
155     if (napiBleScanner && napiBleScanner->GetCallback()) {
156         auto status = napiBleScanner->GetCallback()->eventSubscribe_.Register(env, info);
157         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
158     }
159     return NapiGetUndefinedRet(env);
160 }
161 
Off(napi_env env,napi_callback_info info)162 napi_value NapiBleScanner::Off(napi_env env, napi_callback_info info)
163 {
164     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
165     if (napiBleScanner && napiBleScanner->GetCallback()) {
166         auto status = napiBleScanner->GetCallback()->eventSubscribe_.Deregister(env, info);
167         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
168     }
169     return NapiGetUndefinedRet(env);
170 }
171 } // namespace Bluetooth
172 } // namespace OHOS