1/*
2 * Copyright (c) 2023-2024 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 "profile_utils.h"
17
18#include <codecvt>
19#include <locale>
20#include <regex>
21#include <unordered_set>
22
23#include "cJSON.h"
24#include "device_manager.h"
25#include "dm_constants.h"
26#include "rdb_errno.h"
27
28#include "content_sensor_manager_utils.h"
29#include "distributed_device_profile_constants.h"
30#include "distributed_device_profile_enums.h"
31#include "distributed_device_profile_errors.h"
32#include "distributed_device_profile_log.h"
33
34namespace OHOS {
35namespace DistributedDeviceProfile {
36using namespace OHOS::DistributedHardware;
37
38namespace {
39    const std::string TAG = "ProfileUtils";
40    const std::unordered_set<std::string> NEED_ADD_OH_SUFFIX_DEV_PROFILES { OS_TYPE, OS_VERSION };
41    const std::unordered_set<std::string> NEED_ADD_OH_SUFFIX_SVR_NAMES { "DistributeModemService",
42        "multiScreenAssistantService", "appInfo" };
43}
44
45std::string ProfileUtils::GetDbKeyAnonyString(const std::string& dbKey)
46{
47    constexpr size_t DEVICE_ID_INDEX = 1;
48    std::vector<std::string> splitKeys;
49    if (ProfileUtils::SplitString(dbKey, SEPARATOR, splitKeys) != DP_SUCCESS ||
50        splitKeys.size() <= DEVICE_ID_INDEX) {
51        return GetAnonyString(dbKey);
52    }
53    for (size_t i = DEVICE_ID_INDEX; i < splitKeys.size(); i++) {
54        splitKeys[i] = GetAnonyString(splitKeys[i]);
55    }
56    return JoinString(splitKeys, SEPARATOR);
57}
58
59std::string ProfileUtils::GetAnonyString(const std::string& value)
60{
61    constexpr size_t INT32_SHORT_ID_LENGTH = 10;
62    constexpr size_t INT32_PLAINTEXT_LENGTH = 4;
63    constexpr size_t INT32_MIN_ID_LENGTH = 3;
64    std::string res;
65    std::string tmpStr("***");
66    size_t strLen = value.length();
67    if (strLen < INT32_MIN_ID_LENGTH) {
68        return tmpStr;
69    }
70
71    if (strLen <= INT32_SHORT_ID_LENGTH) {
72        res += value[0];
73        res += tmpStr;
74        res += value[strLen - 1];
75    } else {
76        res.append(value, 0, INT32_PLAINTEXT_LENGTH);
77        res += tmpStr;
78        res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
79    }
80    return res;
81}
82
83std::vector<std::string> ProfileUtils::GetOnlineDevices()
84{
85    std::vector<std::string> targetDevices;
86    std::vector<DmDeviceInfo> allOnlineDeviceInfos;
87    int32_t result = DeviceManager::GetInstance().GetTrustedDeviceList(DP_PKG_NAME, "", allOnlineDeviceInfos);
88    if (result != DP_SUCCESS || allOnlineDeviceInfos.empty()) {
89        HILOGE("GetTrustedDeviceList Failed!");
90        return {};
91    }
92    for (const DmDeviceInfo& dmDeviceInfo : allOnlineDeviceInfos) {
93        targetDevices.push_back(dmDeviceInfo.networkId);
94    }
95    return targetDevices;
96}
97
98std::string ProfileUtils::GetLocalUdidFromDM()
99{
100    std::string udid = "";
101    if (DeviceManager::GetInstance().GetLocalDeviceId(DP_PKG_NAME, udid) != DP_SUCCESS) {
102        HILOGE("Get local udid fail from DM!");
103        return "";
104    }
105    return udid;
106}
107
108bool ProfileUtils::FilterAndGroupOnlineDevices(const std::vector<std::string>& deviceList,
109    std::vector<std::string>& ohBasedDevices, std::vector<std::string>& notOHBasedDevices)
110{
111    if (deviceList.size() == 0 || deviceList.size() > MAX_DEVICE_SIZE) {
112        HILOGE("This deviceList size is invalid, size: %{public}zu!", deviceList.size());
113        return false;
114    }
115    std::vector<DmDeviceInfo> allOnlineDeviceInfos;
116    int32_t result = DeviceManager::GetInstance().GetTrustedDeviceList(DP_PKG_NAME, "", allOnlineDeviceInfos);
117    if (result != DP_SUCCESS || allOnlineDeviceInfos.empty()) {
118        HILOGE("GetTrustedDeviceList Failed!");
119        return false;
120    }
121    for (const DmDeviceInfo& dmDeviceInfo : allOnlineDeviceInfos) {
122        if (std::find(deviceList.begin(), deviceList.end(), dmDeviceInfo.networkId) == deviceList.end()) {
123            continue;
124        }
125        if (dmDeviceInfo.extraData.empty()) {
126            HILOGW("extraData is empty! networkId:%{public}s", GetAnonyString(dmDeviceInfo.networkId).c_str());
127            continue;
128        }
129        if (IsOHBasedDevice(dmDeviceInfo.extraData)) {
130            ohBasedDevices.push_back(dmDeviceInfo.networkId);
131        } else {
132            notOHBasedDevices.push_back(dmDeviceInfo.networkId);
133        }
134    }
135    return true;
136}
137
138bool ProfileUtils::IsOHBasedDevice(const std::string& extraData)
139{
140    if (extraData.empty()) {
141        HILOGE("extraData is empty!");
142        return false;
143    }
144    cJSON* extraDataJson = cJSON_Parse(extraData.c_str());
145    if (extraDataJson == NULL) {
146        HILOGE("extraData parse failed");
147        return false;
148    }
149    int32_t osType = OHOS_TYPE_UNKNOWN;
150    cJSON* osTypeJson = cJSON_GetObjectItem(extraDataJson, DistributedHardware::PARAM_KEY_OS_TYPE);
151    if (cJSON_IsNumber(osTypeJson)) {
152        osType = static_cast<int32_t>(osTypeJson->valueint);
153    }
154    cJSON_Delete(extraDataJson);
155    return osType == OHOS_TYPE;
156}
157
158bool ProfileUtils::IsP2p(const int32_t authForm)
159{
160    if (authForm == static_cast<int32_t>(DistributedHardware::DmAuthForm::INVALID_TYPE) ||
161        authForm == static_cast<int32_t>(DistributedHardware::DmAuthForm::IDENTICAL_ACCOUNT)) {
162        HILOGD("authForm: %{public}d!", authForm);
163        return false;
164    }
165    return true;
166}
167
168ProfileType ProfileUtils::GetProfileType(const std::string& key)
169{
170    if (key.length() == 0 || key.length() > MAX_STRING_LEN) {
171        HILOGE("This key is invalid, value: %{public}s!", GetAnonyString(key).c_str());
172        return ProfileType::PROFILE_TYPE_MIN;
173    }
174    ProfileType profileType = ProfileType::PROFILE_TYPE_MIN;
175    if (StartsWith(key, DEV_PREFIX)) {
176        profileType = ProfileType::DEVICE_PROFILE;
177    }
178    if (StartsWith(key, SVR_PREFIX)) {
179        profileType = ProfileType::SERVICE_PROFILE;
180    }
181    if (StartsWith(key, CHAR_PREFIX)) {
182        profileType = ProfileType::CHAR_PROFILE;
183    }
184    return profileType;
185}
186
187bool ProfileUtils::StartsWith(const std::string& str, const std::string& prefix)
188{
189    return (str.find(prefix, 0) == 0);
190}
191
192bool ProfileUtils::EndsWith(const std::string& str, const std::string& suffix)
193{
194    if (str.length() < suffix.length()) {
195        return false;
196    }
197    return str.substr(str.length() - suffix.length()).compare(suffix) == 0;
198}
199
200std::string ProfileUtils::GetProfileKey(const std::string& dbKey)
201{
202    if (dbKey.length() == 0 || dbKey.length() > MAX_STRING_LEN) {
203        return "";
204    }
205    std::size_t pos = dbKey.find_last_of("#");
206    return dbKey.substr(0, pos);
207}
208
209std::string ProfileUtils::GetDeviceIdByDBKey(const std::string& dbKey)
210{
211    if (dbKey.length() == 0 || dbKey.length() > MAX_STRING_LEN) {
212        return "";
213    }
214    std::vector<std::string> res;
215    if (SplitString(dbKey, SEPARATOR, res) != DP_SUCCESS) {
216        return "";
217    }
218    if (res.size() < NUM_1) {
219        return "";
220    }
221    return res[NUM_1];
222}
223
224std::string ProfileUtils::GetServiceNameByDBKey(const std::string& dbKey)
225{
226    if (dbKey.length() == 0 || dbKey.length() > MAX_STRING_LEN) {
227        return "";
228    }
229    std::vector<std::string> res;
230    if (SplitString(dbKey, SEPARATOR, res) != DP_SUCCESS) {
231        return "";
232    }
233    if (res.size() < NUM_2) {
234        return "";
235    }
236    return res[NUM_2];
237}
238
239std::string ProfileUtils::GetNonOhSuffixServiceNameByDBKey(const std::string& dbKey)
240{
241    std::string serviceName = GetServiceNameByDBKey(dbKey);
242    if (serviceName.empty()) {
243        return "";
244    }
245    return CheckAndRemoveOhSuffix(serviceName);
246}
247
248bool ProfileUtils::IsNeedAddOhSuffix(const std::string& profileName, bool isSvr)
249{
250    if (profileName.length() == 0 || profileName.length() > MAX_STRING_LEN) {
251        return false;
252    }
253    if (isSvr && NEED_ADD_OH_SUFFIX_SVR_NAMES.count(profileName) > 0) {
254        return true;
255    }
256    if (!isSvr && NEED_ADD_OH_SUFFIX_DEV_PROFILES.count(profileName) > 0) {
257        return true;
258    }
259    return false;
260}
261
262std::string ProfileUtils::CheckAndAddOhSuffix(const std::string& profileName, bool isSvr)
263{
264    std::string str = profileName;
265    if (IsNeedAddOhSuffix(str, isSvr)) {
266        str = str + OH_PROFILE_SUFFIX;
267    }
268    return str;
269}
270
271std::string ProfileUtils::CheckAndRemoveOhSuffix(const std::string& profileName)
272{
273    std::string str = profileName;
274    if (EndsWith(str, OH_PROFILE_SUFFIX)) {
275        str = str.erase(str.length() - OH_PROFILE_SUFFIX.length());
276    }
277    return str;
278}
279
280std::string ProfileUtils::GetCharKeyByDBKey(const std::string& dbKey)
281{
282    if (dbKey.length() == 0 || dbKey.length() > MAX_STRING_LEN) {
283        return "";
284    }
285    std::vector<std::string> res;
286    if (SplitString(dbKey, SEPARATOR, res) != DP_SUCCESS) {
287        return "";
288    }
289    if (res.size() < NUM_3) {
290        return "";
291    }
292    return res[NUM_3];
293}
294
295int32_t ProfileUtils::SplitString(const std::string& str, const std::string& splits, std::vector<std::string>& res)
296{
297    if (str == "") {
298        return DP_INVALID_PARAMS;
299    }
300    std::string strs = str + splits;
301    size_t pos = strs.find(splits);
302    int32_t step = splits.size();
303
304    while (pos != strs.npos) {
305        std::string temp = strs.substr(0, pos);
306        res.push_back(temp);
307        strs = strs.substr(pos + step, strs.size());
308        pos = strs.find(splits);
309    }
310    return DP_SUCCESS;
311}
312
313std::string ProfileUtils::JoinString(const std::vector<std::string>& strs, const std::string& delimiter)
314{
315    std::string res = EMPTY_STRING;
316    if (strs.empty()) {
317        return res;
318    }
319    for (size_t i = 0; i < strs.size(); i++) {
320        res += strs[i];
321        if (i != strs.size() - 1) {
322            res += delimiter;
323        }
324    }
325    return res;
326}
327
328bool ProfileUtils::IsKeyValid(const std::string& key)
329{
330    if (key.length() == 0 || key.length() > MAX_STRING_LEN) {
331        return false;
332    }
333    size_t found = key.find(SEPARATOR);
334    if (found != std::string::npos) {
335        return false;
336    }
337    return true;
338}
339
340bool ProfileUtils::IsLocalUdid(const std::string& udid)
341{
342    if (udid.length() == 0 || udid.length() > MAX_STRING_LEN) {
343        return false;
344    }
345    std::string localUdid = ContentSensorManagerUtils::GetInstance().ObtainLocalUdid();
346    return localUdid == udid;
347}
348
349bool ProfileUtils::IsDevProfileValid(const DeviceProfile& devProfile)
350{
351    return IsKeyValid(devProfile.GetDeviceId()) && IsLocalUdid(devProfile.GetDeviceId());
352}
353
354bool ProfileUtils::IsSvrProfileValid(const ServiceProfile& svrProfile)
355{
356    return IsKeyValid(svrProfile.GetDeviceId()) && IsLocalUdid(svrProfile.GetDeviceId()) &&
357        IsKeyValid(svrProfile.GetServiceName());
358}
359
360bool ProfileUtils::IsCharProfileValid(const CharacteristicProfile& charProfile)
361{
362    return IsKeyValid(charProfile.GetDeviceId()) && IsLocalUdid(charProfile.GetDeviceId()) &&
363        IsKeyValid(charProfile.GetServiceName()) && IsKeyValid(charProfile.GetCharacteristicKey());
364}
365
366bool ProfileUtils::IsDeviceProfileValid(const DeviceProfile& devProfile)
367{
368    if (devProfile.GetOsVersion().empty() || devProfile.GetOsType() == MIN_OS_TYPE) {
369        return false;
370    }
371    return true;
372}
373
374bool ProfileUtils::IsServiceProfileValid(const ServiceProfile& svrProfile)
375{
376    if (svrProfile.GetServiceName().empty() || svrProfile.GetServiceType().empty()) {
377        return false;
378    }
379    return true;
380}
381
382bool ProfileUtils::IsCharacteristicProfileValid(const CharacteristicProfile& charProfile)
383{
384    if (charProfile.GetCharacteristicKey().empty() || charProfile.GetCharacteristicValue().empty()) {
385        return false;
386    }
387    return true;
388}
389
390std::string ProfileUtils::GenerateDeviceProfileKey(const std::string& deviceId)
391{
392    return DEV_PREFIX + SEPARATOR + deviceId;
393}
394
395std::string ProfileUtils::GenerateServiceProfileKey(const std::string& deviceId, const std::string& serviceName)
396{
397    return SVR_PREFIX + SEPARATOR + deviceId + SEPARATOR + serviceName;
398}
399
400std::string ProfileUtils::GenerateCharProfileKey(const std::string& deviceId, const std::string& serviceName,
401    const std::string& charKey)
402{
403    return CHAR_PREFIX + SEPARATOR + deviceId + SEPARATOR + serviceName + SEPARATOR + charKey;
404}
405
406int32_t ProfileUtils::TrustDeviceProfileToEntries(const TrustDeviceProfile& profile, ValuesBucket& values)
407{
408    values.PutString(DEVICE_ID, profile.GetDeviceId());
409    values.PutInt(DEVICE_ID_TYPE, profile.GetDeviceIdType());
410    values.PutString(DEVICE_ID_HASH, profile.GetDeviceIdHash());
411    values.PutInt(STATUS, profile.GetStatus());
412    return DP_SUCCESS;
413}
414
415int32_t ProfileUtils::AccessControlProfileToEntries(const AccessControlProfile& profile, ValuesBucket& values)
416{
417    values.PutLong(ACCESS_CONTROL_ID, profile.GetAccessControlId());
418    values.PutLong(ACCESSER_ID, profile.GetAccesserId());
419    values.PutLong(ACCESSEE_ID, profile.GetAccesseeId());
420    values.PutString(TRUST_DEVICE_ID, profile.GetTrustDeviceId());
421    values.PutInt(AUTHENTICATION_TYPE, profile.GetAuthenticationType());
422    values.PutInt(DEVICE_ID_TYPE, profile.GetDeviceIdType());
423    values.PutString(DEVICE_ID_HASH, profile.GetDeviceIdHash());
424    values.PutInt(BIND_TYPE, profile.GetBindType());
425    values.PutString(SESSION_KEY, profile.GetSessionKey());
426    values.PutInt(LAST_AUTH_TIME, profile.GetLastAuthTime());
427    values.PutInt(VALID_PERIOD, profile.GetValidPeriod());
428    values.PutInt(STATUS, profile.GetStatus());
429    values.PutInt(BIND_LEVEL, profile.GetBindLevel());
430    return DP_SUCCESS;
431}
432
433int32_t ProfileUtils::AccesserToEntries(const AccessControlProfile& aclProfile, ValuesBucket& values)
434{
435    Accesser accesser = aclProfile.GetAccesser();
436    values.PutLong(ACCESSER_ID, accesser.GetAccesserId());
437    values.PutString(ACCESSER_DEVICE_ID, accesser.GetAccesserDeviceId());
438    values.PutInt(ACCESSER_USER_ID, accesser.GetAccesserUserId());
439    values.PutString(ACCESSER_ACCOUNT_ID, accesser.GetAccesserAccountId());
440    values.PutLong(ACCESSER_TOKEN_ID, accesser.GetAccesserTokenId());
441    values.PutString(ACCESSER_BUNDLE_NAME, accesser.GetAccesserBundleName());
442    values.PutString(ACCESSER_HAP_SIGNATURE, accesser.GetAccesserHapSignature());
443    values.PutInt(ACCESSER_BIND_LEVEL, accesser.GetAccesserBindLevel());
444    return DP_SUCCESS;
445}
446
447int32_t ProfileUtils::AccesseeToEntries(const AccessControlProfile& aclProfile, ValuesBucket& values)
448{
449    Accessee accessee = aclProfile.GetAccessee();
450    values.PutLong(ACCESSEE_ID, accessee.GetAccesseeId());
451    values.PutString(ACCESSEE_DEVICE_ID, accessee.GetAccesseeDeviceId());
452    values.PutInt(ACCESSEE_USER_ID, accessee.GetAccesseeUserId());
453    values.PutString(ACCESSEE_ACCOUNT_ID, accessee.GetAccesseeAccountId());
454    values.PutLong(ACCESSEE_TOKEN_ID, accessee.GetAccesseeTokenId());
455    values.PutString(ACCESSEE_BUNDLE_NAME, accessee.GetAccesseeBundleName());
456    values.PutString(ACCESSEE_HAP_SIGNATURE, accessee.GetAccesseeHapSignature());
457    values.PutInt(ACCESSEE_BIND_LEVEL, accessee.GetAccesseeBindLevel());
458    return DP_SUCCESS;
459}
460
461int32_t ProfileUtils::DeviceProfileToEntries(const DeviceProfile& profile, std::map<std::string, std::string>& values)
462{
463    std::string deviceProfileKey = GenerateDeviceProfileKey(profile.GetDeviceId());
464    values[GenerateDBKey(deviceProfileKey, OS_SYS_CAPACITY)] = profile.GetOsSysCap();
465    values[GenerateDBKey(deviceProfileKey, OS_VERSION)] = profile.GetOsVersion();
466    values[GenerateDBKey(deviceProfileKey, OS_TYPE)] = std::to_string(profile.GetOsType());
467    values[GenerateDBKey(deviceProfileKey, OS_VERSION + OH_PROFILE_SUFFIX)] = profile.GetOsVersion();
468    values[GenerateDBKey(deviceProfileKey, OS_TYPE + OH_PROFILE_SUFFIX)] = std::to_string(profile.GetOsType());
469    return DP_SUCCESS;
470}
471
472int32_t ProfileUtils::ServiceProfileToEntries(const ServiceProfile& profile, std::map<std::string, std::string>& values)
473{
474    std::string serviceName = CheckAndAddOhSuffix(profile.GetServiceName(), true);
475    std::string serviceProfileKey = GenerateServiceProfileKey(profile.GetDeviceId(), serviceName);
476    // value not need add OH suffix
477    values[GenerateDBKey(serviceProfileKey, SERVICE_NAME)] = profile.GetServiceName();
478    values[GenerateDBKey(serviceProfileKey, SERVICE_TYPE)] = profile.GetServiceType();
479    return DP_SUCCESS;
480}
481
482int32_t ProfileUtils::CharacteristicProfileToEntries(const CharacteristicProfile& profile,
483                                                     std::map<std::string, std::string>& values)
484{
485    std::string serviceName = CheckAndAddOhSuffix(profile.GetServiceName(), true);
486    std::string charProfileKey = GenerateCharProfileKey(profile.GetDeviceId(), serviceName,
487        profile.GetCharacteristicKey());
488    values[GenerateDBKey(charProfileKey, CHARACTERISTIC_KEY)] = profile.GetCharacteristicKey();
489    values[GenerateDBKey(charProfileKey, CHARACTERISTIC_VALUE)] = profile.GetCharacteristicValue();
490    return DP_SUCCESS;
491}
492
493int32_t ProfileUtils::EntriesToTrustDeviceProfile(const ValuesBucket& values, TrustDeviceProfile& profile)
494{
495    ValueObject valueObject;
496    std::string strValue = "";
497    int32_t intValue = 0;
498    if (values.GetObject(DEVICE_ID, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
499        profile.SetDeviceId(strValue);
500    }
501    if (values.GetObject(DEVICE_ID_HASH, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
502        profile.SetDeviceIdHash(strValue);
503    }
504    if (values.GetObject(DEVICE_TYPE_ID, valueObject) && valueObject.GetInt(intValue) == NativeRdb::E_OK) {
505        profile.SetDeviceIdType(intValue);
506    }
507    if (values.GetObject(STATUS, valueObject) && valueObject.GetInt(intValue) == NativeRdb::E_OK) {
508        profile.SetStatus(intValue);
509    }
510    return DP_SUCCESS;
511}
512
513int32_t ProfileUtils::EntriesToAccessControlProfile(const ValuesBucket& values, AccessControlProfile& profile)
514{
515    std::string strValue = "";
516    int32_t intValue = 0;
517    int64_t int64Value = 0;
518    if (GetLongValue(values, ACCESS_CONTROL_ID, int64Value)) {
519        profile.SetAccessControlId(int64Value);
520    }
521    if (GetLongValue(values, ACCESSER_ID, int64Value)) {
522        profile.SetAccesserId(int64Value);
523    }
524    if (GetLongValue(values, ACCESSEE_ID, int64Value)) {
525        profile.SetAccesseeId(int64Value);
526    }
527    if (GetStringValue(values, SESSION_KEY, strValue)) {
528        profile.SetSessionKey(strValue);
529    }
530    if (GetIntValue(values, BIND_TYPE, intValue)) {
531        profile.SetBindType(intValue);
532    }
533    if (GetIntValue(values, AUTHENTICATION_TYPE, intValue)) {
534        profile.SetAuthenticationType(intValue);
535    }
536    if (GetIntValue(values, BIND_LEVEL, intValue)) {
537        profile.SetBindLevel(intValue);
538    }
539    if (GetIntValue(values, STATUS, intValue)) {
540        profile.SetStatus(intValue);
541    }
542    if (GetIntValue(values, VALID_PERIOD, intValue)) {
543        profile.SetValidPeriod(intValue);
544    }
545    if (GetIntValue(values, LAST_AUTH_TIME, intValue)) {
546        profile.SetLastAuthTime(intValue);
547    }
548    if (GetStringValue(values, TRUST_DEVICE_ID, strValue)) {
549        profile.SetTrustDeviceId(strValue);
550    }
551    if (GetIntValue(values, DEVICE_TYPE_ID, intValue)) {
552        profile.SetDeviceIdType(intValue);
553    }
554    if (GetStringValue(values, DEVICE_ID_HASH, strValue)) {
555        profile.SetDeviceIdHash(strValue);
556    }
557    return DP_SUCCESS;
558}
559
560int32_t ProfileUtils::EntriesToAccesser(const ValuesBucket& values, Accesser& accesser)
561{
562    ValueObject valueObject;
563    std::string strValue = "";
564    int32_t intValue = 0;
565    int64_t int64Value = 0;
566    if (values.GetObject(ACCESSER_ID, valueObject) && valueObject.GetLong(int64Value) == NativeRdb::E_OK) {
567        accesser.SetAccesserId(int64Value);
568    }
569    if (values.GetObject(ACCESSER_DEVICE_ID, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
570        accesser.SetAccesserDeviceId(strValue);
571    }
572    if (values.GetObject(ACCESSER_USER_ID, valueObject) && valueObject.GetInt(intValue) == NativeRdb::E_OK) {
573        accesser.SetAccesserUserId(intValue);
574    }
575    if (values.GetObject(ACCESSER_ACCOUNT_ID, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
576        accesser.SetAccesserAccountId(strValue);
577    }
578    if (values.GetObject(ACCESSER_TOKEN_ID, valueObject) && valueObject.GetLong(int64Value) == NativeRdb::E_OK) {
579        accesser.SetAccesserTokenId(int64Value);
580    }
581    if (values.GetObject(ACCESSER_BUNDLE_NAME, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
582        accesser.SetAccesserBundleName(strValue);
583    }
584    if (values.GetObject(ACCESSER_BIND_LEVEL, valueObject) && valueObject.GetInt(intValue) == NativeRdb::E_OK) {
585        accesser.SetAccesserBindLevel(intValue);
586    }
587    return DP_SUCCESS;
588}
589
590int32_t ProfileUtils::EntriesToAccessee(const ValuesBucket& values, Accessee& accessee)
591{
592    ValueObject valueObject;
593    std::string strValue = "";
594    int32_t intValue = 0;
595    int64_t int64Value = 0;
596    if (values.GetObject(ACCESSEE_ID, valueObject) && valueObject.GetLong(int64Value) == NativeRdb::E_OK) {
597        accessee.SetAccesseeId(int64Value);
598    }
599    if (values.GetObject(ACCESSEE_DEVICE_ID, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
600        accessee.SetAccesseeDeviceId(strValue);
601    }
602    if (values.GetObject(ACCESSEE_USER_ID, valueObject) && valueObject.GetInt(intValue) == NativeRdb::E_OK) {
603        accessee.SetAccesseeUserId(intValue);
604    }
605    if (values.GetObject(ACCESSEE_ACCOUNT_ID, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
606        accessee.SetAccesseeAccountId(strValue);
607    }
608    if (values.GetObject(ACCESSEE_TOKEN_ID, valueObject) && valueObject.GetLong(int64Value) == NativeRdb::E_OK) {
609        accessee.SetAccesseeTokenId(int64Value);
610    }
611    if (values.GetObject(ACCESSEE_BUNDLE_NAME, valueObject) && valueObject.GetString(strValue) == NativeRdb::E_OK) {
612        accessee.SetAccesseeBundleName(strValue);
613    }
614    if (values.GetObject(ACCESSEE_BIND_LEVEL, valueObject) && valueObject.GetInt(intValue) == NativeRdb::E_OK) {
615        accessee.SetAccesseeBindLevel(intValue);
616    }
617    return DP_SUCCESS;
618}
619
620int32_t ProfileUtils::EntriesToDeviceProfile(std::map<std::string, std::string> values, DeviceProfile& profile)
621{
622    if (values.empty() || values.size() > MAX_DB_RECORD_SIZE) {
623        HILOGI("Entries size is invalid!size: %{public}zu!", values.size());
624        return DP_INVALID_PARAMS;
625    }
626    auto propertiesMap = GetProfilePropertiesMap(values);
627    if (IsPropertyValid(propertiesMap, OS_SYS_CAPACITY, MAX_STRING_LEN)) {
628        profile.SetOsSysCap(propertiesMap[OS_SYS_CAPACITY]);
629    }
630    if (IsPropertyValid(propertiesMap, OS_VERSION, MAX_STRING_LEN)) {
631        profile.SetOsVersion(propertiesMap[OS_VERSION]);
632    }
633    if (IsPropertyValid(propertiesMap, OS_VERSION + OH_PROFILE_SUFFIX, MAX_STRING_LEN)) {
634        profile.SetOsVersion(propertiesMap[OS_VERSION + OH_PROFILE_SUFFIX]);
635    }
636    if (IsPropertyValid(propertiesMap, OS_TYPE, MIN_OS_TYPE, MAX_OS_TYPE)) {
637        int32_t osType = std::atoi(propertiesMap[OS_TYPE].c_str());
638        profile.SetOsType(osType);
639    }
640    if (IsPropertyValid(propertiesMap, OS_TYPE + OH_PROFILE_SUFFIX, MIN_OS_TYPE, MAX_OS_TYPE)) {
641        int32_t osType = std::atoi(propertiesMap[OS_TYPE + OH_PROFILE_SUFFIX].c_str());
642        profile.SetOsType(osType);
643    }
644    return DP_SUCCESS;
645}
646
647int32_t ProfileUtils::EntriesToServiceProfile(std::map<std::string, std::string> values, ServiceProfile& profile)
648{
649    if (values.empty() || values.size() > MAX_DB_RECORD_SIZE) {
650        HILOGI("Entries size is invalid!size: %{public}zu!", values.size());
651        return DP_INVALID_PARAMS;
652    }
653    auto iter = values.begin();
654    profile.SetDeviceId(GetDeviceIdByDBKey(iter->first));
655    auto propertiesMap = GetProfilePropertiesMap(values);
656    if (propertiesMap.count(SERVICE_NAME) != 0 && 0 < propertiesMap[SERVICE_NAME].length() &&
657        propertiesMap[SERVICE_NAME].length() < MAX_STRING_LEN) {
658        profile.SetServiceName(CheckAndRemoveOhSuffix(propertiesMap[SERVICE_NAME]));
659    }
660    if (propertiesMap.count(SERVICE_TYPE) != 0 && 0 < propertiesMap[SERVICE_TYPE].length() &&
661        propertiesMap[SERVICE_TYPE].length() < MAX_STRING_LEN) {
662        profile.SetServiceType(propertiesMap[SERVICE_TYPE]);
663    }
664    return DP_SUCCESS;
665}
666
667int32_t ProfileUtils::EntriesToCharProfile(std::map<std::string, std::string> values, CharacteristicProfile& profile)
668{
669    if (values.empty() || values.size() > MAX_DB_RECORD_SIZE) {
670        HILOGI("Entries size is invalid!size : %{public}zu", values.size());
671        return DP_INVALID_PARAMS;
672    }
673    auto iter = values.begin();
674    profile.SetDeviceId(GetDeviceIdByDBKey(iter->first));
675    profile.SetServiceName(GetNonOhSuffixServiceNameByDBKey(iter->first));
676    auto propertiesMap = GetProfilePropertiesMap(values);
677    if (propertiesMap.count(CHARACTERISTIC_KEY) != 0 && 0 < propertiesMap[CHARACTERISTIC_KEY].length() &&
678        propertiesMap[CHARACTERISTIC_KEY].length() < MAX_STRING_LEN) {
679        profile.SetCharacteristicKey(propertiesMap[CHARACTERISTIC_KEY]);
680    }
681    if (propertiesMap.count(CHARACTERISTIC_VALUE) != 0 && 0 < propertiesMap[CHARACTERISTIC_VALUE].length() &&
682        propertiesMap[CHARACTERISTIC_VALUE].length() < MAX_STRING_LEN) {
683        profile.SetCharacteristicValue(propertiesMap[CHARACTERISTIC_VALUE]);
684    }
685    return DP_SUCCESS;
686}
687
688std::string ProfileUtils::GenerateDBKey(const std::string& profileKey, const std::string& profileProperty)
689{
690    return profileKey + SEPARATOR + profileProperty;
691}
692
693std::string ProfileUtils::GetProfileProperty(const std::string& dbKey)
694{
695    if (dbKey.length() == 0 || dbKey.length() > MAX_STRING_LEN) {
696        return "";
697    }
698    std::size_t pos = dbKey.find_last_of("#");
699    if (pos == std::string::npos) {
700        return "";
701    }
702    return dbKey.substr(pos + 1);
703}
704
705std::map<std::string, std::string> ProfileUtils::GetProfilePropertiesMap(std::map<std::string, std::string> dbEntries)
706{
707    std::map<std::string, std::string> propertiesMap;
708    for (const auto& item : dbEntries) {
709        std::string profileProperty = GetProfileProperty(item.first);
710        if (profileProperty.empty()) {
711            HILOGE("GetProfileProperty fail, %{public}s!", GetDbKeyAnonyString(item.first).c_str());
712            continue;
713        }
714        propertiesMap[profileProperty] = item.second;
715    }
716    return propertiesMap;
717}
718
719std::string ProfileUtils::toString(const std::u16string& str16)
720{
721    return std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.to_bytes(str16);
722}
723
724bool ProfileUtils::IsPropertyValid(const std::map<std::string, std::string>& propertyMap, const std::string& property,
725    int32_t maxValue)
726{
727    if (propertyMap.count(property) != 0 && 0 < propertyMap.at(property).length() &&
728        (static_cast<int32_t>(propertyMap.at(property).length())) < maxValue) {
729        return true;
730    }
731    HILOGE("property is valid, property : %{public}s", property.c_str());
732    return false;
733}
734
735bool ProfileUtils::IsPropertyValid(const std::map<std::string, std::string>& propertyMap, const std::string& property,
736    int32_t minValue, int32_t maxValue)
737{
738    if (property.empty() || propertyMap.find(property) == propertyMap.end()) {
739        HILOGE("property is valid, property : %{public}s", property.c_str());
740        return false;
741    }
742    std::string propertyValue = propertyMap.at(property);
743    if (!IsNumStr(propertyValue)) {
744        HILOGE("%{public}s is not numeric string", GetAnonyString(propertyValue).c_str());
745        return false;
746    }
747    if (minValue < std::atoi(propertyValue.c_str()) && std::atoi(propertyValue.c_str()) < maxValue) {
748        return true;
749    }
750    return false;
751}
752
753bool ProfileUtils::IsNumStr(const std::string& inString)
754{
755    if (inString.empty()) {
756        HILOGE("inString is empty");
757        return false;
758    }
759    std::regex isNumStrRule(IS_NUMSTRING_RULES);
760    return std::regex_match(inString, isNumStrRule);
761}
762
763bool ProfileUtils::GetIntValue(const ValuesBucket& values, const std::string& property, int32_t& value)
764{
765    ValueObject valueObject;
766    if (values.GetObject(property, valueObject) && valueObject.GetInt(value) == NativeRdb::E_OK) {
767        return true;
768    }
769    return false;
770}
771
772bool ProfileUtils::GetStringValue(const ValuesBucket& values, const std::string& property, std::string& value)
773{
774    ValueObject valueObject;
775    if (values.GetObject(property, valueObject) && valueObject.GetString(value) == NativeRdb::E_OK) {
776        return true;
777    }
778    return false;
779}
780
781bool ProfileUtils::GetLongValue(const ValuesBucket& values, const std::string& property, int64_t& value)
782{
783    ValueObject valueObject;
784    if (values.GetObject(property, valueObject) && valueObject.GetLong(value) == NativeRdb::E_OK) {
785        return true;
786    }
787    return false;
788}
789
790bool ProfileUtils::GetUdidByNetworkId(const std::string& networkId, std::string& udid)
791{
792    return ((DeviceManager::GetInstance().GetUdidByNetworkId(DP_PKG_NAME, networkId, udid) == 0) ? true : false);
793}
794
795bool ProfileUtils::GetUuidByNetworkId(const std::string& networkId, std::string& uuid)
796{
797    return ((DeviceManager::GetInstance().GetUuidByNetworkId(DP_PKG_NAME, networkId, uuid) == 0) ? true : false);
798}
799
800std::string ProfileUtils::GetDbKeyByProfile(const CharacteristicProfile& profile)
801{
802    if (profile.GetDeviceId().empty() ||
803        profile.GetServiceName().empty() ||
804        profile.GetCharacteristicKey().empty()) {
805        HILOGE("GetDbKeyByProfile fail");
806        return "";
807    }
808    std::string serviceName = CheckAndAddOhSuffix(profile.GetServiceName(), true);
809    std::string dbKey = CHAR_PREFIX + SEPARATOR + profile.GetDeviceId() + SEPARATOR + serviceName +
810        SEPARATOR + profile.GetCharacteristicKey() + SEPARATOR + CHARACTERISTIC_VALUE;
811    return dbKey;
812}
813} // namespace DistributedDeviceProfile
814} // namespace OHOS
815