• 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_client.h"
16 #include <unistd.h>
17 #include "bluetooth_log.h"
18 #include "napi_bluetooth_utils.h"
19 #include "napi_bluetooth_host.h"
20 
21 
22 namespace OHOS {
23 namespace Bluetooth {
24 using namespace std;
25 
26 thread_local napi_ref NapiGattClient::consRef_ = nullptr;
27 
28 
CreateGattClientDevice(napi_env env,napi_callback_info info)29 napi_value NapiGattClient::CreateGattClientDevice(napi_env env, napi_callback_info info)
30 {
31     HILOGI("CreateGattClientDevice called");
32 
33     size_t expectedArgsCount = ARGS_SIZE_ONE;
34     size_t argc = expectedArgsCount;
35     napi_value argv[ARGS_SIZE_ONE] = {0};
36 
37     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
38 
39     NAPI_ASSERT(env, argc == expectedArgsCount, "Requires 1 arguments.");
40 
41     napi_value result;
42     napi_value constructor = nullptr;
43     napi_get_reference_value(env, consRef_, &constructor);
44     napi_new_instance(env, constructor, argc, argv, &result);
45 
46     return result;
47 }
48 
DefineGattClientJSClass(napi_env env)49 void NapiGattClient::DefineGattClientJSClass(napi_env env)
50 {
51     napi_property_descriptor properties[] = {
52         DECLARE_NAPI_FUNCTION("connect", Connect),
53         DECLARE_NAPI_FUNCTION("disconnect", Disconnect),
54         DECLARE_NAPI_FUNCTION("close", Close),
55         DECLARE_NAPI_FUNCTION("getDeviceName", GetDeviceName),
56         DECLARE_NAPI_FUNCTION("getServices", GetServices),
57         DECLARE_NAPI_FUNCTION("readCharacteristicValue", ReadCharacteristicValue),
58         DECLARE_NAPI_FUNCTION("readDescriptorValue", ReadDescriptorValue),
59         DECLARE_NAPI_FUNCTION("writeCharacteristicValue", WriteCharacteristicValue),
60         DECLARE_NAPI_FUNCTION("writeDescriptorValue", WriteDescriptorValue),
61         DECLARE_NAPI_FUNCTION("getRssiValue", GetRssiValue),
62         DECLARE_NAPI_FUNCTION("setBLEMtuSize", SetBLEMtuSize),
63         DECLARE_NAPI_FUNCTION("setNotifyCharacteristicChanged", SetNotifyCharacteristicChanged),
64         DECLARE_NAPI_FUNCTION("on", On),
65         DECLARE_NAPI_FUNCTION("off", Off),
66     };
67 
68     napi_value constructor = nullptr;
69 
70     napi_define_class(env, "GattClientDevice", NAPI_AUTO_LENGTH, GattClientConstructor, nullptr,
71         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
72 
73     napi_create_reference(env, constructor, 1, &consRef_);
74 }
75 
GattClientConstructor(napi_env env,napi_callback_info info)76 napi_value NapiGattClient::GattClientConstructor(napi_env env, napi_callback_info info)
77 {
78     HILOGI("GattClientConstructor called");
79     napi_value thisVar = nullptr;
80 
81     size_t expectedArgsCount = ARGS_SIZE_ONE;
82     size_t argc = expectedArgsCount;
83     napi_value argv[ARGS_SIZE_ONE] = {0};
84 
85     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
86 
87     string deviceId;
88     ParseString(env, deviceId, argv[PARAM0]);
89     SetGattClinetDeviceId(deviceId);
90 
91     NapiGattClient *gattClient = new NapiGattClient(deviceId);
92 
93     napi_wrap(
94         env, thisVar, gattClient,
95         [](napi_env env, void* data, void* hint) {
96             NapiGattClient* client = (NapiGattClient*)data;
97             delete client;
98         },
99         nullptr,
100         nullptr);
101 
102     return thisVar;
103 }
104 
105 
On(napi_env env,napi_callback_info info)106 napi_value NapiGattClient::On(napi_env env, napi_callback_info info)
107 {
108     HILOGI("On called");
109     NapiGattClient* gattClient = nullptr;
110     size_t expectedArgsCount = ARGS_SIZE_TWO;
111     size_t argc = expectedArgsCount;
112     napi_value argv[ARGS_SIZE_TWO] = {0};
113     napi_value thisVar = nullptr;
114 
115     napi_value ret = nullptr;
116     napi_get_undefined(env, &ret);
117 
118     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
119     if (argc != expectedArgsCount) {
120         HILOGE("Requires 2 argument.");
121         return ret;
122     }
123     string type;
124     ParseString(env, type, argv[PARAM0]);
125     std::shared_ptr<BluetoothCallbackInfo> callbackInfo;
126     if (type.c_str() == STR_BT_GATT_CLIENT_CALLBACK_BLE_CHARACTERISTIC_CHANGE) {
127         callbackInfo = std::make_shared<GattCharacteristicCallbackInfo>();
128     } else {
129         callbackInfo = std::make_shared<BluetoothCallbackInfo>();
130     }
131     callbackInfo->env_ = env;
132 
133     napi_unwrap(env, thisVar, (void **)&gattClient);
134     napi_valuetype valueType = napi_undefined;
135     napi_typeof(env, argv[PARAM1], &valueType);
136     if (valueType != napi_function) {
137         HILOGE("Wrong argument type. Function expected.");
138         return ret;
139     }
140     napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
141     gattClient->GetCallback().SetCallbackInfo(type, callbackInfo);
142 
143     HILOGI("%{public}s is registered", type.c_str());
144 
145     return ret;
146 }
147 
Off(napi_env env,napi_callback_info info)148 napi_value NapiGattClient::Off(napi_env env, napi_callback_info info)
149 {
150     HILOGI("Off called");
151     NapiGattClient* gattClient = nullptr;
152     size_t expectedArgsCount = ARGS_SIZE_ONE;
153     size_t argc = expectedArgsCount;
154     napi_value argv[ARGS_SIZE_ONE] = {0};
155     napi_value thisVar = nullptr;
156 
157     napi_value ret = nullptr;
158     napi_get_undefined(env, &ret);
159 
160     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
161     if (argc != expectedArgsCount) {
162         HILOGE("Requires 1 argument.");
163         return ret;
164     }
165 
166     string type;
167     ParseString(env, type, argv[PARAM0]);
168 
169     napi_unwrap(env, thisVar, (void **)&gattClient);
170     gattClient->GetCallback().SetCallbackInfo(type, nullptr);
171 
172     return ret;
173 }
174 
175 
Connect(napi_env env,napi_callback_info info)176 napi_value NapiGattClient::Connect(napi_env env, napi_callback_info info)
177 {
178     HILOGI("Connect called");
179     NapiGattClient *gattClient = nullptr;
180     napi_value thisVar = nullptr;
181     bool isOK = false;
182 
183     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
184     napi_unwrap(env, thisVar, (void **)&gattClient);
185     if (gattClient->GetClient()->Connect(gattClient->GetCallback(), true, GATT_TRANSPORT_TYPE_LE) ==
186         GattStatus::GATT_SUCCESS) {
187         HILOGI("NAPI Connect successfully");
188         isOK = true;
189     }
190 
191     napi_value ret = nullptr;
192     napi_get_boolean(env, isOK, &ret);
193     return ret;
194 }
195 
Disconnect(napi_env env,napi_callback_info info)196 napi_value NapiGattClient::Disconnect(napi_env env, napi_callback_info info)
197 {
198     HILOGI("Disconnect called");
199     NapiGattClient* gattClient = nullptr;
200     napi_value thisVar = nullptr;
201     bool isOK = false;
202 
203     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
204     napi_unwrap(env, thisVar, (void**)&gattClient);
205     if (gattClient->GetClient()->Disconnect() == GattStatus::GATT_SUCCESS) {
206         isOK = true;
207     }
208 
209     napi_value ret = nullptr;
210     napi_get_boolean(env, isOK, &ret);
211     return ret;
212 }
213 
ReadCharacteristicValue(napi_env env,napi_callback_info info)214 napi_value NapiGattClient::ReadCharacteristicValue(napi_env env, napi_callback_info info)
215 {
216     HILOGI("ReadCharacteristicValue called");
217     NapiGattClient *gattClient = nullptr;
218     size_t expectedArgsCount = ARGS_SIZE_TWO;
219     size_t argc = expectedArgsCount;
220     napi_value argv[ARGS_SIZE_TWO] = {0};
221 
222     napi_value thisVar = nullptr;
223     napi_value ret = nullptr;
224     napi_get_undefined(env, &ret);
225 
226     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
227     if (argc != expectedArgsCount && argc != expectedArgsCount - CALLBACK_SIZE) {
228         HILOGE("Requires 1 or 2 arguments.");
229         return ret;
230     }
231 
232     napi_unwrap(env, thisVar, (void**)&gattClient);
233 
234     gattClient->readCharacteristicValueCallbackInfo_ = new ReadCharacteristicValueCallbackInfo();
235     ReadCharacteristicValueCallbackInfo *callbackInfo = gattClient->readCharacteristicValueCallbackInfo_;
236     callbackInfo->env_ = env;
237     callbackInfo->client_ = gattClient->GetClient();
238     callbackInfo->inputCharacteristic_ = GetCharacteristicFromJS(env, argv[PARAM0], nullptr, callbackInfo->client_);
239 
240     napi_value promise = nullptr;
241 
242     if (argc == expectedArgsCount) {
243         // Callback mode
244         HILOGI("readCharacteristicValue callback mode");
245         napi_valuetype valueType = napi_undefined;
246         napi_typeof(env, argv[PARAM1], &valueType);
247         if (valueType != napi_function) {
248             HILOGE("Wrong argument type. Function expected.");
249             return ret;
250         }
251         napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
252         napi_get_undefined(env, &promise);
253     } else {
254         // Promise mode
255         HILOGI("readCharacteristicValue promise mode");
256         napi_create_promise(env, &callbackInfo->deferred_, &promise);
257     }
258 
259     napi_value resource = nullptr;
260     napi_create_string_utf8(env, "readCharacteristicValue", NAPI_AUTO_LENGTH, &resource);
261 
262     napi_create_async_work(
263         env,
264         nullptr,
265         resource,
266         [](napi_env env, void *data) {
267             HILOGI("readCharacteristicValue execute");
268             ReadCharacteristicValueCallbackInfo* callbackInfo = (ReadCharacteristicValueCallbackInfo*)data;
269             callbackInfo->asyncState_ = ASYNC_START;
270             int result = -1;
271             if (callbackInfo->inputCharacteristic_ != nullptr) {
272                 result = callbackInfo->client_->ReadCharacteristic(*(callbackInfo->inputCharacteristic_));
273             }
274 
275             if (result == GattStatus::GATT_SUCCESS) {
276                 callbackInfo->errorCode_ = CODE_SUCCESS;
277                 int tryTime = 100;
278                 while (callbackInfo->asyncState_ == ASYNC_START && tryTime > 0) {
279                     usleep(SLEEP_TIME);
280                     if (callbackInfo->asyncState_ == ASYNC_DONE) {
281                         break;
282                     }
283                     tryTime--;
284                 }
285                 if (callbackInfo->asyncState_ != ASYNC_DONE) {
286                     callbackInfo->errorCode_ = CODE_FAILED;
287                 }
288             } else {
289                 callbackInfo->errorCode_ = CODE_FAILED;
290             }
291         },
292         [](napi_env env, napi_status status, void *data) {
293             HILOGI("readCharacteristicValue execute back");
294             ReadCharacteristicValueCallbackInfo* callbackInfo = (ReadCharacteristicValueCallbackInfo*)data;
295             napi_value result[ARGS_SIZE_TWO] = {0};
296             napi_value callback = 0;
297             napi_value undefined = 0;
298             napi_value callResult = 0;
299             napi_get_undefined(env, &undefined);
300 
301             if (callbackInfo->errorCode_ == CODE_SUCCESS) {
302                 napi_create_object(env, &result[PARAM1]);
303 
304                 ConvertBLECharacteristicToJS(env, result[PARAM1],
305                     const_cast<GattCharacteristic&>(*(callbackInfo->outputCharacteristic_)));
306             } else {
307                 napi_get_undefined(env, &result[PARAM1]);
308             }
309 
310             if (callbackInfo->callback_) {
311                 // Callback mode
312                 result[PARAM0] = GetCallbackErrorValue(callbackInfo->env_, callbackInfo->errorCode_);
313                 napi_get_reference_value(env, callbackInfo->callback_, &callback);
314                 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
315                 napi_delete_reference(env, callbackInfo->callback_);
316             } else {
317                 if (callbackInfo->errorCode_ == CODE_SUCCESS) {
318                 // Promise mode
319                     napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
320                 } else {
321                     napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM1]);
322                 }
323             }
324             napi_delete_async_work(env, callbackInfo->asyncWork_);
325             delete callbackInfo;
326             callbackInfo = nullptr;
327         },
328         (void*)callbackInfo,
329         &callbackInfo->asyncWork_);
330 
331     napi_queue_async_work(env, callbackInfo->asyncWork_);
332 
333     return promise;
334 }
335 
ReadDescriptorValue(napi_env env,napi_callback_info info)336 napi_value NapiGattClient::ReadDescriptorValue(napi_env env, napi_callback_info info)
337 {
338     HILOGI("readDescriptorValue called");
339     NapiGattClient* gattClient = nullptr;
340     size_t expectedArgsCount = ARGS_SIZE_TWO;
341     size_t argc = expectedArgsCount;
342     napi_value argv[ARGS_SIZE_TWO] = {0};
343 
344     napi_value thisVar = nullptr;
345     napi_value ret = nullptr;
346     napi_get_undefined(env, &ret);
347 
348     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
349     if (argc != expectedArgsCount && argc != expectedArgsCount - CALLBACK_SIZE) {
350         HILOGE("Requires 1 or 2 arguments.");
351         return ret;
352     }
353 
354     napi_unwrap(env, thisVar, (void**)&gattClient);
355 
356     gattClient->readDescriptorValueCallbackInfo_ = new ReadDescriptorValueCallbackInfo();
357     ReadDescriptorValueCallbackInfo *callbackInfo = gattClient->readDescriptorValueCallbackInfo_;
358     callbackInfo->env_ = env;
359     callbackInfo->client_ = gattClient->GetClient();
360     callbackInfo->inputDescriptor_ = GetDescriptorFromJS(env, argv[PARAM0], nullptr, gattClient->GetClient());
361 
362     napi_value promise = nullptr;
363 
364     if (argc == expectedArgsCount) {
365         // Callback mode
366         HILOGI("readDescriptorValue callback mode");
367         napi_valuetype valueType = napi_undefined;
368         napi_typeof(env, argv[PARAM1], &valueType);
369         if (valueType != napi_function) {
370             HILOGE("Wrong argument type. Function expected.");
371             return ret;
372         }
373         napi_create_reference(env, argv[PARAM1], 1, &callbackInfo->callback_);
374         napi_get_undefined(env, &promise);
375     } else {
376         // Promise mode
377         HILOGI("readDescriptorValue promise mode");
378         napi_create_promise(env, &callbackInfo->deferred_, &promise);
379     }
380 
381     napi_value resource = nullptr;
382     napi_create_string_utf8(env, "readDescriptorValue", NAPI_AUTO_LENGTH, &resource);
383 
384     napi_create_async_work(
385         env, nullptr, resource,
386         [](napi_env env, void* data) {
387             HILOGI("readDescriptorValue execute");
388             ReadDescriptorValueCallbackInfo* callbackInfo = (ReadDescriptorValueCallbackInfo*)data;
389             callbackInfo->asyncState_ = ASYNC_START;
390             int result = -1;
391             if (callbackInfo->inputDescriptor_ != nullptr) {
392                 result = callbackInfo->client_->ReadDescriptor(*(callbackInfo->inputDescriptor_));
393             }
394 
395             if (result == GattStatus::GATT_SUCCESS) {
396                 callbackInfo->errorCode_ = CODE_SUCCESS;
397                 int tryTime = 100;
398                 while (callbackInfo->asyncState_ == ASYNC_START && tryTime > 0) {
399                     usleep(SLEEP_TIME);
400                     if (callbackInfo->asyncState_ == ASYNC_DONE) {
401                         break;
402                     }
403                     tryTime--;
404                 }
405                 if (callbackInfo->asyncState_ != ASYNC_DONE) {
406                     callbackInfo->errorCode_ = CODE_FAILED;
407                 }
408             } else {
409                 callbackInfo->errorCode_ = CODE_FAILED;
410             }
411         },
412         [](napi_env env, napi_status status, void* data) {
413             HILOGI("readDescriptorValue execute back");
414             ReadDescriptorValueCallbackInfo* callbackInfo = (ReadDescriptorValueCallbackInfo*)data;
415             napi_value result[ARGS_SIZE_TWO] = {0};
416             napi_value callback = 0;
417             napi_value undefined = 0;
418             napi_value callResult = 0;
419             napi_get_undefined(env, &undefined);
420 
421             if (callbackInfo->errorCode_ == CODE_SUCCESS) {
422                 napi_create_object(env, &result[PARAM1]);
423 
424                 ConvertBLEDescriptorToJS(env, result[PARAM1],
425                     const_cast<GattDescriptor&>(*(callbackInfo->outputDescriptor_)));
426             } else {
427                 napi_get_undefined(env, &result[PARAM1]);
428             }
429 
430             if (callbackInfo->callback_) {
431                 // Callback mode
432                 result[PARAM0] = GetCallbackErrorValue(callbackInfo->env_, callbackInfo->errorCode_);
433                 napi_get_reference_value(env, callbackInfo->callback_, &callback);
434                 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
435                 napi_delete_reference(env, callbackInfo->callback_);
436             } else {
437                 if (callbackInfo->errorCode_ == CODE_SUCCESS) {
438                 // Promise mode
439                     napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
440                 } else {
441                     napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM1]);
442                 }
443             }
444             napi_delete_async_work(env, callbackInfo->asyncWork_);
445             delete callbackInfo;
446             callbackInfo = nullptr;
447         },
448         (void*)callbackInfo,
449         &callbackInfo->asyncWork_);
450 
451     napi_queue_async_work(env, callbackInfo->asyncWork_);
452 
453     return promise;
454 }
455 
GetServices(napi_env env,napi_callback_info info)456 napi_value NapiGattClient::GetServices(napi_env env, napi_callback_info info)
457 {
458     HILOGI("getServices called");
459     NapiGattClient* gattClient = nullptr;
460     size_t expectedArgsCount = ARGS_SIZE_ONE;
461     size_t argc = expectedArgsCount;
462     napi_value argv[ARGS_SIZE_ONE] = {0};
463 
464     napi_value thisVar = nullptr;
465     napi_value ret = nullptr;
466     napi_get_undefined(env, &ret);
467 
468     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
469     if (argc != expectedArgsCount && argc != expectedArgsCount - CALLBACK_SIZE) {
470         HILOGE("Requires 0 or 1 arguments.");
471         return ret;
472     }
473 
474     napi_unwrap(env, thisVar, (void**)&gattClient);
475 
476     GetServiceCallbackInfo *callbackInfo = new GetServiceCallbackInfo();
477 
478     callbackInfo->env_ = env;
479     callbackInfo->client_ = gattClient->GetClient();
480 
481     napi_value promise = nullptr;
482 
483     if (argc == expectedArgsCount) {
484         // Callback mode
485         HILOGI("getService callback mode");
486         napi_valuetype valueType = napi_undefined;
487         napi_typeof(env, argv[PARAM0], &valueType);
488         if (valueType != napi_function) {
489             HILOGE("Wrong argument type. Function expected.");
490             delete callbackInfo;
491             callbackInfo = nullptr;
492             return ret;
493         }
494         napi_create_reference(env, argv[PARAM0], 1, &callbackInfo->callback_);
495         napi_get_undefined(env, &promise);
496     } else {
497         // Promise mode
498         HILOGI("getServices promise mode");
499         napi_create_promise(env, &callbackInfo->deferred_, &promise);
500     }
501 
502     napi_value resource = nullptr;
503     napi_create_string_utf8(env, "getServices", NAPI_AUTO_LENGTH, &resource);
504 
505     napi_create_async_work(
506         env, nullptr, resource,
507         [](napi_env env, void* data) {
508             HILOGI("getServices execute");
509             GetServiceCallbackInfo* callbackInfo = (GetServiceCallbackInfo*)data;
510             if (callbackInfo->client_->DiscoverServices() != GattStatus::GATT_SUCCESS) {
511                 callbackInfo->errorCode_ = CODE_FAILED;
512             } else {
513                 callbackInfo->services_ = callbackInfo->client_->GetService();
514                 callbackInfo->errorCode_ = CODE_SUCCESS;
515             }
516         },
517         [](napi_env env, napi_status status, void* data) {
518             HILOGI("getServices execute back");
519             GetServiceCallbackInfo* callbackInfo = (GetServiceCallbackInfo*)data;
520             napi_value result[ARGS_SIZE_TWO] = {0};
521             napi_value callback = 0;
522             napi_value undefined = 0;
523             napi_value callResult = 0;
524             napi_get_undefined(env, &undefined);
525 
526             if (callbackInfo->errorCode_ == CODE_SUCCESS) {
527                 napi_create_array(env, &result[PARAM1]);
528                 ConvertGattServiceVectorToJS(env, result[PARAM1], callbackInfo->services_);
529             } else {
530                 napi_get_undefined(env, &result[PARAM1]);
531             }
532 
533             if (callbackInfo->callback_) {
534                 // Callback mode
535                 result[PARAM0] = GetCallbackErrorValue(callbackInfo->env_, callbackInfo->errorCode_);
536                 napi_get_reference_value(env, callbackInfo->callback_, &callback);
537                 napi_call_function(env, undefined, callback, ARGS_SIZE_TWO, result, &callResult);
538                 napi_delete_reference(env, callbackInfo->callback_);
539             } else {
540                 if (callbackInfo->errorCode_ == CODE_SUCCESS) {
541                 // Promise mode
542                     napi_resolve_deferred(env, callbackInfo->deferred_, result[PARAM1]);
543                 } else {
544                     napi_reject_deferred(env, callbackInfo->deferred_, result[PARAM1]);
545                 }
546             }
547             napi_delete_async_work(env, callbackInfo->asyncWork_);
548             delete callbackInfo;
549             callbackInfo = nullptr;
550         },
551         (void *)callbackInfo,
552         &callbackInfo->asyncWork_);
553 
554     napi_queue_async_work(env, callbackInfo->asyncWork_);
555 
556     return promise;
557 }
558 
Close(napi_env env,napi_callback_info info)559 napi_value NapiGattClient::Close(napi_env env, napi_callback_info info)
560 {
561     HILOGI("Close called");
562     NapiGattClient* gattClient = nullptr;
563     bool isOK = true;
564     napi_value thisVar = nullptr;
565 
566     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
567     napi_unwrap(env, thisVar, (void**)&gattClient);
568 
569     delete gattClient;
570 
571     napi_value ret = nullptr;
572     napi_get_boolean(env, isOK, &ret);
573     return ret;
574 }
575 
WriteCharacteristicValue(napi_env env,napi_callback_info info)576 napi_value NapiGattClient::WriteCharacteristicValue(napi_env env, napi_callback_info info)
577 {
578     HILOGI("WriteCharacteristicValue called");
579     NapiGattClient* gattClient = nullptr;
580 
581     size_t expectedArgsCount = ARGS_SIZE_ONE;
582     size_t argc = expectedArgsCount;
583     napi_value argv[ARGS_SIZE_ONE] = {0};
584     napi_value ret = nullptr;
585 
586     napi_value thisVar = nullptr;
587     bool isOK = false;
588 
589     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
590     if (argc != expectedArgsCount) {
591         HILOGE("Requires 1 argument.");
592         return ret;
593     }
594 
595     napi_unwrap(env, thisVar, (void**)&gattClient);
596 
597     GattCharacteristic* characteristic = GetCharacteristicFromJS(env, argv[PARAM0], nullptr, gattClient->GetClient());
598     if (characteristic != nullptr) {
599         int ret = gattClient->GetClient()->WriteCharacteristic(*characteristic);
600         if (ret == GattStatus::GATT_SUCCESS) {
601             isOK = true;
602         }
603     }
604 
605     napi_get_boolean(env, isOK, &ret);
606     return ret;
607 }
608 
WriteDescriptorValue(napi_env env,napi_callback_info info)609 napi_value NapiGattClient::WriteDescriptorValue(napi_env env, napi_callback_info info)
610 {
611     HILOGI("WriteDescriptorValue called");
612     NapiGattClient* gattClient = nullptr;
613 
614     size_t expectedArgsCount = ARGS_SIZE_ONE;
615     size_t argc = expectedArgsCount;
616     napi_value argv[ARGS_SIZE_ONE] = {0};
617     napi_value ret = nullptr;
618 
619     napi_value thisVar = nullptr;
620     bool isOK = false;
621 
622     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
623     if (argc != expectedArgsCount) {
624         HILOGE("Requires 1 argument.");
625         return ret;
626     }
627 
628     napi_unwrap(env, thisVar, (void**)&gattClient);
629 
630     GattDescriptor* descriptor = GetDescriptorFromJS(env, argv[PARAM0], nullptr, gattClient->GetClient());
631     if (descriptor != nullptr) {
632         int ret = gattClient->GetClient()->WriteDescriptor(*descriptor);
633         if (ret == GattStatus::GATT_SUCCESS) {
634             isOK = true;
635         }
636     }
637 
638     napi_get_boolean(env, isOK, &ret);
639     return ret;
640 }
641 
SetBLEMtuSize(napi_env env,napi_callback_info info)642 napi_value NapiGattClient::SetBLEMtuSize(napi_env env, napi_callback_info info)
643 {
644     HILOGI("SetBLEMtuSize called");
645     NapiGattClient* gattClient = nullptr;
646 
647     size_t expectedArgsCount = ARGS_SIZE_ONE;
648     size_t argc = expectedArgsCount;
649     napi_value argv[ARGS_SIZE_ONE] = {0};
650     napi_value ret = nullptr;
651 
652     napi_value thisVar = nullptr;
653     bool isOK = false;
654 
655     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
656     if (argc != expectedArgsCount) {
657         HILOGE("Requires 1 argument.");
658         return ret;
659     }
660 
661     napi_unwrap(env, thisVar, (void**)&gattClient);
662 
663     int32_t mtuSize;
664     ParseInt32(env, mtuSize, argv[PARAM0]);
665 
666     if (gattClient->GetClient()->RequestBleMtuSize(mtuSize) == GattStatus::GATT_SUCCESS) {
667         isOK = true;
668     }
669 
670     napi_get_boolean(env, isOK, &ret);
671     return ret;
672 }
673 
SetNotifyCharacteristicChanged(napi_env env,napi_callback_info info)674 napi_value NapiGattClient::SetNotifyCharacteristicChanged(napi_env env, napi_callback_info info)
675 {
676     HILOGI("SetNotifyCharacteristicChanged called");
677     NapiGattClient* gattClient = nullptr;
678 
679     size_t expectedArgsCount = ARGS_SIZE_TWO;
680     size_t argc = expectedArgsCount;
681     napi_value argv[ARGS_SIZE_TWO] = {0};
682     napi_value ret = nullptr;
683 
684     napi_value thisVar = nullptr;
685     bool isOK = false;
686 
687     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
688     if (argc != expectedArgsCount) {
689         HILOGE("Requires 1 argument.");
690         return ret;
691     }
692 
693     napi_unwrap(env, thisVar, (void**)&gattClient);
694 
695     GattCharacteristic* characteristic = GetCharacteristicFromJS(env, argv[PARAM0], nullptr, gattClient->GetClient());
696 
697     bool enableNotify = false;
698     ParseBool(env, enableNotify, argv[PARAM1]);
699 
700     if (gattClient->GetClient()->SetNotifyCharacteristic(*characteristic, enableNotify) ==
701         GattStatus::GATT_SUCCESS) {
702         isOK = true;
703     }
704 
705     napi_get_boolean(env, isOK, &ret);
706     return ret;
707 }
708 } // namespace Bluetooth
709 } // namespace OHOS
710