• 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         int ret = napiBleScanner->GetBleCentralManager()->StartScan(settings, scanFilters);
112         return NapiAsyncWorkRet(ret);
113     };
114 
115     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NEED_CALLBACK);
116     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
117     bool success =
118         napiBleScanner->GetCallback()->asyncWorkMap_.TryPush(NapiAsyncType::BLE_START_SCAN, asyncWork);
119     NAPI_BT_ASSERT_RETURN_UNDEF(env, success, BT_ERR_INTERNAL_ERROR);
120 
121     asyncWork->Run();
122     return asyncWork->GetRet();
123 }
124 
StopScan(napi_env env,napi_callback_info info)125 napi_value NapiBleScanner::StopScan(napi_env env, napi_callback_info info)
126 {
127     HILOGI("enter");
128     auto status = CheckEmptyParam(env, info);
129     NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
130 
131     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
132     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner != nullptr, BT_ERR_INVALID_PARAM);
133     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner->GetBleCentralManager() != nullptr, BT_ERR_INVALID_PARAM);
134     NAPI_BT_ASSERT_RETURN_UNDEF(env, napiBleScanner->GetCallback() != nullptr, BT_ERR_INVALID_PARAM);
135 
136     auto func = [napiBleScanner]() {
137         int ret = napiBleScanner->GetBleCentralManager()->StopScan();
138         return NapiAsyncWorkRet(ret);
139     };
140 
141     auto asyncWork = NapiAsyncWorkFactory::CreateAsyncWork(env, info, func, ASYNC_WORK_NEED_CALLBACK);
142     NAPI_BT_ASSERT_RETURN_UNDEF(env, asyncWork, BT_ERR_INTERNAL_ERROR);
143     bool success =
144         napiBleScanner->GetCallback()->asyncWorkMap_.TryPush(NapiAsyncType::BLE_STOP_SCAN, asyncWork);
145     NAPI_BT_ASSERT_RETURN_UNDEF(env, success, BT_ERR_INTERNAL_ERROR);
146 
147     asyncWork->Run();
148     return asyncWork->GetRet();
149 }
150 
On(napi_env env,napi_callback_info info)151 napi_value NapiBleScanner::On(napi_env env, napi_callback_info info)
152 {
153     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
154     if (napiBleScanner && napiBleScanner->GetCallback()) {
155         auto status = napiBleScanner->GetCallback()->eventSubscribe_.Register(env, info);
156         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
157     }
158     return NapiGetUndefinedRet(env);
159 }
160 
Off(napi_env env,napi_callback_info info)161 napi_value NapiBleScanner::Off(napi_env env, napi_callback_info info)
162 {
163     NapiBleScanner *napiBleScanner = NapiGetBleScanner(env, info);
164     if (napiBleScanner && napiBleScanner->GetCallback()) {
165         auto status = napiBleScanner->GetCallback()->eventSubscribe_.Deregister(env, info);
166         NAPI_BT_ASSERT_RETURN_UNDEF(env, status == napi_ok, BT_ERR_INVALID_PARAM);
167     }
168     return NapiGetUndefinedRet(env);
169 }
170 } // namespace Bluetooth
171 } // namespace OHOS