• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 
16 #include "dm_native_util.h"
17 
18 #include "dm_anonymous.h"
19 #include "dm_constants.h"
20 #include "dm_log.h"
21 #include "ipc_skeleton.h"
22 #include "js_native_api.h"
23 #include "tokenid_kit.h"
24 
25 using namespace OHOS::Security::AccessToken;
26 
27 namespace OHOS {
28 namespace DistributedHardware {
29 namespace {
30 const std::string ERR_MESSAGE_NO_PERMISSION = "Permission verify failed.";
31 const std::string ERR_MESSAGE_NOT_SYSTEM_APP = "The caller is not a system application.";
32 const std::string ERR_MESSAGE_INVALID_PARAMS = "Input parameter error.";
33 const std::string ERR_MESSAGE_FAILED = "Failed to execute the function.";
34 const std::string ERR_MESSAGE_OBTAIN_SERVICE = "Failed to obtain the service.";
35 const std::string ERR_MESSAGE_AUTHENTICALTION_INVALID = "Authentication invalid.";
36 const std::string ERR_MESSAGE_DISCOVERY_INVALID = "Discovery invalid.";
37 const std::string ERR_MESSAGE_PUBLISH_INVALID = "Publish invalid.";
38 const std::string ERR_MESSAGE_FROM_CLOUD_FAILED = "Get data from cloud failed.";
39 const std::string ERR_MESSAGE_NEED_LOGIN = "A login account is required.";
40 const std::string ERR_MESSAGE_SCAS_CHECK_FAILED = "The device name contains non-compliant content.";
41 
42 const int32_t DM_NAPI_DISCOVER_EXTRA_INIT_ONE = -1;
43 const int32_t DM_NAPI_DISCOVER_EXTRA_INIT_TWO = -2;
44 const int32_t DM_NAPI_DESCRIPTION_BUF_LENGTH = 16384;
45 const int32_t DM_NAPI_BUF_LENGTH = 256;
46 const int32_t MAX_OBJECT_LEN = 4096;
47 
JsObjectToString(const napi_env & env,const napi_value & object,const std::string & fieldStr,char * dest,const int32_t destLen)48 void JsObjectToString(const napi_env &env, const napi_value &object, const std::string &fieldStr,
49                       char *dest, const int32_t destLen)
50 {
51     if (dest == nullptr || destLen < 0 || (destLen > MAX_OBJECT_LEN && fieldStr != CUSTOM_DESCRIPTION) ||
52         destLen > DM_NAPI_DESCRIPTION_BUF_LENGTH) {
53         return;
54     }
55     bool hasProperty = false;
56     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
57     if (hasProperty) {
58         napi_value field = nullptr;
59         napi_valuetype valueType = napi_undefined;
60 
61         napi_get_named_property(env, object, fieldStr.c_str(), &field);
62         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
63         if (!CheckArgsType(env, valueType == napi_string, fieldStr.c_str(), "string")) {
64             return;
65         }
66         size_t result = 0;
67         NAPI_CALL_RETURN_VOID(env, napi_get_value_string_utf8(env, field, dest, destLen, &result));
68     } else {
69         LOGE("devicemanager napi js to str no property: %{public}s", fieldStr.c_str());
70     }
71 }
72 
GetStrFromJsObj(const napi_env & env,const napi_value & jsObj,const std::string & fieldStr)73 std::string GetStrFromJsObj(const napi_env &env, const napi_value &jsObj, const std::string &fieldStr)
74 {
75     char str[DM_NAPI_BUF_LENGTH] = "";
76     JsObjectToString(env, jsObj, fieldStr, str, sizeof(str));
77     return str;
78 }
79 
JsObjectToBool(const napi_env & env,const napi_value & object,const std::string & fieldStr,bool & fieldRef)80 void JsObjectToBool(const napi_env &env, const napi_value &object, const std::string &fieldStr,
81                     bool &fieldRef)
82 {
83     bool hasProperty = false;
84     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
85     if (hasProperty) {
86         napi_value field = nullptr;
87         napi_valuetype valueType = napi_undefined;
88 
89         napi_get_named_property(env, object, fieldStr.c_str(), &field);
90         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
91         if (!CheckArgsType(env, valueType == napi_boolean, fieldStr.c_str(), "bool")) {
92             return;
93         }
94         napi_get_value_bool(env, field, &fieldRef);
95     } else {
96         LOGE("devicemanager napi js to bool no property: %{public}s", fieldStr.c_str());
97         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + " no property " + fieldStr;
98         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
99     }
100 }
101 
JsObjectToInt(const napi_env & env,const napi_value & object,const std::string & fieldStr,int32_t & fieldRef)102 void JsObjectToInt(const napi_env &env, const napi_value &object, const std::string &fieldStr,
103                    int32_t &fieldRef)
104 {
105     bool hasProperty = false;
106     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
107     if (hasProperty) {
108         napi_value field = nullptr;
109         napi_valuetype valueType = napi_undefined;
110 
111         napi_get_named_property(env, object, fieldStr.c_str(), &field);
112         NAPI_CALL_RETURN_VOID(env, napi_typeof(env, field, &valueType));
113         if (!CheckArgsType(env, valueType == napi_number, fieldStr.c_str(), "number")) {
114             return;
115         }
116         napi_get_value_int32(env, field, &fieldRef);
117     } else {
118         LOGE("devicemanager napi js to int no property: %{public}s", fieldStr.c_str());
119     }
120 }
121 
GetIntFromJsObj(const napi_env & env,const napi_value & object,const std::string & fieldStr)122 int32_t GetIntFromJsObj(const napi_env &env, const napi_value &object, const std::string &fieldStr)
123 {
124     int32_t num = 0;
125     JsObjectToInt(env, object, fieldStr, num);
126     return num;
127 }
128 
GetDeviceTypeById(DmDeviceType type)129 std::string GetDeviceTypeById(DmDeviceType type)
130 {
131     const static std::pair<DmDeviceType, std::string> mapArray[] = {
132         {DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_UNKNOWN_STRING},
133         {DEVICE_TYPE_PHONE, DEVICE_TYPE_PHONE_STRING},
134         {DEVICE_TYPE_PAD, DEVICE_TYPE_PAD_STRING},
135         {DEVICE_TYPE_TV, DEVICE_TYPE_TV_STRING},
136         {DEVICE_TYPE_CAR, DEVICE_TYPE_CAR_STRING},
137         {DEVICE_TYPE_WATCH, DEVICE_TYPE_WATCH_STRING},
138         {DEVICE_TYPE_WIFI_CAMERA, DEVICE_TYPE_WIFICAMERA_STRING},
139         {DEVICE_TYPE_PC, DEVICE_TYPE_PC_STRING},
140         {DEVICE_TYPE_SMART_DISPLAY, DEVICE_TYPE_SMART_DISPLAY_STRING},
141         {DEVICE_TYPE_2IN1, DEVICE_TYPE_2IN1_STRING},
142     };
143     for (const auto& item : mapArray) {
144         if (item.first == type) {
145             return item.second;
146         }
147     }
148     return DEVICE_TYPE_UNKNOWN_STRING;
149 }
150 
CheckArgsVal(napi_env env,bool assertion,const std::string & param,const std::string & msg)151 bool CheckArgsVal(napi_env env, bool assertion, const std::string &param, const std::string &msg)
152 {
153     if (!(assertion)) {
154         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The value of " + param + ": " + msg;
155         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
156         return false;
157     }
158     return true;
159 }
160 }
161 
GenerateBusinessError(napi_env env,int32_t err,const std::string & msg)162 napi_value GenerateBusinessError(napi_env env, int32_t err, const std::string &msg)
163 {
164     napi_value businessError = nullptr;
165     NAPI_CALL(env, napi_create_object(env, &businessError));
166     napi_value errorCode = nullptr;
167     NAPI_CALL(env, napi_create_int32(env, err, &errorCode));
168     napi_value errorMessage = nullptr;
169     NAPI_CALL(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &errorMessage));
170     NAPI_CALL(env, napi_set_named_property(env, businessError, "code", errorCode));
171     NAPI_CALL(env, napi_set_named_property(env, businessError, "message", errorMessage));
172 
173     return businessError;
174 }
175 
CheckArgsCount(napi_env env,bool assertion,const std::string & message)176 bool CheckArgsCount(napi_env env, bool assertion, const std::string &message)
177 {
178     if (!(assertion)) {
179         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + message;
180         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
181         return false;
182     }
183     return true;
184 }
185 
CheckArgsType(napi_env env,bool assertion,const std::string & paramName,const std::string & type)186 bool CheckArgsType(napi_env env, bool assertion, const std::string &paramName, const std::string &type)
187 {
188     if (!(assertion)) {
189         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + "The type of " + paramName +
190                 " must be " + type;
191         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
192         return false;
193     }
194     return true;
195 }
196 
CreateErrorForCall(napi_env env,int32_t code,const std::string & errMsg,bool isAsync)197 napi_value CreateErrorForCall(napi_env env, int32_t code, const std::string &errMsg, bool isAsync)
198 {
199     LOGI("CreateErrorForCall code:%{public}d, message:%{public}s", code, errMsg.c_str());
200     napi_value error = nullptr;
201     if (isAsync) {
202         napi_throw_error(env, std::to_string(code).c_str(), errMsg.c_str());
203     } else {
204         error = GenerateBusinessError(env, code, errMsg);
205     }
206     return error;
207 }
208 
CreateBusinessError(napi_env env,int32_t errCode,bool isAsync)209 napi_value CreateBusinessError(napi_env env, int32_t errCode, bool isAsync)
210 {
211     napi_value error = nullptr;
212     switch (errCode) {
213         case ERR_DM_NO_PERMISSION:
214             error = CreateErrorForCall(env, ERR_NO_PERMISSION, ERR_MESSAGE_NO_PERMISSION, isAsync);
215             break;
216         case ERR_DM_DISCOVERY_REPEATED:
217             error = CreateErrorForCall(env, DM_ERR_DISCOVERY_INVALID, ERR_MESSAGE_DISCOVERY_INVALID, isAsync);
218             break;
219         case ERR_DM_PUBLISH_REPEATED:
220             error = CreateErrorForCall(env, DM_ERR_PUBLISH_INVALID, ERR_MESSAGE_PUBLISH_INVALID, isAsync);
221             break;
222         case ERR_DM_AUTH_BUSINESS_BUSY:
223             error = CreateErrorForCall(env, DM_ERR_AUTHENTICALTION_INVALID,
224                 ERR_MESSAGE_AUTHENTICALTION_INVALID, isAsync);
225             break;
226         case ERR_DM_INPUT_PARA_INVALID:
227         case ERR_DM_UNSUPPORTED_AUTH_TYPE:
228         case ERR_DM_MAX_SIZE_FAIL:
229             error = CreateErrorForCall(env, ERR_INVALID_PARAMS, ERR_MESSAGE_INVALID_PARAMS, isAsync);
230             break;
231         case ERR_DM_INIT_FAILED:
232             error = CreateErrorForCall(env, DM_ERR_OBTAIN_SERVICE, ERR_MESSAGE_OBTAIN_SERVICE, isAsync);
233             break;
234         case ERR_NOT_SYSTEM_APP:
235             error = CreateErrorForCall(env, ERR_NOT_SYSTEM_APP, ERR_MESSAGE_NOT_SYSTEM_APP, isAsync);
236             break;
237         case ERR_DM_HILINKSVC_RSP_PARSE_FAILD:
238         case ERR_DM_HILINKSVC_REPLY_FAILED:
239         case ERR_DM_HILINKSVC_ICON_URL_EMPTY:
240         case ERR_DM_HILINKSVC_DISCONNECT:
241             error = CreateErrorForCall(env, DM_ERR_FROM_CLOUD_FAILED, ERR_MESSAGE_FROM_CLOUD_FAILED, isAsync);
242             break;
243         case ERR_DM_WISE_NEED_LOGIN:
244             error = CreateErrorForCall(env, DM_ERR_NEED_LOGIN, ERR_MESSAGE_NEED_LOGIN, isAsync);
245             break;
246         case ERR_DM_HILINKSVC_SCAS_CHECK_FAILED:
247             error = CreateErrorForCall(env, DM_ERR_SCAS_CHECK_FAILED, ERR_MESSAGE_SCAS_CHECK_FAILED, isAsync);
248             break;
249         default:
250             error = CreateErrorForCall(env, DM_ERR_FAILED, ERR_MESSAGE_FAILED, isAsync);
251             break;
252     }
253     return error;
254 }
255 
IsFunctionType(napi_env env,napi_value value)256 bool IsFunctionType(napi_env env, napi_value value)
257 {
258     napi_valuetype eventHandleType = napi_undefined;
259     napi_typeof(env, value, &eventHandleType);
260     return CheckArgsType(env, eventHandleType == napi_function, "callback", "function");
261 }
262 
SetValueUtf8String(const napi_env & env,const std::string & fieldStr,const std::string & str,napi_value & result)263 void SetValueUtf8String(const napi_env &env, const std::string &fieldStr, const std::string &str,
264                         napi_value &result)
265 {
266     napi_value value = nullptr;
267     napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &value);
268     napi_set_named_property(env, result, fieldStr.c_str(), value);
269 }
270 
SetValueInt32(const napi_env & env,const std::string & fieldStr,const int32_t intValue,napi_value & result)271 void SetValueInt32(const napi_env &env, const std::string &fieldStr, const int32_t intValue,
272                    napi_value &result)
273 {
274     napi_value value = nullptr;
275     napi_create_int32(env, intValue, &value);
276     napi_set_named_property(env, result, fieldStr.c_str(), value);
277 }
278 
DeviceBasicInfoToJsArray(const napi_env & env,const std::vector<DmDeviceBasicInfo> & vecDevInfo,const int32_t idx,napi_value & arrayResult)279 void DeviceBasicInfoToJsArray(const napi_env &env,
280                               const std::vector<DmDeviceBasicInfo> &vecDevInfo, const int32_t idx,
281                               napi_value &arrayResult)
282 {
283     napi_value result = nullptr;
284     napi_create_object(env, &result);
285     DmDeviceBasicToJsObject(env, vecDevInfo[idx], result);
286 
287     napi_status status = napi_set_element(env, arrayResult, idx, result);
288     if (status != napi_ok) {
289         LOGE("DmDeviceBasicInfo To JsArray set element error: %{public}d", status);
290     }
291 }
292 
DmDeviceBasicToJsObject(napi_env env,const DmDeviceBasicInfo & devInfo,napi_value & result)293 void DmDeviceBasicToJsObject(napi_env env, const DmDeviceBasicInfo &devInfo, napi_value &result)
294 {
295     SetValueUtf8String(env, "deviceId", devInfo.deviceId, result);
296     SetValueUtf8String(env, "networkId", devInfo.networkId, result);
297     SetValueUtf8String(env, "deviceName", devInfo.deviceName, result);
298     std::string deviceType = GetDeviceTypeById(static_cast<DmDeviceType>(devInfo.deviceTypeId));
299     SetValueUtf8String(env, "deviceType", deviceType.c_str(), result);
300     SetValueUtf8String(env, "extraData", devInfo.extraData.c_str(), result);
301 }
302 
JsToDmPublishInfo(const napi_env & env,const napi_value & object,DmPublishInfo & info)303 void JsToDmPublishInfo(const napi_env &env, const napi_value &object, DmPublishInfo &info)
304 {
305     int32_t publishId = -1;
306     JsObjectToInt(env, object, "publishId", publishId);
307     info.publishId = publishId;
308 
309     int32_t mode = -1;
310     JsObjectToInt(env, object, "mode", mode);
311     info.mode = static_cast<DmDiscoverMode>(mode);
312 
313     int32_t freq = -1;
314     JsObjectToInt(env, object, "freq", freq);
315     info.freq = static_cast<DmExchangeFreq>(freq);
316 
317     JsObjectToBool(env, object, "ranging", info.ranging);
318     return;
319 }
320 
JsToBindParam(const napi_env & env,const napi_value & object,std::string & bindParam,int32_t & bindType,bool & isMetaType)321 void JsToBindParam(const napi_env &env, const napi_value &object, std::string &bindParam,
322                    int32_t &bindType, bool &isMetaType)
323 {
324     int32_t bindTypeTemp = -1;
325     JsObjectToInt(env, object, "bindType", bindTypeTemp);
326     bindType = bindTypeTemp;
327 
328     char appOperation[DM_NAPI_DESCRIPTION_BUF_LENGTH] = "";
329     JsObjectToString(env, object, "appOperation", appOperation, sizeof(appOperation));
330     char customDescription[DM_NAPI_DESCRIPTION_BUF_LENGTH] = "";
331     JsObjectToString(env, object, "customDescription", customDescription, sizeof(customDescription));
332     char targetPkgName[DM_NAPI_BUF_LENGTH] = "";
333     JsObjectToString(env, object, "targetPkgName", targetPkgName, sizeof(targetPkgName));
334     char metaType[DM_NAPI_BUF_LENGTH] = "";
335     JsObjectToString(env, object, "metaType", metaType, sizeof(metaType));
336     std::string metaTypeStr = metaType;
337     isMetaType = !metaTypeStr.empty();
338 
339     char pinCode[DM_NAPI_BUF_LENGTH] = "";
340     JsObjectToString(env, object, "pinCode", pinCode, sizeof(pinCode));
341     char authToken[DM_NAPI_BUF_LENGTH] = "";
342     JsObjectToString(env, object, "authToken", authToken, sizeof(authToken));
343     char brMac[DM_NAPI_BUF_LENGTH] = "";
344     JsObjectToString(env, object, "brMac", brMac, sizeof(brMac));
345     char isShowTrustDialog[DM_NAPI_BUF_LENGTH] = "";
346     JsObjectToString(env, object, "isShowTrustDialog", isShowTrustDialog, sizeof(isShowTrustDialog));
347     char bleMac[DM_NAPI_BUF_LENGTH] = "";
348     JsObjectToString(env, object, "bleMac", bleMac, sizeof(bleMac));
349     char wifiIP[DM_NAPI_BUF_LENGTH] = "";
350     JsObjectToString(env, object, "wifiIP", wifiIP, sizeof(wifiIP));
351 
352     int32_t wifiPort = -1;
353     JsObjectToInt(env, object, "wifiPort", wifiPort);
354     int32_t bindLevel = 0;
355     JsObjectToInt(env, object, "bindLevel", bindLevel);
356 
357     JsonObject jsonObj;
358     jsonObj[AUTH_TYPE] = bindType;
359     jsonObj[APP_OPERATION] = std::string(appOperation);
360     jsonObj[CUSTOM_DESCRIPTION] = std::string(customDescription);
361     jsonObj[PARAM_KEY_TARGET_PKG_NAME] = std::string(targetPkgName);
362     jsonObj[PARAM_KEY_META_TYPE] = metaTypeStr;
363     jsonObj[PARAM_KEY_PIN_CODE] = std::string(pinCode);
364     jsonObj[PARAM_KEY_AUTH_TOKEN] = std::string(authToken);
365     jsonObj[PARAM_KEY_IS_SHOW_TRUST_DIALOG] = std::string(isShowTrustDialog);
366     jsonObj[PARAM_KEY_BR_MAC] = std::string(brMac);
367     jsonObj[PARAM_KEY_BLE_MAC] = std::string(bleMac);
368     jsonObj[PARAM_KEY_WIFI_IP] = std::string(wifiIP);
369     jsonObj[PARAM_KEY_WIFI_PORT] = wifiPort;
370     jsonObj[BIND_LEVEL] = bindLevel;
371     bindParam = SafetyDump(jsonObj);
372 }
373 
IsSystemApp()374 bool IsSystemApp()
375 {
376     uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
377     return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
378 }
379 
JsToDiscoverTargetType(napi_env env,const napi_value & object,int32_t & discoverTargetType)380 bool JsToDiscoverTargetType(napi_env env, const napi_value &object, int32_t &discoverTargetType)
381 {
382     napi_valuetype objectType = napi_undefined;
383     napi_typeof(env, object, &objectType);
384     if (!(CheckArgsType(env, objectType == napi_object, "discoverParameter", "object or undefined"))) {
385         return false;
386     }
387     bool hasProperty = false;
388     napi_has_named_property(env, object, "discoverTargetType", &hasProperty);
389     if (hasProperty) {
390         napi_value field = nullptr;
391         napi_valuetype valueType = napi_undefined;
392         napi_get_named_property(env, object, "discoverTargetType", &field);
393         napi_typeof(env, field, &valueType);
394         if (!CheckArgsType(env, valueType == napi_number, "discoverTargetType", "number")) {
395             return false;
396         }
397         napi_get_value_int32(env, field, &discoverTargetType);
398         return true;
399     }
400     LOGE("discoverTargetType is invalid.");
401     return false;
402 }
403 
JsToDmDiscoveryExtra(const napi_env & env,const napi_value & object,std::string & extra)404 void JsToDmDiscoveryExtra(const napi_env &env, const napi_value &object, std::string &extra)
405 {
406     JsonObject jsonObj;
407     int32_t availableStatus = DM_NAPI_DISCOVER_EXTRA_INIT_ONE;
408     JsObjectToInt(env, object, "availableStatus", availableStatus);
409     if (availableStatus != DM_NAPI_DISCOVER_EXTRA_INIT_ONE) {
410         jsonObj["credible"] = availableStatus;
411     }
412 
413     int32_t discoverDistance = DM_NAPI_DISCOVER_EXTRA_INIT_ONE;
414     JsObjectToInt(env, object, "discoverDistance", discoverDistance);
415     if (discoverDistance != DM_NAPI_DISCOVER_EXTRA_INIT_ONE) {
416         jsonObj["range"] = discoverDistance;
417     }
418 
419     int32_t authenticationStatus = DM_NAPI_DISCOVER_EXTRA_INIT_ONE;
420     JsObjectToInt(env, object, "authenticationStatus", authenticationStatus);
421     if (authenticationStatus != DM_NAPI_DISCOVER_EXTRA_INIT_ONE) {
422         jsonObj["isTrusted"] = authenticationStatus;
423     }
424 
425     int32_t authorizationType = DM_NAPI_DISCOVER_EXTRA_INIT_TWO;
426     JsObjectToInt(env, object, "authorizationType", authorizationType);
427     if (authorizationType != DM_NAPI_DISCOVER_EXTRA_INIT_TWO) {
428         jsonObj["authForm"] = authorizationType;
429     }
430 
431     int32_t deviceType = DM_NAPI_DISCOVER_EXTRA_INIT_ONE;
432     JsObjectToInt(env, object, "deviceType", deviceType);
433     if (deviceType != DM_NAPI_DISCOVER_EXTRA_INIT_ONE) {
434         jsonObj["deviceType"] = deviceType;
435     }
436     extra = SafetyDump(jsonObj);
437     LOGI("JsToDmDiscoveryExtra, extra :%{public}s", extra.c_str());
438 }
439 
JsToDiscoveryParam(const napi_env & env,const napi_value & object,std::map<std::string,std::string> & discParam)440 void JsToDiscoveryParam(const napi_env &env, const napi_value &object,
441     std::map<std::string, std::string> &discParam)
442 {
443     char customData[DM_NAPI_BUF_LENGTH] = "";
444     JsObjectToString(env, object, "CUSTOM_DATA", customData, sizeof(customData));
445     discParam.insert(std::pair<std::string, std::string>(PARAM_KEY_CUSTOM_DATA, customData));
446     char capability[DM_NAPI_BUF_LENGTH] = "";
447     JsObjectToString(env, object, "DISC_CAPABILITY", capability, sizeof(capability));
448     discParam.insert(std::pair<std::string, std::string>(PARAM_KEY_DISC_CAPABILITY, capability));
449 }
InsertMapParames(JsonObject & bindParamObj,std::map<std::string,std::string> & bindParamMap)450 void InsertMapParames(JsonObject &bindParamObj, std::map<std::string, std::string> &bindParamMap)
451 {
452     LOGI("Insert map parames start");
453     if (IsInt32(bindParamObj, AUTH_TYPE)) {
454         int32_t authType = bindParamObj[AUTH_TYPE].Get<int32_t>();
455         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_AUTH_TYPE, std::to_string(authType)));
456     }
457     if (IsString(bindParamObj, APP_OPERATION)) {
458         std::string appOperation = bindParamObj[APP_OPERATION].Get<std::string>();
459         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_APP_OPER, appOperation));
460     }
461     if (IsString(bindParamObj, CUSTOM_DESCRIPTION)) {
462         std::string appDescription = bindParamObj[CUSTOM_DESCRIPTION].Get<std::string>();
463         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_APP_DESC, appDescription));
464     }
465     if (IsString(bindParamObj, PARAM_KEY_TARGET_PKG_NAME)) {
466         std::string targetPkgName = bindParamObj[PARAM_KEY_TARGET_PKG_NAME].Get<std::string>();
467         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_TARGET_PKG_NAME, targetPkgName));
468     }
469     if (IsString(bindParamObj, PARAM_KEY_META_TYPE)) {
470         std::string metaType = bindParamObj[PARAM_KEY_META_TYPE].Get<std::string>();
471         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_META_TYPE, metaType));
472     }
473     if (IsString(bindParamObj, PARAM_KEY_PIN_CODE)) {
474         std::string pinCode = bindParamObj[PARAM_KEY_PIN_CODE].Get<std::string>();
475         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_PIN_CODE, pinCode));
476     }
477     if (IsString(bindParamObj, PARAM_KEY_AUTH_TOKEN)) {
478         std::string authToken = bindParamObj[PARAM_KEY_AUTH_TOKEN].Get<std::string>();
479         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_AUTH_TOKEN, authToken));
480     }
481     if (IsString(bindParamObj, PARAM_KEY_IS_SHOW_TRUST_DIALOG)) {
482         std::string isShowTrustDialog = bindParamObj[PARAM_KEY_IS_SHOW_TRUST_DIALOG].Get<std::string>();
483         bindParamMap.insert(std::pair<std::string, std::string>(PARAM_KEY_IS_SHOW_TRUST_DIALOG, isShowTrustDialog));
484     }
485     if (IsInt32(bindParamObj, BIND_LEVEL)) {
486         int32_t bindLevel = bindParamObj[BIND_LEVEL].Get<std::int32_t>();
487         bindParamMap.insert(std::pair<std::string, std::string>(BIND_LEVEL, std::to_string(bindLevel)));
488     }
489 }
490 
JsToStringAndCheck(napi_env env,napi_value value,const std::string & valueName,std::string & strValue)491 bool JsToStringAndCheck(napi_env env, napi_value value, const std::string &valueName, std::string &strValue)
492 {
493     napi_valuetype deviceIdType = napi_undefined;
494     napi_typeof(env, value, &deviceIdType);
495     if (!CheckArgsType(env, deviceIdType == napi_string, valueName, "string")) {
496         return false;
497     }
498     size_t valueLen = 0;
499     napi_status stat = napi_get_value_string_utf8(env, value, nullptr, 0, &valueLen);
500     if (stat != napi_ok) {
501         return false;
502     }
503     if (!CheckArgsVal(env, valueLen > 0, valueName, "len == 0")) {
504         return false;
505     }
506     if (!CheckArgsVal(env, valueLen < DM_NAPI_BUF_LENGTH, valueName, "len >= MAXLEN")) {
507         return false;
508     }
509     char temp[DM_NAPI_BUF_LENGTH] = {0};
510     napi_status status = napi_get_value_string_utf8(env, value, temp, valueLen + 1, &valueLen);
511     if (status != napi_ok) {
512         return false;
513     }
514     strValue = temp;
515     return true;
516 }
517 
JsObjectToStrVector(const napi_env & env,const napi_value & object,const std::string & fieldStr,std::vector<std::string> & fieldRef)518 void JsObjectToStrVector(const napi_env &env, const napi_value &object, const std::string &fieldStr,
519     std::vector<std::string> &fieldRef)
520 {
521     bool hasProperty = false;
522     NAPI_CALL_RETURN_VOID(env, napi_has_named_property(env, object, fieldStr.c_str(), &hasProperty));
523     if (!hasProperty) {
524         LOGE("no property: %{public}s", fieldStr.c_str());
525         return;
526     }
527 
528     napi_value field = nullptr;
529     napi_get_named_property(env, object, fieldStr.c_str(), &field);
530     bool isArr = false;
531     napi_is_array(env, field, &isArr);
532     if (!isArr) {
533         LOGE("property: %{public}s is not array", fieldStr.c_str());
534         return;
535     }
536     uint32_t length = 0;
537     napi_get_array_length(env, field, &length);
538     for (size_t i = 0; i < length; i++) {
539         napi_value element;
540         napi_get_element(env, field, i, &element);
541         size_t strLen = 0;
542         napi_get_value_string_utf8(env, element, nullptr, 0, &strLen);
543         if (strLen == 0) {
544             continue;
545         }
546         char buf[DEVICE_UUID_LENGTH] = {0};
547         napi_get_value_string_utf8(env, element, buf, strLen + 1, &strLen);
548         fieldRef.emplace_back(buf);
549     }
550 }
551 
JsToDmDeviceProfileInfoFilterOptions(const napi_env & env,const napi_value & object,DmDeviceProfileInfoFilterOptions & info)552 void JsToDmDeviceProfileInfoFilterOptions(const napi_env &env, const napi_value &object,
553     DmDeviceProfileInfoFilterOptions &info)
554 {
555     napi_valuetype filterOptionsType;
556     napi_typeof(env, object, &filterOptionsType);
557     if (filterOptionsType != napi_object) {
558         LOGE("filterOptions is not object");
559         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + " The type of filterOptions must be object";
560         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
561         return;
562     }
563     bool isCloud = false;
564     JsObjectToBool(env, object, "isCloud", isCloud);
565     info.isCloud = isCloud;
566     std::vector<std::string> deviceIdList;
567     JsObjectToStrVector(env, object, "deviceIdList", deviceIdList);
568     info.deviceIdList = deviceIdList;
569 }
570 
JsToDmDeviceNetworkIdFilterOptions(const napi_env & env,const napi_value & object,NetworkIdQueryFilter & info)571 void JsToDmDeviceNetworkIdFilterOptions(const napi_env &env, const napi_value &object,
572     NetworkIdQueryFilter &info)
573 {
574     napi_valuetype filterOptionsType;
575     napi_typeof(env, object, &filterOptionsType);
576     if (filterOptionsType != napi_object) {
577         LOGE("filterOptions is not object");
578         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + " The type of filterOptions must be object";
579         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
580         return;
581     }
582     char wiseDeviceId[DM_NAPI_BUF_LENGTH] = "";
583     JsObjectToString(env, object, "wiseDeviceId", wiseDeviceId, sizeof(wiseDeviceId));
584     info.wiseDeviceId = wiseDeviceId;
585     int32_t onlineStatus = 0;
586     JsObjectToInt(env, object, "onlineStatus", onlineStatus);
587     info.onlineStatus = onlineStatus;
588 }
589 
DmServiceProfileInfoToJsArray(const napi_env & env,const std::vector<DmServiceProfileInfo> & svrInfos,napi_value & arrayResult)590 void DmServiceProfileInfoToJsArray(const napi_env &env, const std::vector<DmServiceProfileInfo> &svrInfos,
591     napi_value &arrayResult)
592 {
593     for (uint32_t i = 0; i < svrInfos.size(); i++) {
594         napi_value item = nullptr;
595         napi_create_object(env, &item);
596         SetValueUtf8String(env, "deviceId", svrInfos[i].deviceId, item);
597         SetValueUtf8String(env, "serviceId", svrInfos[i].serviceId, item);
598         SetValueUtf8String(env, "serviceType", svrInfos[i].serviceType, item);
599         napi_value data = nullptr;
600         napi_create_object(env, &data);
601         for (const auto& [key, value] : svrInfos[i].data) {
602             SetValueUtf8String(env, key, value, data);
603         }
604         napi_set_named_property(env, item, "data", data);
605         napi_status status = napi_set_element(env, arrayResult, i, item);
606         if (status != napi_ok) {
607             LOGE("DmServiceProfileInfoToJsArray To JsArray set element error: %{public}d", status);
608         }
609     }
610 }
611 
DmDeviceProfileInfoToJs(const napi_env & env,const DmDeviceProfileInfo & devInfo,napi_value & jsObj)612 void DmDeviceProfileInfoToJs(const napi_env &env, const DmDeviceProfileInfo &devInfo, napi_value &jsObj)
613 {
614     SetValueUtf8String(env, "deviceId", devInfo.deviceId, jsObj);
615     SetValueUtf8String(env, "deviceSn", devInfo.deviceSn, jsObj);
616     SetValueUtf8String(env, "mac", devInfo.mac, jsObj);
617     SetValueUtf8String(env, "model", devInfo.model, jsObj);
618     SetValueUtf8String(env, "internalModel", devInfo.internalModel, jsObj);
619     SetValueUtf8String(env, "deviceType", devInfo.deviceType, jsObj);
620     SetValueUtf8String(env, "manufacturer", devInfo.manufacturer, jsObj);
621     SetValueUtf8String(env, "deviceName", devInfo.deviceName, jsObj);
622     SetValueUtf8String(env, "productName", devInfo.productName, jsObj);
623     SetValueUtf8String(env, "productId", devInfo.productId, jsObj);
624     SetValueUtf8String(env, "subProductId", devInfo.subProductId, jsObj);
625     SetValueUtf8String(env, "sdkVersion", devInfo.sdkVersion, jsObj);
626     SetValueUtf8String(env, "bleMac", devInfo.bleMac, jsObj);
627     SetValueUtf8String(env, "brMac", devInfo.brMac, jsObj);
628     SetValueUtf8String(env, "sleMac", devInfo.sleMac, jsObj);
629     SetValueUtf8String(env, "firmwareVersion", devInfo.firmwareVersion, jsObj);
630     SetValueUtf8String(env, "hardwareVersion", devInfo.hardwareVersion, jsObj);
631     SetValueUtf8String(env, "softwareVersion", devInfo.softwareVersion, jsObj);
632     SetValueInt32(env, "protocolType", devInfo.protocolType, jsObj);
633     SetValueInt32(env, "setupType", devInfo.setupType, jsObj);
634     SetValueUtf8String(env, "wiseDeviceId", devInfo.wiseDeviceId, jsObj);
635     SetValueUtf8String(env, "wiseUserId", devInfo.wiseUserId, jsObj);
636     SetValueUtf8String(env, "registerTime", devInfo.registerTime, jsObj);
637     SetValueUtf8String(env, "modifyTime", devInfo.modifyTime, jsObj);
638     SetValueUtf8String(env, "shareTime", devInfo.shareTime, jsObj);
639     SetValueInt32(env, "isLocalDevice", devInfo.isLocalDevice ? 1 : 0, jsObj);
640 }
641 
DmDeviceProfileInfoToJsArray(const napi_env & env,const std::vector<DmDeviceProfileInfo> & devInfos,napi_value & arrayResult)642 void DmDeviceProfileInfoToJsArray(const napi_env &env, const std::vector<DmDeviceProfileInfo> &devInfos,
643     napi_value &arrayResult)
644 {
645     for (uint32_t i = 0; i < devInfos.size(); i++) {
646         napi_value item = nullptr;
647         napi_create_object(env, &item);
648         DmDeviceProfileInfoToJs(env, devInfos[i], item);
649         if (!devInfos[i].services.empty()) {
650             napi_value services = nullptr;
651             napi_create_array(env, &services);
652             bool isArray = false;
653             napi_is_array(env, services, &isArray);
654             if (!isArray) {
655                 LOGE("napi_create_array failed");
656             }
657             DmServiceProfileInfoToJsArray(env, devInfos[i].services, services);
658             napi_set_named_property(env, item, "services", services);
659         }
660         napi_status status = napi_set_element(env, arrayResult, i, item);
661         if (status != napi_ok) {
662             LOGE("DmDeviceProfileInfo To JsArray set element error: %{public}d", status);
663         }
664     }
665 }
666 
JsToDmDeviceIconInfoFilterOptions(const napi_env & env,const napi_value & object,DmDeviceIconInfoFilterOptions & info)667 void JsToDmDeviceIconInfoFilterOptions(const napi_env &env, const napi_value &object,
668     DmDeviceIconInfoFilterOptions &info)
669 {
670     napi_valuetype filterOptionsType;
671     napi_typeof(env, object, &filterOptionsType);
672     if (filterOptionsType != napi_object) {
673         LOGE("filterOptions is not object");
674         std::string errMsg = ERR_MESSAGE_INVALID_PARAMS + " The type of filterOptions must be object";
675         napi_throw_error(env, std::to_string(ERR_INVALID_PARAMS).c_str(), errMsg.c_str());
676         return;
677     }
678     char productId[DM_NAPI_BUF_LENGTH] = "";
679     JsObjectToString(env, object, "productId", productId, sizeof(productId));
680     info.productId = productId;
681     char subProductId[DM_NAPI_BUF_LENGTH] = "";
682     JsObjectToString(env, object, "subProductId", subProductId, sizeof(subProductId));
683     info.subProductId = subProductId;
684     char internalModel[DM_NAPI_BUF_LENGTH] = "";
685     JsObjectToString(env, object, "internalModel", internalModel, sizeof(internalModel));
686     info.internalModel = internalModel;
687     char imageType[DM_NAPI_BUF_LENGTH] = "";
688     JsObjectToString(env, object, "imageType", imageType, sizeof(imageType));
689     info.imageType = imageType;
690     char specName[DM_NAPI_BUF_LENGTH] = "";
691     JsObjectToString(env, object, "specName", specName, sizeof(specName));
692     info.specName = specName;
693 }
694 
DmDeviceIconInfoToJs(const napi_env & env,const DmDeviceIconInfo & deviceIconInfo,napi_value & jsObj)695 void DmDeviceIconInfoToJs(const napi_env &env, const DmDeviceIconInfo &deviceIconInfo, napi_value &jsObj)
696 {
697     SetValueUtf8String(env, "productId", deviceIconInfo.productId, jsObj);
698     SetValueUtf8String(env, "internalModel", deviceIconInfo.internalModel, jsObj);
699     SetValueUtf8String(env, "subProductId", deviceIconInfo.subProductId, jsObj);
700     SetValueUtf8String(env, "imageType", deviceIconInfo.imageType, jsObj);
701     SetValueUtf8String(env, "specName", deviceIconInfo.specName, jsObj);
702     SetValueUtf8String(env, "url", deviceIconInfo.url, jsObj);
703     size_t iconLen = deviceIconInfo.icon.size();
704     if (iconLen > 0) {
705         void *icon = nullptr;
706         napi_value iconBuffer = nullptr;
707         napi_create_arraybuffer(env, iconLen, &icon, &iconBuffer);
708         if (icon != nullptr &&
709             memcpy_s(icon, iconLen, reinterpret_cast<const void *>(deviceIconInfo.icon.data()), iconLen) == 0) {
710             napi_value iconArray = nullptr;
711             napi_create_typedarray(env, napi_uint8_array, iconLen, iconBuffer, 0, &iconArray);
712             napi_set_named_property(env, jsObj, "icon", iconArray);
713         }
714     }
715 }
716 
JsToDmServiceProfileInfo(const napi_env & env,const napi_value & jsObj,DmServiceProfileInfo & svrInfos)717 bool JsToDmServiceProfileInfo(const napi_env &env, const napi_value &jsObj, DmServiceProfileInfo &svrInfos)
718 {
719     napi_valuetype jsObjType;
720     napi_typeof(env, jsObj, &jsObjType);
721     if (jsObjType != napi_object) {
722         LOGE("jsObjType is not object");
723         return false;
724     }
725     svrInfos.serviceId = GetStrFromJsObj(env, jsObj, "sid");
726     svrInfos.serviceType = GetStrFromJsObj(env, jsObj, "st");
727     return true;
728 }
729 
GetServiceProfileInfosFromJsObj(const napi_env & env,const napi_value & jsObj,const std::string & fieldStr)730 std::vector<DmServiceProfileInfo> GetServiceProfileInfosFromJsObj(const napi_env &env, const napi_value &jsObj,
731     const std::string &fieldStr)
732 {
733     bool hasProperty = false;
734     napi_has_named_property(env, jsObj, fieldStr.c_str(), &hasProperty);
735     if (!hasProperty) {
736         return {};
737     }
738     napi_value jsServicesArray = nullptr;
739     napi_get_named_property(env, jsObj, fieldStr.c_str(), &jsServicesArray);
740     bool isArr = false;
741     napi_is_array(env, jsObj, &isArr);
742     if (!isArr) {
743         LOGE("object is not array");
744         return {};
745     }
746     std::vector<DmServiceProfileInfo> services = {};
747     uint32_t length = 0;
748     napi_get_array_length(env, jsServicesArray, &length);
749     for (size_t i = 0; i < length; i++) {
750         napi_value element;
751         napi_get_element(env, jsServicesArray, i, &element);
752         DmServiceProfileInfo svrInfo;
753         if (JsToDmServiceProfileInfo(env, jsServicesArray, svrInfo)) {
754             services.emplace_back(svrInfo);
755         }
756     }
757     return services;
758 }
759 
JsToDmDeviceProfileInfo(const napi_env & env,const napi_value & jsObj,DmDeviceProfileInfo & devInfo)760 bool JsToDmDeviceProfileInfo(const napi_env &env, const napi_value &jsObj, DmDeviceProfileInfo &devInfo)
761 {
762     napi_valuetype jsObjType;
763     napi_typeof(env, jsObj, &jsObjType);
764     if (jsObjType != napi_object) {
765         LOGE("jsObjType is not object");
766         return false;
767     }
768     devInfo.deviceId = GetStrFromJsObj(env, jsObj, "deviceId");
769     devInfo.deviceSn = GetStrFromJsObj(env, jsObj, "deviceSn");
770     devInfo.mac = GetStrFromJsObj(env, jsObj, "mac");
771     devInfo.model = GetStrFromJsObj(env, jsObj, "model");
772     devInfo.internalModel = GetStrFromJsObj(env, jsObj, "internalModel");
773     devInfo.deviceType = GetStrFromJsObj(env, jsObj, "deviceType");
774     devInfo.manufacturer = GetStrFromJsObj(env, jsObj, "manufacturer");
775     devInfo.deviceName = GetStrFromJsObj(env, jsObj, "deviceName");
776     devInfo.productName = GetStrFromJsObj(env, jsObj, "productName");
777     devInfo.productId = GetStrFromJsObj(env, jsObj, "productId");
778     devInfo.subProductId = GetStrFromJsObj(env, jsObj, "subProductId");
779     devInfo.sdkVersion = GetStrFromJsObj(env, jsObj, "sdkVersion");
780     devInfo.bleMac = GetStrFromJsObj(env, jsObj, "bleMac");
781     devInfo.brMac = GetStrFromJsObj(env, jsObj, "brMac");
782     devInfo.sleMac = GetStrFromJsObj(env, jsObj, "sleMac");
783     devInfo.firmwareVersion = GetStrFromJsObj(env, jsObj, "firmwareVersion");
784     devInfo.hardwareVersion = GetStrFromJsObj(env, jsObj, "hardwareVersion");
785     devInfo.softwareVersion = GetStrFromJsObj(env, jsObj, "softwareVersion");
786     devInfo.protocolType = GetIntFromJsObj(env, jsObj, "protocolType");
787     devInfo.setupType = GetIntFromJsObj(env, jsObj, "setupType");
788     devInfo.wiseDeviceId = GetStrFromJsObj(env, jsObj, "wiseDeviceId");
789     devInfo.registerTime = GetStrFromJsObj(env, jsObj, "registerTime");
790     devInfo.modifyTime = GetStrFromJsObj(env, jsObj, "modifyTime");
791     devInfo.shareTime = GetStrFromJsObj(env, jsObj, "shareTime");
792     devInfo.services = GetServiceProfileInfosFromJsObj(env, jsObj, "services");
793     for (auto &item : devInfo.services) {
794         item.deviceId = devInfo.deviceId;
795     }
796     return true;
797 }
798 
JsToDmDeviceProfileInfos(const napi_env & env,const napi_value & jsObj,std::vector<DmDeviceProfileInfo> & devInfos)799 bool JsToDmDeviceProfileInfos(const napi_env &env, const napi_value &jsObj, std::vector<DmDeviceProfileInfo> &devInfos)
800 {
801     bool isArr = false;
802     napi_is_array(env, jsObj, &isArr);
803     if (!isArr) {
804         LOGE("object is not array");
805         return false;
806     }
807     uint32_t length = 0;
808     napi_get_array_length(env, jsObj, &length);
809     for (size_t i = 0; i < length; i++) {
810         napi_value element;
811         napi_get_element(env, jsObj, i, &element);
812         DmDeviceProfileInfo devInfo;
813         if (JsToDmDeviceProfileInfo(env, element, devInfo)) {
814             devInfos.emplace_back(devInfo);
815         }
816     }
817     return true;
818 }
819 } // namespace DistributedHardware
820 } // namespace OHOS
821