• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 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  
16  #include "napi_parser_utils.h"
17  
18  #include <string>
19  #include <vector>
20  
21  #include "napi_async_callback.h"
22  
23  namespace OHOS {
24  namespace Bluetooth {
25  
26  // shall check object type is napi_object before, if it's other type, return false
27  // If the 'name' field is not exist, or napi function call error, return false
NapiIsObjectPropertyExist(napi_env env,napi_value object,const char * name)28  static bool NapiIsObjectPropertyExist(napi_env env, napi_value object, const char *name)
29  {
30      auto status = NapiIsObject(env, object);
31      if (status != napi_ok) {
32          HILOGE("expect object");
33          return false;
34      }
35      bool exist = false;
36      status = napi_has_named_property(env, object, name, &exist);
37      if (status != napi_ok) {
38          HILOGE("Get object property failed, name: %{public}s", name);
39          return false;
40      }
41      return exist;
42  }
43  
NapiParseGattService(napi_env env,napi_value object,NapiGattService & outService)44  napi_status NapiParseGattService(napi_env env, napi_value object, NapiGattService &outService)
45  {
46      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "isPrimary", "characteristics",
47          "includeServices"}));
48  
49      std::string uuid {};
50      bool isPrimary = true;
51      std::vector<NapiBleCharacteristic> characteristics {};
52      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
53      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", uuid));
54      NAPI_BT_CALL_RETURN(NapiParseObjectBoolean(env, object, "isPrimary", isPrimary));
55      NAPI_BT_CALL_RETURN(NapiParseObjectArray(env, object, "characteristics", characteristics));
56      if (NapiIsObjectPropertyExist(env, object, "includeServices")) {
57          std::vector<NapiGattService> includeServices {};
58          NAPI_BT_CALL_RETURN(NapiParseObjectArray(env, object, "includeServices", includeServices));
59          outService.includeServices = std::move(includeServices);
60      }
61      outService.serviceUuid = UUID::FromString(uuid);
62      outService.isPrimary = isPrimary;
63      outService.characteristics = std::move(characteristics);
64      return napi_ok;
65  }
66  
67  namespace {
68  const NapiGattPermission DEFAULT_GATT_PERMISSIONS = {
69      .readable = true,
70      .writeable = true,
71  };
72  const NapiGattProperties DEFAULT_GATT_PROPERTIES = {
73      .write = true,
74      .writeNoResponse = true,
75      .read = true,
76  };
ConvertGattPermissions(const NapiGattPermission & napiPermissions)77  uint16_t ConvertGattPermissions(const NapiGattPermission &napiPermissions)
78  {
79      uint16_t permissions = 0;
80      if (napiPermissions.readable) {
81          permissions |= static_cast<uint16_t>(GattPermission::READABLE);
82      }
83      if (napiPermissions.writeable) {
84          permissions |= static_cast<uint16_t>(GattPermission::WRITEABLE);
85      }
86      if (napiPermissions.readEncrypted) {
87          permissions |= static_cast<uint16_t>(GattPermission::READ_ENCRYPTED_MITM);
88      }
89      if (napiPermissions.writeEncrypted) {
90          permissions |= static_cast<uint16_t>(GattPermission::WRITE_ENCRYPTED_MITM);
91      }
92      return permissions;
93  }
ConvertGattProperties(const NapiGattProperties & napiProperties)94  uint16_t ConvertGattProperties(const NapiGattProperties &napiProperties)
95  {
96      uint16_t properties = 0;
97      if (napiProperties.read) {
98          properties |= static_cast<uint16_t>(GattCharacteristic::READ);
99      }
100      if (napiProperties.write) {
101          properties |= static_cast<uint16_t>(GattCharacteristic::WRITE);
102      }
103      if (napiProperties.writeNoResponse) {
104          properties |= static_cast<uint16_t>(GattCharacteristic::WRITE_WITHOUT_RESPONSE);
105      }
106      if (napiProperties.notify) {
107          properties |= static_cast<uint16_t>(GattCharacteristic::NOTIFY);
108      }
109      if (napiProperties.indicate) {
110          properties |= static_cast<uint16_t>(GattCharacteristic::INDICATE);
111      }
112      return properties;
113  }
114  }  // namespace {}
115  
NapiParseGattCharacteristic(napi_env env,napi_value object,NapiBleCharacteristic & outCharacteristic)116  napi_status NapiParseGattCharacteristic(napi_env env, napi_value object, NapiBleCharacteristic &outCharacteristic)
117  {
118      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "characteristicUuid",
119          "characteristicValue", "descriptors", "properties", "permissions"}));
120  
121      std::string serviceUuid {};
122      std::string characterUuid {};
123      std::vector<uint8_t> characterValue {};
124      std::vector<NapiBleDescriptor> descriptors {};
125      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
126      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", serviceUuid));
127      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "characteristicUuid", characterUuid));
128      NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "characteristicValue", characterValue));
129      NAPI_BT_CALL_RETURN(NapiParseObjectArray(env, object, "descriptors", descriptors));
130  
131      NapiGattProperties properties = DEFAULT_GATT_PROPERTIES;
132      if (NapiIsObjectPropertyExist(env, object, "properties"))  {
133          NAPI_BT_CALL_RETURN(NapiParseObjectGattProperties(env, object, "properties", properties));
134      }
135      NapiGattPermission permissions = DEFAULT_GATT_PERMISSIONS;
136      if (NapiIsObjectPropertyExist(env, object, "permissions")) {
137          NAPI_BT_CALL_RETURN(NapiParseObjectGattPermissions(env, object, "permissions", permissions));
138      }
139  
140      outCharacteristic.serviceUuid = UUID::FromString(serviceUuid);
141      outCharacteristic.characteristicUuid = UUID::FromString(characterUuid);
142      outCharacteristic.characteristicValue = std::move(characterValue);
143      outCharacteristic.descriptors = std::move(descriptors);
144      outCharacteristic.properties = ConvertGattProperties(properties);
145      outCharacteristic.permissions = ConvertGattPermissions(permissions);
146      return napi_ok;
147  }
148  
NapiParseGattDescriptor(napi_env env,napi_value object,NapiBleDescriptor & outDescriptor)149  napi_status NapiParseGattDescriptor(napi_env env, napi_value object, NapiBleDescriptor &outDescriptor)
150  {
151      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "characteristicUuid",
152          "descriptorUuid", "descriptorValue", "permissions"}));
153  
154      std::string serviceUuid {};
155      std::string characterUuid {};
156      std::string descriptorUuid {};
157      std::vector<uint8_t> descriptorValue {};
158      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
159      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", serviceUuid));
160      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "characteristicUuid", characterUuid));
161      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "descriptorUuid", descriptorUuid));
162      NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "descriptorValue", descriptorValue));
163  
164      NapiGattPermission permissions = DEFAULT_GATT_PERMISSIONS;
165      if (NapiIsObjectPropertyExist(env, object, "permissions")) {
166          NAPI_BT_CALL_RETURN(NapiParseObjectGattPermissions(env, object, "permissions", permissions));
167      }
168  
169      outDescriptor.serviceUuid = UUID::FromString(serviceUuid);
170      outDescriptor.characteristicUuid = UUID::FromString(characterUuid);
171      outDescriptor.descriptorUuid = UUID::FromString(descriptorUuid);
172      outDescriptor.descriptorValue = std::move(descriptorValue);
173      outDescriptor.permissions = ConvertGattPermissions(permissions);
174      return napi_ok;
175  }
176  
NapiParseNotifyCharacteristic(napi_env env,napi_value object,NapiNotifyCharacteristic & outCharacter)177  napi_status NapiParseNotifyCharacteristic(napi_env env, napi_value object, NapiNotifyCharacteristic &outCharacter)
178  {
179      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "characteristicUuid",
180          "characteristicValue", "confirm"}));
181  
182      std::string serviceUuid {};
183      std::string characterUuid {};
184      std::vector<uint8_t> characterValue {};
185      bool confirm = false;
186      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
187      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", serviceUuid));
188      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "characteristicUuid", characterUuid));
189      NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "characteristicValue", characterValue));
190      NAPI_BT_CALL_RETURN(NapiParseObjectBoolean(env, object, "confirm", confirm));
191  
192      outCharacter.serviceUuid = UUID::FromString(serviceUuid);
193      outCharacter.characterUuid = UUID::FromString(characterUuid);
194      outCharacter.characterValue = std::move(characterValue);
195      outCharacter.confirm = confirm;
196      return napi_ok;
197  }
198  
NapiParseGattsServerResponse(napi_env env,napi_value object,NapiGattsServerResponse & rsp)199  napi_status NapiParseGattsServerResponse(napi_env env, napi_value object, NapiGattsServerResponse &rsp)
200  {
201      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"deviceId", "transId", "status", "offset",
202          "value"}));
203  
204      std::string deviceId {};
205      int transId = 0;
206      int status = 0;
207      int offset = 0;
208      std::vector<uint8_t> value {};
209      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
210      NAPI_BT_CALL_RETURN(NapiParseObjectBdAddr(env, object, "deviceId", deviceId));
211      NAPI_BT_CALL_RETURN(NapiParseObjectInt32(env, object, "transId", transId));
212      NAPI_BT_CALL_RETURN(NapiParseObjectInt32(env, object, "status", status));
213      NAPI_BT_CALL_RETURN(NapiParseObjectInt32(env, object, "offset", offset));
214      NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "value", value));
215  
216      rsp.deviceId = deviceId;
217      rsp.transId = transId;
218      rsp.status = status;
219      rsp.offset = offset;
220      rsp.value = std::move(value);
221      return napi_ok;
222  }
223  
NapiParseObjectGattPermissions(napi_env env,napi_value object,const char * name,NapiGattPermission & outPermissions)224  napi_status NapiParseObjectGattPermissions(napi_env env, napi_value object, const char *name,
225      NapiGattPermission &outPermissions)
226  {
227      napi_value permissionObject;
228      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
229      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, permissionObject));
230      // Parse permission object
231      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, permissionObject, {"readable", "writeable",
232          "readEncrypted", "writeEncrypted"}));
233  
234      bool isExist;
235      NapiGattPermission permissions {};
236      NAPI_BT_CALL_RETURN(
237          NapiParseObjectBooleanOptional(env, permissionObject, "readable", permissions.readable, isExist));
238      NAPI_BT_CALL_RETURN(
239          NapiParseObjectBooleanOptional(env, permissionObject, "writeable", permissions.writeable, isExist));
240      NAPI_BT_CALL_RETURN(
241          NapiParseObjectBooleanOptional(env, permissionObject, "readEncrypted", permissions.readEncrypted, isExist));
242      NAPI_BT_CALL_RETURN(
243          NapiParseObjectBooleanOptional(env, permissionObject, "writeEncrypted", permissions.writeEncrypted, isExist));
244      outPermissions = permissions;
245      return napi_ok;
246  }
247  
NapiParseObjectGattProperties(napi_env env,napi_value object,const char * name,NapiGattProperties & outProperties)248  napi_status NapiParseObjectGattProperties(napi_env env, napi_value object, const char *name,
249      NapiGattProperties &outProperties)
250  {
251      napi_value propertiesObject;
252      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
253      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, propertiesObject));
254      // Parse properties object
255      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, propertiesObject, {"write", "writeNoResponse",
256          "read", "notify", "indicate"}));
257  
258      bool isExist;
259      NapiGattProperties properties {};
260      NAPI_BT_CALL_RETURN(
261          NapiParseObjectBooleanOptional(env, propertiesObject, "write", properties.write, isExist));
262      NAPI_BT_CALL_RETURN(
263          NapiParseObjectBooleanOptional(env, propertiesObject, "writeNoResponse", properties.writeNoResponse, isExist));
264      NAPI_BT_CALL_RETURN(
265          NapiParseObjectBooleanOptional(env, propertiesObject, "read", properties.read, isExist));
266      NAPI_BT_CALL_RETURN(
267          NapiParseObjectBooleanOptional(env, propertiesObject, "notify", properties.notify, isExist));
268      NAPI_BT_CALL_RETURN(
269          NapiParseObjectBooleanOptional(env, propertiesObject, "indicate", properties.indicate, isExist));
270      outProperties = properties;
271      return napi_ok;
272  }
273  
NapiParseBoolean(napi_env env,napi_value value,bool & outBoolean)274  napi_status NapiParseBoolean(napi_env env, napi_value value, bool &outBoolean)
275  {
276      bool boolean = false;
277      NAPI_BT_CALL_RETURN(NapiIsBoolean(env, value));
278      NAPI_BT_CALL_RETURN(napi_get_value_bool(env, value, &boolean));
279      outBoolean = boolean;
280      return napi_ok;
281  }
282  
NapiParseInt32(napi_env env,napi_value value,int32_t & outNum)283  napi_status NapiParseInt32(napi_env env, napi_value value, int32_t &outNum)
284  {
285      int32_t num = 0;
286      NAPI_BT_CALL_RETURN(NapiIsNumber(env, value));
287      NAPI_BT_CALL_RETURN(napi_get_value_int32(env, value, &num));
288      outNum = num;
289      return napi_ok;
290  }
291  
NapiParseUint32(napi_env env,napi_value value,uint32_t & outNum)292  napi_status NapiParseUint32(napi_env env, napi_value value, uint32_t &outNum)
293  {
294      uint32_t num = 0;
295      NAPI_BT_CALL_RETURN(NapiIsNumber(env, value));
296      NAPI_BT_CALL_RETURN(napi_get_value_uint32(env, value, &num));
297      outNum = num;
298      return napi_ok;
299  }
300  
NapiParseString(napi_env env,napi_value value,std::string & outStr)301  napi_status NapiParseString(napi_env env, napi_value value, std::string &outStr)
302  {
303      std::string str {};
304      NAPI_BT_CALL_RETURN(NapiIsString(env, value));
305      NAPI_BT_RETURN_IF(!ParseString(env, str, value), "parse string failed", napi_invalid_arg);
306      outStr = std::move(str);
307      return napi_ok;
308  }
309  
NapiParseBdAddr(napi_env env,napi_value value,std::string & outAddr)310  napi_status NapiParseBdAddr(napi_env env, napi_value value, std::string &outAddr)
311  {
312      std::string bdaddr {};
313      NAPI_BT_CALL_RETURN(NapiParseString(env, value, bdaddr));
314      NAPI_BT_RETURN_IF(!IsValidAddress(bdaddr), "Invalid bdaddr", napi_invalid_arg);
315      outAddr = std::move(bdaddr);
316      return napi_ok;
317  }
318  
NapiParseUuid(napi_env env,napi_value value,std::string & outUuid)319  napi_status NapiParseUuid(napi_env env, napi_value value, std::string &outUuid)
320  {
321      std::string uuid {};
322      NAPI_BT_CALL_RETURN(NapiParseString(env, value, uuid));
323      NAPI_BT_RETURN_IF(!IsValidUuid(uuid), "Invalid uuid", napi_invalid_arg);
324      outUuid = std::move(uuid);
325      return napi_ok;
326  }
327  
NapiParseArrayBuffer(napi_env env,napi_value value,std::vector<uint8_t> & outVec)328  napi_status NapiParseArrayBuffer(napi_env env, napi_value value, std::vector<uint8_t> &outVec)
329  {
330      uint8_t *data = nullptr;
331      size_t size = 0;
332      NAPI_BT_CALL_RETURN(NapiIsArrayBuffer(env, value));
333      bool isSuccess = ParseArrayBuffer(env, &data, size, value);
334      if (!isSuccess) {
335          HILOGE("Parse arraybuffer failed");
336          return napi_invalid_arg;
337      }
338      std::vector<uint8_t> vec(data, data + size);
339      outVec = std::move(vec);
340      return napi_ok;
341  }
342  
NapiParseGattWriteType(napi_env env,napi_value value,int & outWriteType)343  napi_status NapiParseGattWriteType(napi_env env, napi_value value, int &outWriteType)
344  {
345      int writeType = -1;
346      NAPI_BT_CALL_RETURN(NapiParseInt32(env, value, writeType));
347      if (writeType == static_cast<int>(NapiGattWriteType::WRITE)) {
348          HILOGI("gattWriteType: WRITE");
349          outWriteType = GattCharacteristic::WriteType::DEFAULT;
350      } else if (writeType == static_cast<int>(NapiGattWriteType::WRITE_NO_RESPONSE)) {
351          HILOGI("gattWriteType: WRITE_NO_RESPONSE");
352          outWriteType = GattCharacteristic::WriteType::NO_RESPONSE;
353      } else {
354          HILOGE("Invalid gattWriteType: %{public}d", writeType);
355          return napi_invalid_arg;
356      }
357      return napi_ok;
358  }
359  
NapiParseAsyncCallback(napi_env env,napi_callback_info info)360  std::shared_ptr<NapiAsyncCallback> NapiParseAsyncCallback(napi_env env, napi_callback_info info)
361  {
362      size_t argc = ARGS_SIZE_FOUR;
363      napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
364      auto status = napi_get_cb_info(env, info, &argc, argv, nullptr, NULL);
365      if (status != napi_ok) {
366          HILOGE("napi_get_cb_info failed");
367          return nullptr;
368      }
369      if (argc > ARGS_SIZE_FOUR) {
370          HILOGE("size of parameters is larger than ARGS_SIZE_FOUR");
371          return nullptr;
372      }
373  
374      // "argc - 1" is AsyncCallback parameter's index
375      auto asyncCallback = std::make_shared<NapiAsyncCallback>();
376      asyncCallback->env = env;
377      if (argc > 0 && NapiIsFunction(env, argv[argc - 1]) == napi_ok) {
378          HILOGD("callback mode");
379          asyncCallback->callback = std::make_shared<NapiCallback>(env, argv[argc - 1]);
380      } else {
381          HILOGD("promise mode");
382          asyncCallback->promise = std::make_shared<NapiPromise>(env);
383      }
384      return asyncCallback;
385  }
386  
NapiGetObjectProperty(napi_env env,napi_value object,const char * name,napi_value & outProperty,bool & outExist)387  static napi_status NapiGetObjectProperty(napi_env env, napi_value object, const char *name, napi_value &outProperty,
388      bool &outExist)
389  {
390      bool exist = false;
391      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
392      NAPI_BT_CALL_RETURN(napi_has_named_property(env, object, name, &exist));
393      if (exist) {
394          napi_value property;
395          NAPI_BT_CALL_RETURN(napi_get_named_property(env, object, name, &property));
396          outProperty = property;
397      }
398      outExist = exist;
399      return napi_ok;
400  }
NapiGetObjectProperty(napi_env env,napi_value object,const char * name,napi_value & outProperty)401  napi_status NapiGetObjectProperty(napi_env env, napi_value object, const char *name, napi_value &outProperty)
402  {
403      bool exist = false;
404      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, outProperty, exist));
405      NAPI_BT_RETURN_IF(!exist, "no needed property", napi_invalid_arg);
406      return napi_ok;
407  }
NapiGetObjectPropertyOptional(napi_env env,napi_value object,const char * name,napi_value & outProperty,bool & outExist)408  napi_status NapiGetObjectPropertyOptional(napi_env env, napi_value object, const char *name, napi_value &outProperty,
409      bool &outExist)
410  {
411      return NapiGetObjectProperty(env, object, name, outProperty, outExist);
412  }
413  
NapiParseObjectBoolean(napi_env env,napi_value object,const char * name,bool & outBoolean)414  napi_status NapiParseObjectBoolean(napi_env env, napi_value object, const char *name, bool &outBoolean)
415  {
416      napi_value property;
417      bool boolean = true;
418      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
419      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
420      NAPI_BT_CALL_RETURN(NapiParseBoolean(env, property, boolean));
421      outBoolean = boolean;
422      return napi_ok;
423  }
424  
NapiParseObjectUuid(napi_env env,napi_value object,const char * name,std::string & outUuid)425  napi_status NapiParseObjectUuid(napi_env env, napi_value object, const char *name, std::string &outUuid)
426  {
427      napi_value property;
428      std::string uuid {};
429      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
430      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
431      NAPI_BT_CALL_RETURN(NapiParseUuid(env, property, uuid));
432      outUuid = std::move(uuid);
433      return napi_ok;
434  }
435  
NapiParseObjectArrayBuffer(napi_env env,napi_value object,const char * name,std::vector<uint8_t> & outVec)436  napi_status NapiParseObjectArrayBuffer(napi_env env, napi_value object, const char *name, std::vector<uint8_t> &outVec)
437  {
438      napi_value property;
439      std::vector<uint8_t> vec {};
440      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
441      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
442      NAPI_BT_CALL_RETURN(NapiParseArrayBuffer(env, property, vec));
443      outVec = std::move(vec);
444      return napi_ok;
445  }
446  
NapiParseObjectBdAddr(napi_env env,napi_value object,const char * name,std::string & outAddr)447  napi_status NapiParseObjectBdAddr(napi_env env, napi_value object, const char *name, std::string &outAddr)
448  {
449      napi_value property;
450      std::string bdaddr {};
451      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
452      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
453      NAPI_BT_CALL_RETURN(NapiParseBdAddr(env, property, bdaddr));
454      outAddr = std::move(bdaddr);
455      return napi_ok;
456  }
457  
NapiParseObjectInt32(napi_env env,napi_value object,const char * name,int32_t & outNum)458  napi_status NapiParseObjectInt32(napi_env env, napi_value object, const char *name, int32_t &outNum)
459  {
460      napi_value property;
461      int32_t num = 0;
462      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
463      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
464      NAPI_BT_CALL_RETURN(NapiParseInt32(env, property, num));
465      outNum = num;
466      return napi_ok;
467  }
468  
NapiParseObjectUint32(napi_env env,napi_value object,const char * name,uint32_t & outNum)469  napi_status NapiParseObjectUint32(napi_env env, napi_value object, const char *name, uint32_t &outNum)
470  {
471      napi_value property;
472      uint32_t num = 0;
473      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
474      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
475      NAPI_BT_CALL_RETURN(NapiParseUint32(env, property, num));
476      outNum = num;
477      return napi_ok;
478  }
479  
NapiParseObjectBooleanOptional(napi_env env,napi_value object,const char * name,bool & outBoolean,bool & outExist)480  napi_status NapiParseObjectBooleanOptional(napi_env env, napi_value object, const char *name, bool &outBoolean,
481      bool &outExist)
482  {
483      napi_value property;
484      bool exist = false;
485      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
486      NAPI_BT_CALL_RETURN(NapiGetObjectPropertyOptional(env, object, name, property, exist));
487      if (exist) {
488          bool boolean = true;
489          NAPI_BT_CALL_RETURN(NapiParseBoolean(env, property, boolean));
490          outBoolean = boolean;
491      }
492      outExist = exist;
493      return napi_ok;
494  }
NapiParseObjectInt32Optional(napi_env env,napi_value object,const char * name,int32_t & outNum,bool & outExist)495  napi_status NapiParseObjectInt32Optional(napi_env env, napi_value object, const char *name, int32_t &outNum,
496      bool &outExist)
497  {
498      napi_value property;
499      bool exist = false;
500      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
501      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property, exist));
502      if (exist) {
503          int32_t num = 0;
504          NAPI_BT_CALL_RETURN(NapiParseInt32(env, property, num));
505          outNum = num;
506      }
507      outExist = exist;
508      return napi_ok;
509  }
NapiParseObjectUint32Optional(napi_env env,napi_value object,const char * name,uint32_t & outNum,bool & outExist)510  napi_status NapiParseObjectUint32Optional(napi_env env, napi_value object, const char *name, uint32_t &outNum,
511      bool &outExist)
512  {
513      napi_value property;
514      bool exist = false;
515      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
516      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property, exist));
517      if (exist) {
518          uint32_t num = 0;
519          NAPI_BT_CALL_RETURN(NapiParseUint32(env, property, num));
520          outNum = num;
521      }
522      outExist = exist;
523      return napi_ok;
524  }
525  
526  // Parse params template, used for NapiParseArray
527  template <typename T>
NapiParseObject(napi_env env,napi_value object,T & outObj)528  napi_status NapiParseObject(napi_env env, napi_value object, T &outObj)
529  {
530      HILOGE("Unimpleted type");
531      return napi_invalid_arg;
532  }
533  
534  template <>
NapiParseObject(napi_env env,napi_value object,std::string & outObj)535  napi_status NapiParseObject<std::string>(napi_env env, napi_value object, std::string &outObj)
536  {
537      return NapiParseString(env, object, outObj);
538  }
539  
540  template <>
NapiParseObject(napi_env env,napi_value object,UUID & outObj)541  napi_status NapiParseObject<UUID>(napi_env env, napi_value object, UUID &outObj)
542  {
543      std::string uuid {};
544      NAPI_BT_CALL_RETURN(NapiParseUuid(env, object, uuid));
545      outObj = UUID::FromString(uuid);
546      return napi_ok;
547  }
548  
549  template <>
NapiParseObject(napi_env env,napi_value object,NapiAdvManufactureData & outObj)550  napi_status NapiParseObject<NapiAdvManufactureData>(napi_env env, napi_value object, NapiAdvManufactureData &outObj)
551  {
552      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"manufactureId", "manufactureValue"}));
553      uint32_t num = 0;
554      std::vector<uint8_t> vec {};
555      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
556      NAPI_BT_CALL_RETURN(NapiParseObjectUint32(env, object, "manufactureId", num));
557      NAPI_BT_RETURN_IF(num > 0xFFFF, "Invalid manufactureId", napi_invalid_arg);
558      NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "manufactureValue", vec));
559  
560      outObj.id = static_cast<uint16_t>(num);
561      outObj.value = std::string(vec.begin(), vec.end());
562      return napi_ok;
563  }
564  
565  template <>
NapiParseObject(napi_env env,napi_value object,NapiAdvServiceData & outObj)566  napi_status NapiParseObject<NapiAdvServiceData>(napi_env env, napi_value object, NapiAdvServiceData &outObj)
567  {
568      NAPI_BT_CALL_RETURN(NapiCheckObjectPropertiesName(env, object, {"serviceUuid", "serviceValue"}));
569      std::string uuid {};
570      std::vector<uint8_t> vec {};
571      NAPI_BT_CALL_RETURN(NapiIsObject(env, object));
572      NAPI_BT_CALL_RETURN(NapiParseObjectUuid(env, object, "serviceUuid", uuid));
573      NAPI_BT_CALL_RETURN(NapiParseObjectArrayBuffer(env, object, "serviceValue", vec));
574  
575      outObj.uuid = std::move(uuid);
576      outObj.value = std::move(vec);
577      return napi_ok;
578  }
579  
580  template <>
NapiParseObject(napi_env env,napi_value object,NapiGattService & outObj)581  napi_status NapiParseObject<NapiGattService>(napi_env env, napi_value object, NapiGattService &outObj)
582  {
583      return NapiParseGattService(env, object, outObj);
584  }
585  
586  template <>
NapiParseObject(napi_env env,napi_value object,NapiBleCharacteristic & outObj)587  napi_status NapiParseObject<NapiBleCharacteristic>(napi_env env, napi_value object, NapiBleCharacteristic &outObj)
588  {
589      return NapiParseGattCharacteristic(env, object, outObj);
590  }
591  
592  template <>
NapiParseObject(napi_env env,napi_value object,NapiBleDescriptor & outObj)593  napi_status NapiParseObject<NapiBleDescriptor>(napi_env env, napi_value object, NapiBleDescriptor &outObj)
594  {
595      return NapiParseGattDescriptor(env, object, outObj);
596  }
597  
598  template <typename T>
NapiParseArray(napi_env env,napi_value array,std::vector<T> & outVec)599  napi_status NapiParseArray(napi_env env, napi_value array, std::vector<T> &outVec)
600  {
601      std::vector<T> vec {};
602  
603      NAPI_BT_CALL_RETURN(NapiIsArray(env, array));
604      uint32_t length = 0;
605      NAPI_BT_CALL_RETURN(napi_get_array_length(env, array, &length));
606      for (uint32_t i = 0; i < length; ++i) {
607          napi_value element;
608          NAPI_BT_CALL_RETURN(napi_get_element(env, array, i, &element));
609          T object;
610          NAPI_BT_CALL_RETURN(NapiParseObject(env, element, object));
611          vec.push_back(std::move(object));
612      }
613      outVec = std::move(vec);
614      return napi_ok;
615  }
616  // // Declaration, ohters will undefined synbol
617  template napi_status NapiParseArray<NapiBleDescriptor>(napi_env env, napi_value array,
618      std::vector<NapiBleDescriptor> &outVec);
619  template napi_status NapiParseArray<NapiBleCharacteristic>(napi_env env, napi_value array,
620      std::vector<NapiBleCharacteristic> &outVec);
621  template napi_status NapiParseArray<NapiGattService>(napi_env env, napi_value array,
622      std::vector<NapiGattService> &outVec);
623  template napi_status NapiParseArray<NapiAdvServiceData>(napi_env env, napi_value array,
624      std::vector<NapiAdvServiceData> &outVec);
625  template napi_status NapiParseArray<NapiAdvManufactureData>(napi_env env, napi_value array,
626      std::vector<NapiAdvManufactureData> &outVec);
627  template napi_status NapiParseArray<UUID>(napi_env env, napi_value array,
628      std::vector<UUID> &outVec);
629  template napi_status NapiParseArray<std::string>(napi_env env, napi_value array,
630      std::vector<std::string> &outVec);
631  
632  
633  template <typename T>
NapiParseObjectArray(napi_env env,napi_value object,const char * name,std::vector<T> & outVec)634  napi_status NapiParseObjectArray(napi_env env, napi_value object, const char *name, std::vector<T> &outVec)
635  {
636      napi_value property;
637      std::vector<T> vec {};
638      NAPI_BT_CALL_RETURN(NapiGetObjectProperty(env, object, name, property));
639      NAPI_BT_CALL_RETURN(NapiParseArray(env, property, vec));
640      outVec = std::move(vec);
641      return napi_ok;
642  }
643  // Declaration, ohters will undefined synbol
644  template napi_status NapiParseObjectArray<NapiBleDescriptor>(napi_env env, napi_value object, const char *name,
645      std::vector<NapiBleDescriptor> &outVec);
646  template napi_status NapiParseObjectArray<NapiBleCharacteristic>(napi_env env, napi_value object, const char *name,
647      std::vector<NapiBleCharacteristic> &outVec);
648  template napi_status NapiParseObjectArray<NapiGattService>(napi_env env, napi_value object, const char *name,
649      std::vector<NapiGattService> &outVec);
650  template napi_status NapiParseObjectArray<NapiAdvServiceData>(napi_env env, napi_value object, const char *name,
651      std::vector<NapiAdvServiceData> &outVec);
652  template napi_status NapiParseObjectArray<NapiAdvManufactureData>(napi_env env, napi_value object, const char *name,
653      std::vector<NapiAdvManufactureData> &outVec);
654  template napi_status NapiParseObjectArray<UUID>(napi_env env, napi_value object, const char *name,
655      std::vector<UUID> &outVec);
656  template napi_status NapiParseObjectArray<std::string>(napi_env env, napi_value object, const char *name,
657      std::vector<std::string> &outVec);
658  }  // namespace Bluetooth
659  }  // namespace OHOS
660