1 /*
2  * Copyright (c) 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 <dlfcn.h>
17 #include <fstream>
18 #include <regex>
19 
20 #include "static_capability_loader.h"
21 
22 #include "config_policy_utils.h"
23 #include "content_sensor_manager_utils.h"
24 #include "distributed_device_profile_constants.h"
25 #include "distributed_device_profile_enums.h"
26 #include "distributed_device_profile_errors.h"
27 #include "i_static_capability_collector.h"
28 #include "profile_utils.h"
29 
30 namespace OHOS {
31 namespace DistributedDeviceProfile {
32 IMPLEMENT_SINGLE_INSTANCE(StaticCapabilityLoader);
33 namespace {
34     const std::string TAG = "StaticCapabilityLoader";
35 }
36 using StaticCapabilityHandler = IStaticCapabilityCollector *(*)();
Init()37 int32_t StaticCapabilityLoader::Init()
38 {
39     HILOGI("call!");
40     return DP_SUCCESS;
41 }
42 
UnInit()43 int32_t StaticCapabilityLoader::UnInit()
44 {
45     HILOGI("call!");
46     return DP_SUCCESS;
47 }
48 
LoadStaticCapability(std::string & staticCapability)49 int32_t StaticCapabilityLoader::LoadStaticCapability(std::string& staticCapability)
50 {
51     HILOGD("call!");
52     std::string fileContent = "";
53     int32_t loadJsonResult = LoadJsonFile(STATIC_CAPABILITY_PATH, fileContent);
54     if (loadJsonResult != DP_SUCCESS) {
55         HILOGE("Load json failed, result: %{public}d!", loadJsonResult);
56         return loadJsonResult;
57     }
58     cJSON* staticCapabilityJson = cJSON_Parse(fileContent.c_str());
59     if (!cJSON_IsObject(staticCapabilityJson)) {
60         HILOGE("Static capability json parse failed!");
61         cJSON_Delete(staticCapabilityJson);
62         return DP_LOAD_STATIC_CAP_FAIL;
63     }
64     int32_t getCapResult = GetStaticCapability(staticCapabilityJson, staticCapability);
65     if (getCapResult != DP_SUCCESS) {
66         HILOGE("Get static capability result %{public}d!", getCapResult);
67         cJSON_Delete(staticCapabilityJson);
68         return getCapResult;
69     }
70     HILOGI("success!");
71     cJSON_Delete(staticCapabilityJson);
72     return DP_SUCCESS;
73 }
74 
LoadJsonFile(const std::string & filePath,std::string & fileContent)75 int32_t StaticCapabilityLoader::LoadJsonFile(const std::string& filePath, std::string& fileContent)
76 {
77     HILOGD("call!");
78     if (filePath.empty() || filePath.size() > MAX_STRING_LEN) {
79         HILOGE("filePath is invalid!");
80         return DP_INVALID_PARAM;
81     }
82     char buf[MAX_PATH_LEN] = {0};
83     char targetPath[PATH_MAX + 1] = {0x00};
84     char *srcPath = GetOneCfgFile(filePath.c_str(), buf, MAX_PATH_LEN);
85     if (srcPath == nullptr) {
86         HILOGE("srcPath is invalid!");
87         return DP_LOAD_JSON_FILE_FAIL;
88     }
89     if (strlen(srcPath) == 0 || strlen(srcPath) > PATH_MAX || realpath(srcPath, targetPath) == nullptr) {
90         HILOGE("File canonicalization failed!");
91         return DP_LOAD_JSON_FILE_FAIL;
92     }
93     std::ifstream ifs(targetPath);
94     if (!ifs.is_open()) {
95         HILOGE("load json file failed");
96         return DP_LOAD_JSON_FILE_FAIL;
97     }
98     fileContent = std::string(std::istreambuf_iterator<char>{ifs}, std::istreambuf_iterator<char>{});
99     ifs.close();
100     return DP_SUCCESS;
101 }
102 
GetStaticCapability(const cJSON * const staticCapabilityJson,std::string & staticCapability)103 int32_t StaticCapabilityLoader::GetStaticCapability(const cJSON* const staticCapabilityJson,
104     std::string& staticCapability)
105 {
106     HILOGD("call!");
107     if (!cJSON_IsObject(staticCapabilityJson)) {
108         HILOGE("staticInfoJson is json object!");
109         return DP_INVALID_PARAM;
110     }
111     cJSON* staticCapabilities = cJSON_GetObjectItem(staticCapabilityJson, STATIC_CAPABILITY_ATTRIBUTE.c_str());
112     if (!cJSON_IsArray(staticCapabilities)) {
113         HILOGE("StaticCapabilities is not Array!");
114         return DP_PARSE_STATIC_CAP_FAIL;
115     }
116     int32_t capabilityNum = static_cast<int32_t>(cJSON_GetArraySize(staticCapabilities));
117     if (capabilityNum == 0 || capabilityNum > MAX_STATIC_CAPABILITY_SIZE) {
118         HILOGE("CapabilityNum is invalid, nums: %{public}d!", capabilityNum);
119         return DP_PARSE_STATIC_CAP_FAIL;
120     }
121     InitStaticCapability(capabilityNum, staticCapability);
122     SetStaticCapability(staticCapabilities, staticCapability);
123     return DP_SUCCESS;
124 }
125 
GetStaticInfo(const cJSON * const staticInfoJson,const std::string & staticCapability,std::string & staticVersion,std::unordered_map<std::string,CharacteristicProfile> & charProfiles)126 int32_t StaticCapabilityLoader::GetStaticInfo(const cJSON* const staticInfoJson, const std::string& staticCapability,
127     std::string& staticVersion, std::unordered_map<std::string, CharacteristicProfile>& charProfiles)
128 {
129     HILOGD("call!");
130     if (!cJSON_IsObject(staticInfoJson)) {
131         HILOGE("staticInfoJson is json object!");
132         return DP_INVALID_PARAM;
133     }
134     cJSON* lastStaticInfoJson = GetLatestStaticInfoJson(staticInfoJson);
135     if (lastStaticInfoJson == NULL) {
136         HILOGE("lastStaticInfo is nullptr!");
137         return DP_GET_STATIC_INFO_FAIL;
138     }
139     GetStaticVersion(lastStaticInfoJson, staticVersion);
140     std::string localDeviceId = ContentSensorManagerUtils::GetInstance().ObtainLocalUdid();
141     GenerateStaticProfiles(localDeviceId, staticCapability, lastStaticInfoJson, charProfiles);
142     return DP_SUCCESS;
143 }
144 
GetStaticInfoByVersion(const std::string & deviceId,const std::string & staticCapability,const cJSON * const staticInfoJson,const std::string & staticVersion,std::unordered_map<std::string,CharacteristicProfile> & charProfiles)145 int32_t StaticCapabilityLoader::GetStaticInfoByVersion(const std::string& deviceId,
146     const std::string& staticCapability, const cJSON* const staticInfoJson,
147     const std::string& staticVersion, std::unordered_map<std::string, CharacteristicProfile>& charProfiles)
148 {
149     HILOGD("call!");
150     if (deviceId.empty() || deviceId.size() > MAX_STRING_LEN) {
151         HILOGE("deviceId is invalid!");
152         return DP_INVALID_PARAM;
153     }
154     if (!cJSON_IsObject(staticInfoJson)) {
155         HILOGE("staticInfoJson is json object!");
156         return DP_INVALID_PARAM;
157     }
158     if (staticVersion.empty() || staticVersion.size() > MAX_STRING_LEN) {
159         HILOGE("staticVersion is invalid!");
160         return DP_INVALID_PARAM;
161     }
162     cJSON* json = GetStaticInfoJsonByVersion(staticInfoJson, staticVersion);
163     if (json == NULL) {
164         HILOGE("staticInfoJson is nullptr!");
165         return DP_GET_STATIC_INFO_FAIL;
166     }
167     GenerateStaticProfiles(deviceId, staticCapability, json, charProfiles);
168     return DP_SUCCESS;
169 }
170 
GetLatestStaticInfoJson(const cJSON * const staticInfoJson)171 cJSON* StaticCapabilityLoader::GetLatestStaticInfoJson(const cJSON* const staticInfoJson)
172 {
173     HILOGD("call!");
174     if (!cJSON_IsObject(staticInfoJson)) {
175         HILOGE("staticInfoJson is not object!");
176         return NULL;
177     }
178     cJSON* staticInfos = cJSON_GetObjectItem(staticInfoJson, STATIC_INFO.c_str());
179     if (!cJSON_IsArray(staticInfos)) {
180         HILOGE("StaticInfos is not Array!");
181         return NULL;
182     }
183     int32_t staticInfoNum = static_cast<int32_t>(cJSON_GetArraySize(staticInfos));
184     if (staticInfoNum == 0 || staticInfoNum > MAX_STATIC_CAPABILITY_SIZE) {
185         HILOGE("staticInfoNum is invalid, nums: %{public}d!", staticInfoNum);
186         return NULL;
187     }
188     return cJSON_GetArrayItem(staticInfos, staticInfoNum - 1);
189 }
190 
GetStaticInfoJsonByVersion(const cJSON * const staticInfoJson,const std::string & staticVersion)191 cJSON* StaticCapabilityLoader::GetStaticInfoJsonByVersion(const cJSON* const staticInfoJson,
192     const std::string& staticVersion)
193 {
194     HILOGD("call!");
195     if (!cJSON_IsObject(staticInfoJson)) {
196         HILOGE("staticInfoJson is not object!");
197         return NULL;
198     }
199     if (staticVersion.empty() || staticVersion.size() > MAX_STRING_LEN) {
200         HILOGE("staticVersion is invalid!");
201         return NULL;
202     }
203     cJSON* staticInfos = cJSON_GetObjectItem(staticInfoJson, STATIC_INFO.c_str());
204     if (!cJSON_IsArray(staticInfos)) {
205         HILOGE("StaticInfos is not Array!");
206         return NULL;
207     }
208     int32_t staticInfoNum = static_cast<int32_t>(cJSON_GetArraySize(staticInfos));
209     if (staticInfoNum == 0 || staticInfoNum > MAX_STATIC_CAPABILITY_SIZE) {
210         HILOGE("staticInfoNum is invalid, nums: %{public}d!", staticInfoNum);
211         return NULL;
212     }
213     cJSON *item = NULL;
214     cJSON_ArrayForEach(item, staticInfos) {
215         if (!cJSON_IsObject(item)) {
216             HILOGE("Item is not object!");
217             continue;
218         }
219         cJSON* versionItem = cJSON_GetObjectItemCaseSensitive(item, DP_VERSION.c_str());
220         if (!cJSON_IsString(versionItem) || versionItem->valuestring == NULL) {
221             HILOGE("Get DP_Version fail!");
222             continue;
223         }
224         std::string version = versionItem->valuestring;
225         if (StaticVersionCheck(staticVersion, version)) {
226             HILOGI("Get staticInfoJson Success!");
227             return item;
228         }
229     }
230     HILOGE("staticInfoJson not found");
231     return NULL;
232 }
233 
GetStaticVersion(const cJSON * const lastStaticInfo,std::string & staticVersion)234 int32_t StaticCapabilityLoader::GetStaticVersion(const cJSON* const lastStaticInfo, std::string& staticVersion)
235 {
236     HILOGD("call!");
237     if (!cJSON_IsObject(lastStaticInfo)) {
238         HILOGE("LastStaticInfoItem is not object!");
239         return DP_GET_STATIC_INFO_FAIL;
240     }
241     cJSON* dpVersionJson = cJSON_GetObjectItemCaseSensitive(lastStaticInfo, DP_VERSION.c_str());
242     if (!cJSON_IsString(dpVersionJson) || dpVersionJson->valuestring == NULL) {
243         HILOGE("dpVersionJson is invalid!");
244         return DP_GET_STATIC_INFO_FAIL;
245     }
246     staticVersion = dpVersionJson->valuestring;
247     return DP_SUCCESS;
248 }
249 
GenerateStaticProfiles(const std::string & deviceId,const std::string & staticCapability,const cJSON * const staticInfoJson,std::unordered_map<std::string,CharacteristicProfile> & charProfiles)250 int32_t StaticCapabilityLoader::GenerateStaticProfiles(const std::string& deviceId, const std::string& staticCapability,
251     const cJSON* const staticInfoJson, std::unordered_map<std::string, CharacteristicProfile>& charProfiles)
252 {
253     HILOGD("call!");
254     if (deviceId.empty() || deviceId.size() > MAX_STRING_LEN) {
255         HILOGE("deviceId is invalid!");
256         return DP_INVALID_PARAM;
257     }
258     if (!cJSON_IsObject(staticInfoJson)) {
259         HILOGE("staticInfoJson is not object!");
260         return DP_GET_STATIC_INFO_FAIL;
261     }
262     cJSON* abilitiesJson = cJSON_GetObjectItemCaseSensitive(staticInfoJson, ABILITIES.c_str());
263     if (!cJSON_IsArray(abilitiesJson)) {
264         HILOGE("abilitiesJson is not array!");
265         return DP_GET_STATIC_INFO_FAIL;
266     }
267     cJSON* abilityItem = NULL;
268     cJSON_ArrayForEach(abilityItem, abilitiesJson) {
269         if (!cJSON_IsObject(abilityItem)) {
270             HILOGE("abilityItem is not object!");
271             continue;
272         }
273         cJSON* abilityKeyItem = cJSON_GetObjectItemCaseSensitive(abilityItem, ABILITY_KEY.c_str());
274         if (!cJSON_IsString(abilityKeyItem) || abilityKeyItem->valuestring == NULL) {
275             HILOGE("Get abilityKeyItem fail!");
276             continue;
277         }
278         cJSON* abilityValueItem = cJSON_GetObjectItemCaseSensitive(abilityItem, ABILITY_VALUE.c_str());
279         if (!cJSON_IsObject(abilityValueItem)) {
280             HILOGE("Get abilityValueItem fail!");
281             continue;
282         }
283         std::string serviceId = abilityKeyItem->valuestring;
284         if (!HasStaticCapability(serviceId, staticCapability)) {
285             HILOGW("service: %{public}s does not have static capability", serviceId.c_str());
286             continue;
287         }
288         HILOGD("service: %{public}s has static capability", serviceId.c_str());
289         char* abilityValue = cJSON_Print(abilityValueItem);
290         if (abilityValue == NULL) {
291             HILOGE("Get abilityValue fail!");
292             continue;
293         }
294         std::string charValue = abilityValue;
295         cJSON_free(abilityValue);
296         CharacteristicProfile characteristicProfile(deviceId, serviceId, STATIC_CHARACTERISTIC_KEY, charValue);
297         charProfiles[ProfileUtils::GenerateCharProfileKey(deviceId, serviceId, STATIC_CHARACTERISTIC_KEY)] =
298             characteristicProfile;
299     }
300     return DP_SUCCESS;
301 }
302 
LoadStaticInfo(const std::string & staticCapability,std::string & staticVersion,std::unordered_map<std::string,CharacteristicProfile> & charProfiles)303 int32_t StaticCapabilityLoader::LoadStaticInfo(const std::string& staticCapability, std::string& staticVersion,
304     std::unordered_map<std::string, CharacteristicProfile>& charProfiles)
305 {
306     HILOGD("call!");
307     if (staticCapability.empty() || staticCapability.size() > MAX_STRING_LEN) {
308         HILOGE("staticCapability is invalid!");
309         return DP_INVALID_PARAM;
310     }
311     std::string fileContent = "";
312     int32_t loadJsonResult = LoadJsonFile(STATIC_INFO_PATH, fileContent);
313     if (loadJsonResult != DP_SUCCESS) {
314         HILOGE("Load staticInfo json failed, result: %{public}d!", loadJsonResult);
315         return loadJsonResult;
316     }
317     cJSON* staticInfoJson = cJSON_Parse(fileContent.c_str());
318     if (!cJSON_IsObject(staticInfoJson)) {
319         HILOGE("Static info json parse failed!");
320         cJSON_Delete(staticInfoJson);
321         return DP_PARSE_STATIC_INFO_FAIL;
322     }
323     int32_t getInfoResult = GetStaticInfo(staticInfoJson, staticCapability, staticVersion, charProfiles);
324     if (getInfoResult != DP_SUCCESS) {
325         HILOGE("Get static info result %{public}d!", getInfoResult);
326         cJSON_Delete(staticInfoJson);
327         return getInfoResult;
328     }
329     HILOGI("success!");
330     cJSON_Delete(staticInfoJson);
331     return DP_SUCCESS;
332 }
333 
LoadStaticProfiles(const std::string & deviceId,const std::string & staticCapability,const std::string & staticVersion,std::unordered_map<std::string,CharacteristicProfile> & charProfiles)334 int32_t StaticCapabilityLoader::LoadStaticProfiles(const std::string& deviceId, const std::string& staticCapability,
335     const std::string& staticVersion, std::unordered_map<std::string, CharacteristicProfile>& charProfiles)
336 {
337     HILOGD("call!");
338     if (deviceId.empty() || deviceId.size() > MAX_STRING_LEN) {
339         HILOGE("deviceId is invalid!");
340         return DP_INVALID_PARAM;
341     }
342     if (staticCapability.empty() || staticCapability.size() > MAX_STRING_LEN) {
343         HILOGE("staticCapability is invalid!");
344         return DP_INVALID_PARAM;
345     }
346     if (staticVersion.empty() || staticVersion.size() > MAX_STRING_LEN) {
347         HILOGE("staticVersion is invalid!");
348         return DP_INVALID_PARAM;
349     }
350     std::string fileContent = "";
351     int32_t loadJsonResult = LoadJsonFile(STATIC_INFO_PATH, fileContent);
352     if (loadJsonResult != DP_SUCCESS) {
353         HILOGE("Load staticInfo json failed, result: %{public}d!", loadJsonResult);
354         return loadJsonResult;
355     }
356     cJSON* staticInfoJson = cJSON_Parse(fileContent.c_str());
357     if (!cJSON_IsObject(staticInfoJson)) {
358         HILOGE("Static info json parse failed!");
359         cJSON_Delete(staticInfoJson);
360         return DP_PARSE_STATIC_INFO_FAIL;
361     }
362     int32_t getInfoResult = GetStaticInfoByVersion(deviceId, staticCapability, staticInfoJson,
363         staticVersion, charProfiles);
364     if (getInfoResult != DP_SUCCESS) {
365         HILOGE("Get static info result %{public}d!", getInfoResult);
366         cJSON_Delete(staticInfoJson);
367         return getInfoResult;
368     }
369     HILOGI("success!");
370     cJSON_Delete(staticInfoJson);
371     return DP_SUCCESS;
372 }
373 
InitStaticCapability(int32_t size,std::string & staticCapability)374 void StaticCapabilityLoader::InitStaticCapability(int32_t size, std::string& staticCapability)
375 {
376     HILOGI("InitStaticCapability size %{public}d!", size);
377     staticCapability = EMPTY_STRING;
378     for (int32_t i = 0; i < size; i++) {
379         staticCapability += DEFAULT_STATIC_VAL;
380     }
381     HILOGI("InitStaticCapability value %{public}s!", staticCapability.c_str());
382 }
383 
SetStaticCapability(const cJSON * const staticCapabilityItems,std::string & staticCapability)384 void StaticCapabilityLoader::SetStaticCapability(const cJSON* const staticCapabilityItems,
385     std::string& staticCapability)
386 {
387     HILOGD("call!");
388     if (!cJSON_IsArray(staticCapabilityItems)) {
389         HILOGE("staticCapabilityItems is not json array!");
390         return;
391     }
392     cJSON *item = NULL;
393     cJSON_ArrayForEach(item, staticCapabilityItems) {
394         if (!cJSON_IsObject(item)) {
395             HILOGE("Item is not object!");
396             continue;
397         }
398         cJSON* nameItem = cJSON_GetObjectItemCaseSensitive(item, STATIC_CAP_HANDLER_NAME.c_str());
399         if (!cJSON_IsString(nameItem) || nameItem->valuestring == NULL) {
400             HILOGE("Get handler_name fail!");
401             continue;
402         }
403         cJSON* locItem = cJSON_GetObjectItemCaseSensitive(item, STATIC_CAP_HANDLER_LOC.c_str());
404         if (!cJSON_IsString(locItem) || locItem->valuestring == NULL) {
405             HILOGE("Get handler_loc fail!");
406             continue;
407         }
408         std::string handlerName = nameItem->valuestring;
409         std::string handlerLoc = locItem->valuestring;
410         SetStaticCapabilityFlag(handlerName, handlerLoc, staticCapability);
411     }
412 }
413 
SetStaticCapabilityFlag(const std::string & handlerName,const std::string & handlerLoc,std::string & staticCapability)414 void StaticCapabilityLoader::SetStaticCapabilityFlag(const std::string& handlerName, const std::string& handlerLoc,
415     std::string& staticCapability)
416 {
417     HILOGD("call!");
418     if (handlerName.empty() || handlerName.size() > MAX_STRING_LEN) {
419         HILOGE("handlerName is invalid!");
420         return;
421     }
422     if (handlerLoc.empty() || handlerLoc.size() > MAX_STRING_LEN) {
423         HILOGE("handlerLoc is invalid!");
424         return;
425     }
426     if (CAPABILITY_FLAG_MAP.count(handlerName) == 0) {
427         HILOGE("SetStaticCapabilityFlag fail, handlerName: %{public}s!", handlerName.c_str());
428         return;
429     }
430     int32_t capabilityFlag = static_cast<int32_t>(CAPABILITY_FLAG_MAP.at(handlerName));
431     if (capabilityFlag >= static_cast<int32_t>(staticCapability.size())) {
432         HILOGE("SetStaticCapabilityFlag fail, handlerName: %{public}s!", handlerName.c_str());
433         return;
434     }
435     char capabilityValue = GetStaticCapabilityValue(handlerLoc) ? SUPPORT_STATIC_VAL : NOT_SUPPORT_STATIC_VAL;
436     staticCapability[capabilityFlag] = capabilityValue;
437     HILOGI("handlerName: %{public}s, staticCapability: %{public}c", handlerName.c_str(), capabilityValue);
438 }
439 
GetStaticCapabilityValue(const std::string & handlerLoc)440 bool StaticCapabilityLoader::GetStaticCapabilityValue(const std::string& handlerLoc)
441 {
442     HILOGD("call!");
443     if (handlerLoc.length() == 0 || handlerLoc.length() > PATH_MAX) {
444         HILOGE("File canonicalization failed!");
445         return false;
446     }
447     void *so_handler = dlopen(handlerLoc.c_str(), RTLD_LAZY | RTLD_NODELETE);
448     if (so_handler == nullptr) {
449         HILOGE("%{public}s handler load failed, failed reason : %{public}s", handlerLoc.c_str(), dlerror());
450         return false;
451     }
452     auto func = (StaticCapabilityHandler)dlsym(so_handler, "GetStaticCapabilityCollector");
453     if (func == nullptr) {
454         dlclose(so_handler);
455         HILOGE("Get StaticCapabilityHandler is null, failed reason : %{public}s", dlerror());
456         return false;
457     }
458     bool isSupportStaticCapability = func();
459     HILOGI("GetStaticCapabilityValue %{public}d", isSupportStaticCapability);
460     dlclose(so_handler);
461     return isSupportStaticCapability;
462 }
HasStaticCapability(const std::string & serviceId,const std::string & staticCapability)463 bool StaticCapabilityLoader::HasStaticCapability(const std::string& serviceId, const std::string& staticCapability)
464 {
465     HILOGD("call!");
466     int32_t capabilityFlag = static_cast<int32_t>(CAPABILITY_FLAG_MAP.at(serviceId));
467     if (capabilityFlag >= static_cast<int32_t>(staticCapability.size())) {
468         HILOGE("HasStaticCapability fail, capabilityFlag is out of range, serviceId: %{public}s",
469             ProfileUtils::GetAnonyString(serviceId).c_str());
470         return false;
471     }
472     return staticCapability[capabilityFlag] == SUPPORT_STATIC_VAL;
473 }
474 
StaticVersionCheck(const std::string & peerVersion,const std::string & localVersion)475 bool StaticCapabilityLoader::StaticVersionCheck(const std::string& peerVersion, const std::string& localVersion)
476 {
477     HILOGD("call!");
478     if (peerVersion == localVersion) {
479         HILOGI("staticVersion equal");
480         return true;
481     }
482     if (!IsValidVersion(peerVersion) || !IsValidVersion(localVersion)) {
483         HILOGE("Params are valid");
484         return false;
485     }
486     return true;
487 }
488 
IsValidVersion(const std::string & version)489 bool StaticCapabilityLoader::IsValidVersion(const std::string& version)
490 {
491     std::regex rule(STATIC_VERSION_RULES);
492     return std::regex_match(version, rule);
493 }
494 
495 } // namespace DistributedDeviceProfile
496 } // namespace OHOS
497