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 ¶m, 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 ¶mName, 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