• 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_gatt_server.h"
16 #include "bluetooth_gatt_service.h"
17 #include "bluetooth_host.h"
18 #include "bluetooth_log.h"
19 #include "napi_bluetooth_ble.h"
20 #include "napi_bluetooth_gatt_server.h"
21 #include "napi_bluetooth_utils.h"
22 
23 namespace OHOS {
24 namespace Bluetooth {
25 using namespace std;
26 
27 std::vector<std::string> NapiGattServer::deviceList;
28 thread_local napi_ref NapiGattServer::consRef_ = nullptr;
29 
CreateGattServer(napi_env env,napi_callback_info info)30 napi_value NapiGattServer::CreateGattServer(napi_env env, napi_callback_info info)
31 {
32     HILOGI("CreateGattServer called");
33     napi_value result;
34     napi_value constructor = nullptr;
35     napi_get_reference_value(env, consRef_, &constructor);
36     napi_new_instance(env, constructor, 0, nullptr, &result);
37 
38     HILOGI("CreateGattServer finished");
39     return result;
40 }
41 
DefineGattServerJSClass(napi_env env)42 void NapiGattServer::DefineGattServerJSClass(napi_env env)
43 {
44     napi_property_descriptor gattserverDesc[] = {
45         DECLARE_NAPI_FUNCTION("startAdvertising", StartAdvertising),
46         DECLARE_NAPI_FUNCTION("stopAdvertising", StopAdvertising),
47         DECLARE_NAPI_FUNCTION("addService", AddService),
48         DECLARE_NAPI_FUNCTION("removeService", RemoveGattService),
49         DECLARE_NAPI_FUNCTION("close", Close),
50         DECLARE_NAPI_FUNCTION("notifyCharacteristicChanged", NotifyCharacteristicChanged),
51         DECLARE_NAPI_FUNCTION("sendResponse", SendResponse),
52         DECLARE_NAPI_FUNCTION("on", On),
53         DECLARE_NAPI_FUNCTION("off", Off),
54     };
55 
56     napi_value constructor = nullptr;
57     napi_define_class(env, "GattServer", NAPI_AUTO_LENGTH, GattServerConstructor, nullptr,
58         sizeof(gattserverDesc) / sizeof(gattserverDesc[0]), gattserverDesc, &constructor);
59     napi_create_reference(env, constructor, 1, &consRef_);
60 }
61 
GattServerConstructor(napi_env env,napi_callback_info info)62 napi_value NapiGattServer::GattServerConstructor(napi_env env, napi_callback_info info)
63 {
64     napi_value thisVar = nullptr;
65     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
66     NapiGattServer* gattServer = new NapiGattServer();
67 
68     napi_wrap(
69         env, thisVar, gattServer,
70         [](napi_env env, void* data, void* hint) {
71             NapiGattServer* server = (NapiGattServer*)data;
72             delete server;
73         },
74         nullptr,
75         nullptr);
76 
77     return thisVar;
78 }
79 
On(napi_env env,napi_callback_info info)80 napi_value NapiGattServer::On(napi_env env, napi_callback_info info)
81 {
82     HILOGI("RegisterGattServerCallback called");
83     NapiGattServer *gattServer = nullptr;
84     size_t expectedArgsCount = ARGS_SIZE_TWO;
85     size_t argc = expectedArgsCount;
86     napi_value argv[ARGS_SIZE_TWO] = {0};
87     napi_value thisVar = nullptr;
88 
89     napi_value ret = nullptr;
90     napi_get_undefined(env, &ret);
91 
92     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
93     if (argc != expectedArgsCount) {
94         HILOGE("Requires 2 arguments.");
95         return ret;
96     }
97     string type;
98     ParseString(env, type, argv[PARAM0]);
99     std::shared_ptr<BluetoothCallbackInfo> callbackInfo ;
100 
101     if (type.c_str() == STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_READ ||
102         type.c_str() == STR_BT_GATT_SERVER_CALLBACK_CHARACTERISTIC_WRITE) {
103         callbackInfo = std::make_shared<GattCharacteristicCallbackInfo>();
104     } else if (type.c_str() == STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_WRITE ||
105         type.c_str() == STR_BT_GATT_SERVER_CALLBACK_DESCRIPTOR_READ){
106         callbackInfo = std::make_shared<GattDescriptorCallbackInfo>();
107     } else {
108        callbackInfo = std::make_shared<BluetoothCallbackInfo>();
109     }
110     callbackInfo->env_ = env;
111 
112     napi_unwrap(env, thisVar, (void **)&gattServer);
113     napi_valuetype valueType = napi_undefined;
114     napi_typeof(env, argv[PARAM1], &valueType);
115     if (valueType != napi_function) {
116         HILOGE("Wrong argument type. Function expected.");
117         return ret;
118     }
119     napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
120     gattServer->GetCallback().SetCallbackInfo(type, callbackInfo);
121 
122     HILOGI("%{public}s is registered", type.c_str());
123 
124     return ret;
125 }
126 
Off(napi_env env,napi_callback_info info)127 napi_value NapiGattServer::Off(napi_env env, napi_callback_info info)
128 {
129     HILOGI("DeregisterGattServerCallback called");
130     NapiGattServer *GattServer = nullptr;
131     size_t expectedArgsCount = ARGS_SIZE_ONE;
132     size_t argc = expectedArgsCount;
133     napi_value argv[ARGS_SIZE_ONE] = {0};
134     napi_value thisVar = nullptr;
135 
136     napi_value ret = nullptr;
137     napi_get_undefined(env, &ret);
138 
139     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
140     if (argc != expectedArgsCount) {
141         HILOGE("Requires 1 argument.");
142         return ret;
143     }
144     string type;
145     ParseString(env, type, argv[PARAM0]);
146 
147     napi_unwrap(env, thisVar, (void **)&GattServer);
148     GattServer->GetCallback().SetCallbackInfo(type, nullptr);
149 
150     return ret;
151 }
152 
AddService(napi_env env,napi_callback_info info)153 napi_value NapiGattServer::AddService(napi_env env, napi_callback_info info)
154 {
155     HILOGI("AddService called");
156     NapiGattServer *gattServer = nullptr;
157     size_t expectedArgsCount = ARGS_SIZE_ONE;
158     size_t argc = expectedArgsCount;
159     napi_value argv[ARGS_SIZE_ONE] = {0};
160     napi_value thisVar = nullptr;
161     bool isOK = false;
162     napi_value ret = nullptr;
163     napi_get_boolean(env, isOK, &ret);
164 
165     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
166     if (argc != expectedArgsCount) {
167         HILOGE("Requires 1 argument.");
168         return ret;
169     }
170     GattService* gattService = GetServiceFromJS(env, argv[PARAM0], nullptr, nullptr);
171 
172     napi_unwrap(env, thisVar, (void**)&gattServer);
173     if (gattServer->GetServer()->AddService(*gattService) == GattStatus::GATT_SUCCESS) {
174         isOK = true;
175     }
176     delete gattService;
177 
178     napi_get_boolean(env, isOK, &ret);
179     return ret;
180 }
181 
Close(napi_env env,napi_callback_info info)182 napi_value NapiGattServer::Close(napi_env env, napi_callback_info info)
183 {
184     HILOGI("Close called");
185     NapiGattServer* gattServer = nullptr;
186     bool isOK = true;
187     napi_value thisVar = nullptr;
188 
189     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
190     napi_unwrap(env, thisVar, (void**)&gattServer);
191 
192     delete gattServer;
193 
194     napi_value ret = nullptr;
195     napi_get_boolean(env, isOK, &ret);
196     return ret;
197 }
198 
RemoveGattService(napi_env env,napi_callback_info info)199 napi_value NapiGattServer::RemoveGattService(napi_env env, napi_callback_info info)
200 {
201     HILOGI("RemoveGattService called");
202     NapiGattServer* gattServer = nullptr;
203     size_t expectedArgsCount = ARGS_SIZE_ONE;
204     size_t argc = expectedArgsCount;
205     napi_value argv[ARGS_SIZE_ONE] = {0};
206     napi_value thisVar = nullptr;
207     std::string uuid;
208     bool isOK = false;
209 
210     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
211     NAPI_ASSERT(env, argc == expectedArgsCount, "Requires 1 arguments.");
212     ParseString(env, uuid, argv[PARAM0]);
213 
214     napi_unwrap(env, thisVar, (void**)&gattServer);
215     UUID serviceUuid = UUID::FromString(uuid);
216 
217     std::optional<std::reference_wrapper<GattService>> gattService =
218                                                                 gattServer->GetServer()->GetService(serviceUuid, true);
219     if (gattService != std::nullopt) {
220         if (gattServer->GetServer()->RemoveGattService(*gattService) == GattStatus::GATT_SUCCESS) {
221         isOK = true;
222         }
223     }
224     gattService = gattServer->GetServer()->GetService(serviceUuid, false);
225     if (gattService != std::nullopt) {
226         if (gattServer->GetServer()->RemoveGattService(*gattService) == GattStatus::GATT_SUCCESS) {
227         isOK = true;
228         }
229     }
230 
231     napi_value ret = nullptr;
232     napi_get_boolean(env, isOK, &ret);
233     return ret;
234 }
235 
SendResponse(napi_env env,napi_callback_info info)236 napi_value NapiGattServer::SendResponse(napi_env env, napi_callback_info info)
237 {
238     NapiGattServer* gattServer = nullptr;
239     size_t expectedArgsCount = ARGS_SIZE_ONE;
240     size_t argc = expectedArgsCount;
241     napi_value argv[ARGS_SIZE_ONE] = {0};
242     napi_value thisVar = nullptr;
243     bool isOK = false;
244 
245     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
246     NAPI_ASSERT(env, argc == expectedArgsCount, "Requires 1 arguments.");
247 
248     ServerResponse serverresponse = GetServerResponseFromJS(env, argv[PARAM0]);
249     napi_unwrap(env, thisVar, (void**)&gattServer);
250     BluetoothRemoteDevice remoteDevice =
251         BluetoothHost::GetDefaultHost().GetRemoteDevice(serverresponse.deviceId, 1);
252     if (gattServer->GetServer()->SendResponse(
253         remoteDevice, serverresponse.transId,
254         serverresponse.status,
255         serverresponse.offset,
256         serverresponse.value,
257         serverresponse.length) == GattStatus::GATT_SUCCESS) {
258         isOK = true;
259     }
260 
261     napi_value ret = nullptr;
262     napi_get_boolean(env, isOK, &ret);
263     return ret;
264 }
265 
NotifyCharacteristicChanged(napi_env env,napi_callback_info info)266 napi_value NapiGattServer::NotifyCharacteristicChanged(napi_env env, napi_callback_info info)
267 {
268     HILOGI("NotifyCharacteristicChanged called");
269     NapiGattServer* gattServer = nullptr;
270     size_t expectedArgsCount = ARGS_SIZE_TWO;
271     size_t argc = expectedArgsCount;
272     std::string deviceID;
273     napi_value argv[ARGS_SIZE_TWO] = {0, 0};
274     napi_value thisVar = nullptr;
275     bool isOK = false;
276     napi_value ret = nullptr;
277     napi_get_boolean(env, isOK, &ret);
278 
279     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
280     if (argc != expectedArgsCount) {
281         HILOGE("Requires 2 argument.");
282         return ret;
283     }
284     napi_unwrap(env, thisVar, (void**)&gattServer);
285     ParseString(env, deviceID, argv[PARAM0]);
286     BluetoothRemoteDevice remoteDevice = BluetoothHost::GetDefaultHost().GetRemoteDevice(deviceID, 1);
287     GattCharacteristic* characteristic = GetCharacteristicFromJS(env, argv[PARAM1], gattServer->GetServer(), nullptr);
288 
289     if (characteristic == nullptr) {
290         HILOGI("characteristic is nullptr");
291         return ret;
292     }
293     if (gattServer->GetServer()->NotifyCharacteristicChanged(
294         remoteDevice, *characteristic, true) == GattStatus::GATT_SUCCESS) {
295         isOK = true;
296     }
297 
298     napi_get_boolean(env, isOK, &ret);
299     return ret;
300 }
301 } // namespace Bluetooth
302 } // namespace OHOS
303