• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "thermal_srv_config_parser.h"
17 
18 #include "string_operation.h"
19 #include "thermal_common.h"
20 #include "thermal_service.h"
21 #include "string_ex.h"
22 
23 #include <dlfcn.h>
24 
25 namespace OHOS {
26 namespace PowerMgr {
27 namespace {
28 constexpr uint32_t AUX_SENSOR_RANGE_LEN = 2;
29 const std::string TRUE_STR = "1";
30 constexpr const char* GET_THERMAL_EXT_CONGIH_FUNC = "GetThermalExtConfig";
31 constexpr const char* THERMAL_CONFIG_LIBRARY_PATH = "libthermal_manager_ext.z.so";
32 const std::string SYSTEM_PREFIX = "/system";
33 constexpr int32_t SYSTEM_PREFIX_INDEX = 7;
34 constexpr int32_t THERMAL_SERVICE_CONFIG_INDEX = 2;
35 constexpr int32_t TEMPDIFF_SENSOR_SIZE = 2;
36 typedef int32_t(*Func)(int32_t, std::string&);
37 }
38 
ThermalSrvConfigParser()39 ThermalSrvConfigParser::ThermalSrvConfigParser() {};
40 
ThermalSrvConfigInit(const std::string & path)41 bool ThermalSrvConfigParser::ThermalSrvConfigInit(const std::string& path)
42 {
43     if (ParseXmlFile(path)) {
44         return true;
45     }
46     return false;
47 }
48 
DecryptConfig(const std::string & path,std::string & result)49 bool ThermalSrvConfigParser::DecryptConfig(const std::string& path, std::string& result)
50 {
51     if (path.compare(0, SYSTEM_PREFIX_INDEX, SYSTEM_PREFIX) == 0) {
52         return false;
53     }
54     THERMAL_HILOGI(COMP_SVC, "start DecryptConfig");
55     void *handler = dlopen(THERMAL_CONFIG_LIBRARY_PATH, RTLD_LAZY);
56     if (handler == nullptr) {
57         THERMAL_HILOGE(COMP_SVC, "dlopen failed, reason : %{public}s", dlerror());
58         return false;
59     }
60 
61     Func getDecryptConfig = reinterpret_cast<Func>(dlsym(handler, GET_THERMAL_EXT_CONGIH_FUNC));
62     if (getDecryptConfig == nullptr) {
63         THERMAL_HILOGE(COMP_SVC, "find function %{public}s failed, reason : %{public}s",
64             GET_THERMAL_EXT_CONGIH_FUNC, dlerror());
65 #ifndef FUZZ_TEST
66         dlclose(handler);
67 #endif
68         return false;
69     }
70 
71     int32_t ret = getDecryptConfig(THERMAL_SERVICE_CONFIG_INDEX, result);
72     if (ret != 0) {
73         THERMAL_HILOGE(COMP_SVC, "decrypt config failed, ret:%{public}d", ret);
74 #ifndef FUZZ_TEST
75         dlclose(handler);
76 #endif
77         return false;
78     }
79 
80 #ifndef FUZZ_TEST
81     dlclose(handler);
82 #endif
83     THERMAL_HILOGI(COMP_SVC, "end DecryptConfig");
84     return true;
85 }
86 
ParseXmlFile(const std::string & path)87 bool ThermalSrvConfigParser::ParseXmlFile(const std::string& path)
88 {
89     xmlDocPtr docParse;
90     std::string result;
91     if (DecryptConfig(path, result)) {
92         // Initialize configuration file through the decrypt results
93         docParse = xmlReadMemory(
94             result.c_str(), int(result.size()), NULL, NULL, XML_PARSE_NOBLANKS);
95     } else {
96         THERMAL_HILOGI(COMP_SVC, "don't need decrypt");
97         docParse = xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS);
98     }
99 
100     std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(docParse, xmlFreeDoc);
101     if (docPtr == nullptr) {
102         THERMAL_HILOGE(COMP_SVC, "init failed, read file failed");
103         return false;
104     }
105 
106     auto rootNode = xmlDocGetRootElement(docPtr.get());
107     if (rootNode == nullptr) {
108         THERMAL_HILOGE(COMP_SVC, "get root node failed");
109         return false;
110     }
111 
112     for (xmlNodePtr node = rootNode->xmlChildrenNode; node != nullptr; node = node->next) {
113         if (!ParseRootNode(node)) {
114             return false;
115         }
116     }
117     return true;
118 }
119 
ParseRootNode(const xmlNodePtr & node)120 bool ThermalSrvConfigParser::ParseRootNode(const xmlNodePtr& node)
121 {
122     bool ret = false;
123     if (!xmlStrcmp(node->name, BAD_CAST"base")) {
124         ret = ParseBaseNode(node);
125     } else if (!xmlStrcmp(node->name, BAD_CAST"level")) {
126         ret = ParseLevelNode(node);
127     } else if (!xmlStrcmp(node->name, BAD_CAST"state")) {
128         ret = ParseStateNode(node);
129     } else if (!xmlStrcmp(node->name, BAD_CAST"action")) {
130         ret = ParseActionNode(node);
131     } else if (!xmlStrcmp(node->name, BAD_CAST"policy")) {
132         ret = ParsePolicyNode(node);
133     } else if (!xmlStrcmp(node->name, BAD_CAST"idle")) {
134         ret = ParseIdleNode(node);
135     } else if (!xmlStrcmp(node->name, BAD_CAST"fan")) {
136         ret = ParseFanNode(node);
137     } else if (!xmlStrcmp(node->name, BAD_CAST"comment")) {
138         ret = true;
139     } else {
140         THERMAL_HILOGE(COMP_SVC, "unknown root node %{public}s",
141             reinterpret_cast<const char*>(node->name));
142     }
143     return ret;
144 }
145 
ParseBaseNode(const xmlNodePtr & node)146 bool ThermalSrvConfigParser::ParseBaseNode(const xmlNodePtr& node)
147 {
148     BaseInfoMap baseInfoMap;
149     xmlNodePtr cur = node->xmlChildrenNode;
150     while (cur != nullptr) {
151         if (xmlStrcmp(cur->name, BAD_CAST"item")) {
152             cur = cur->next;
153             continue;
154         }
155         BaseItem bi;
156         xmlChar* xmlTag = xmlGetProp(cur, BAD_CAST"tag");
157         if (xmlTag != nullptr) {
158             bi.tag = reinterpret_cast<char*>(xmlTag);
159             xmlFree(xmlTag);
160         } else {
161             THERMAL_HILOGE(COMP_SVC, "base tag is null");
162             return false;
163         }
164 
165         xmlChar* xmlValue = xmlGetProp(cur, BAD_CAST"value");
166         if (xmlValue != nullptr) {
167             bi.value = reinterpret_cast<char*>(xmlValue);
168             xmlFree(xmlValue);
169         } else {
170             THERMAL_HILOGE(COMP_SVC, "base value is null, tag: %{public}s", bi.tag.c_str());
171             return false;
172         }
173         baseInfoMap.emplace(bi.tag, bi.value);
174         cur = cur->next;
175         THERMAL_HILOGD(COMP_SVC, "tag: %{public}s, value: %{public}s", bi.tag.c_str(), bi.value.c_str());
176     }
177     auto tms = ThermalService::GetInstance();
178     tms->GetBaseinfoObj()->SetBaseInfo(baseInfoMap);
179     auto iter = baseInfoMap.find("sim_tz");
180     if (iter != baseInfoMap.end()) {
181         if (iter->second == "") {
182             tms->SetSimulationXml(false);
183             return true;
184         }
185         if (iter->second == "0" || iter->second == "1") {
186             int64_t result = 0;
187             if (!StringOperation::ParseStrtollResult(iter->second, result)) {
188                 return false;
189             }
190             tms->SetSimulationXml(static_cast<bool>(result));
191             return true;
192         }
193         return false;
194     }
195     tms->SetSimulationXml(false);
196     return true;
197 }
198 
ParseLevelNode(const xmlNodePtr & node)199 bool ThermalSrvConfigParser::ParseLevelNode(const xmlNodePtr& node)
200 {
201     xmlNodePtr cur = node->xmlChildrenNode;
202     SensorClusterMap msc;
203     while (cur != nullptr) {
204         if (xmlStrcmp(cur->name, BAD_CAST"sensor_cluster")) {
205             cur = cur->next;
206             continue;
207         }
208         std::string name;
209         SensorClusterPtr sc = std::make_shared<ThermalConfigSensorCluster>();
210         xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
211         if (xmlName != nullptr) {
212             name = reinterpret_cast<char*>(xmlName);
213             xmlFree(xmlName);
214         } else {
215             THERMAL_HILOGE(COMP_SVC, "level cluster name is null");
216             return false;
217         }
218         if (!ParseLevelState(cur, sc) || !ParseAuxSensorInfo(cur, sc) || !ParseSensorInfo(cur, sc)
219             || !ParseTempDiffInfo(cur, sc)) {
220             THERMAL_HILOGE(COMP_SVC, "parse sensor info failed, cluster name: %{public}s", name.c_str());
221             return false;
222         }
223         xmlChar* desc = xmlGetProp(cur, BAD_CAST("desc"));
224         if (desc != nullptr) {
225             if (TrimStr(reinterpret_cast<char*>(desc)) == TRUE_STR) {
226                 sc->SetDescFlag(true);
227                 THERMAL_HILOGD(COMP_SVC, "cluster [%{public}s] is desc", name.c_str());
228             }
229             xmlFree(desc);
230         }
231         if (!sc->CheckStandard()) {
232             THERMAL_HILOGE(COMP_SVC, "cluster [%{public}s] some config error", name.c_str());
233             return false;
234         }
235         msc.emplace(std::pair(name, sc));
236         cur = cur->next;
237     }
238     auto tms = ThermalService::GetInstance();
239     tms->GetPolicy()->SetSensorClusterMap(msc);
240     return true;
241 }
242 
ParseLevelState(const xmlNodePtr & cur,SensorClusterPtr & sc)243 bool ThermalSrvConfigParser::ParseLevelState(const xmlNodePtr& cur, SensorClusterPtr& sc)
244 {
245     for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
246         if (xmlStrcmp(subNode->name, BAD_CAST"state") || (subNode->properties == nullptr)) {
247             continue;
248         }
249         for (auto levStateProp = subNode->properties; levStateProp != nullptr; levStateProp = levStateProp->next) {
250             std::string propName = reinterpret_cast<const char*>(levStateProp->name);
251             xmlChar* xmlPropValue = xmlGetProp(subNode, levStateProp->name);
252             if (xmlPropValue != nullptr) {
253                 std::string propValue = reinterpret_cast<char*>(xmlPropValue);
254                 THERMAL_HILOGD(COMP_SVC, "level state: %{public}s, value: %{public}s",
255                     propName.c_str(), propValue.c_str());
256                 sc->AddState(propName, propValue);
257                 xmlFree(xmlPropValue);
258             } else {
259                 THERMAL_HILOGE(COMP_SVC, "level state prop [%{public}s] value is null", propName.c_str());
260                 return false;
261             }
262         }
263     }
264     return true;
265 }
266 
ParseAuxSensorInfo(const xmlNodePtr & cur,SensorClusterPtr & sc)267 bool ThermalSrvConfigParser::ParseAuxSensorInfo(const xmlNodePtr& cur, SensorClusterPtr& sc)
268 {
269     xmlChar* auxSensor = xmlGetProp(cur, BAD_CAST"aux_sensor");
270     if (auxSensor != nullptr) {
271         std::vector<std::string> auxsensors;
272         AuxSensorInfoMap auxSensorLevelInfo;
273         std::string auxsensor = reinterpret_cast<char*>(auxSensor);
274         sc->SetAuxFlag(true);
275         StringOperation::SplitString(auxsensor, auxsensors, ",");
276         for (uint32_t i = 0; i < auxsensors.size(); i++) {
277             std::vector<AuxLevelItem> auxLevelItems;
278             std::string sensorType = auxsensors[i];
279             if (sensorType.empty()) {
280                 THERMAL_HILOGE(COMP_SVC, "aux sensor type is empty");
281                 return false;
282             }
283             THERMAL_HILOGD(COMP_SVC, "parse aux sensor [%{public}s] item:", sensorType.c_str());
284             if (!ParseAuxSensorLevInfo(cur, auxsensors, i, auxLevelItems)) {
285                 THERMAL_HILOGE(COMP_SVC, "parse aux sensor [%{public}s] sub node failed", sensorType.c_str());
286                 return false;
287             }
288             if (auxLevelItems.empty()) {
289                 THERMAL_HILOGE(COMP_SVC, "aux sensor [%{public}s] level info is empty", sensorType.c_str());
290                 return false;
291             }
292             auxSensorLevelInfo.emplace(sensorType, auxLevelItems);
293         }
294         sc->SetAuxSensorLevelInfo(auxSensorLevelInfo);
295         xmlFree(auxSensor);
296     }
297     return true;
298 }
299 
ParseAuxSensorLevInfo(const xmlNodePtr & cur,std::vector<std::string> & auxsensors,const uint32_t sensorIdx,std::vector<AuxLevelItem> & auxLevelItems)300 bool ThermalSrvConfigParser::ParseAuxSensorLevInfo(const xmlNodePtr& cur,
301     std::vector<std::string>& auxsensors, const uint32_t sensorIdx, std::vector<AuxLevelItem>& auxLevelItems)
302 {
303     for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
304         if (xmlStrcmp(subNode->name, BAD_CAST"item")) {
305             continue;
306         }
307         std::string tempRangeStr;
308         AuxLevelItem auxlevelItem;
309         if (!ParseAuxSensorTriggerRange(subNode, auxsensors, tempRangeStr, sensorIdx)) {
310             THERMAL_HILOGE(COMP_SVC, "parse aux sensor range failed");
311             return false;
312         }
313 
314         std::vector<std::string> tempRanges;
315         StringOperation::SplitString(tempRangeStr, tempRanges, "_");
316         if (static_cast<uint32_t>(tempRanges.size()) < AUX_SENSOR_RANGE_LEN) {
317             THERMAL_HILOGE(COMP_SVC, "aux sensor temp range split failed");
318             return false;
319         }
320         const int32_t INDEX0 = 0;
321         const int32_t INDEX1 = 1;
322         StrToInt(tempRanges[INDEX0], auxlevelItem.lowerTemp);
323         StrToInt(tempRanges[INDEX1], auxlevelItem.upperTemp);
324         xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
325         if (xmlLevel != nullptr) {
326             StrToInt(reinterpret_cast<char*>(xmlLevel), auxlevelItem.level);
327             xmlFree(xmlLevel);
328         } else {
329             THERMAL_HILOGE(COMP_SVC, "aux sensor level is null");
330             return false;
331         }
332         THERMAL_HILOGD(COMP_SVC, "lowerTemp: %{public}d, upperTemp: %{public}d",
333             auxlevelItem.lowerTemp, auxlevelItem.upperTemp);
334         auxLevelItems.push_back(auxlevelItem);
335     }
336     return true;
337 }
338 
ParseAuxSensorTriggerRange(const xmlNodePtr & subNode,std::vector<std::string> & auxsensors,std::string & tempRangeStr,const uint32_t sensorIdx)339 bool ThermalSrvConfigParser::ParseAuxSensorTriggerRange(const xmlNodePtr& subNode,
340     std::vector<std::string>& auxsensors, std::string& tempRangeStr, const uint32_t sensorIdx)
341 {
342     xmlChar* xmlTriggerRange = xmlGetProp(subNode, BAD_CAST("aux_trigger_range"));
343     if (xmlTriggerRange != nullptr) {
344         std::string auxTriggerRange = reinterpret_cast<char*>(xmlTriggerRange);
345         if (!auxTriggerRange.empty()) {
346             std::vector<std::string> auxTempranges;
347             StringOperation::SplitString(auxTriggerRange, auxTempranges, ",");
348             if (auxsensors.size() > auxTempranges.size()) {
349                 THERMAL_HILOGE(COMP_SVC, "aux sensor size (%{public}zu) don't match range size (%{public}zu)",
350                     auxsensors.size(), auxTempranges.size());
351                 xmlFree(xmlTriggerRange);
352                 return false;
353             }
354             tempRangeStr = auxTempranges[sensorIdx];
355         } else {
356             THERMAL_HILOGE(COMP_SVC, "aux sensor trigger range is empty");
357             return false;
358         }
359         xmlFree(xmlTriggerRange);
360     } else {
361         THERMAL_HILOGE(COMP_SVC, "aux sensor trigger range is null");
362         return false;
363     }
364     return true;
365 }
366 
ParseSensorInfo(const xmlNodePtr & cur,SensorClusterPtr & sc)367 bool ThermalSrvConfigParser::ParseSensorInfo(const xmlNodePtr& cur, SensorClusterPtr& sc)
368 {
369     SensorInfoMap sensorLevelInfo;
370     std::vector<std::string> sensors;
371     xmlChar* xmlSensor = xmlGetProp(cur, BAD_CAST"sensor");
372     if (xmlSensor != nullptr) {
373         StringOperation::SplitString(reinterpret_cast<char*>(xmlSensor), sensors, ",");
374         if (sensors.empty()) {
375             THERMAL_HILOGE(COMP_SVC, "sensor type is empty");
376             return false;
377         }
378         for (uint32_t i = 0; i < sensors.size(); i++) {
379             std::string sensorType = sensors.at(i);
380             std::vector<LevelItem> levelItems;
381             if (!ParseSensorLevelInfo(cur, levelItems, sensors, i, sc)) {
382                 THERMAL_HILOGE(COMP_SVC, "parse sensor [%{public}s] level failed", sensorType.c_str());
383                 return false;
384             }
385             if (levelItems.empty()) {
386                 THERMAL_HILOGE(COMP_SVC, "sensor [%{public}s] level info is empty", sensorType.c_str());
387                 return false;
388             }
389             sensorLevelInfo.emplace(std::pair(sensorType, levelItems));
390         }
391         sc->SetSensorLevelInfo(sensorLevelInfo);
392         xmlFree(xmlSensor);
393     } else {
394         THERMAL_HILOGE(COMP_SVC, "sensor type is null");
395         return false;
396     }
397     return true;
398 }
399 
ParseSensorLevelInfo(const xmlNodePtr & cur,std::vector<LevelItem> & levelItems,std::vector<std::string> & sensors,const uint32_t sensorIdx,SensorClusterPtr & sc)400 bool ThermalSrvConfigParser::ParseSensorLevelInfo(const xmlNodePtr& cur, std::vector<LevelItem>& levelItems,
401     std::vector<std::string>& sensors, const uint32_t sensorIdx, SensorClusterPtr& sc)
402 {
403     for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
404         if (xmlStrcmp(subNode->name, BAD_CAST"item")) {
405             continue;
406         }
407         LevelItem levelItem;
408         if (!ParseLevelThreshold(subNode, levelItem, sensors, sensorIdx)) {
409             THERMAL_HILOGE(COMP_SVC, "parse level threshold failed");
410             return false;
411         }
412 
413         xmlChar* tempRiseRates = xmlGetProp(subNode, BAD_CAST("temp_rise_rate"));
414         if (tempRiseRates != nullptr) {
415             std::vector<std::string> rates;
416             sc->SetRateFlag(true);
417             StringOperation::SplitString(reinterpret_cast<char*>(tempRiseRates), rates, ",");
418             if (sensors.size() != rates.size()) {
419                 THERMAL_HILOGE(COMP_SVC, "sensor size (%{public}zu) don't match rise rate (%{public}zu)",
420                     sensors.size(), rates.size());
421                 xmlFree(tempRiseRates);
422                 return false;
423             }
424             StringOperation::StrToDouble(rates.at(sensorIdx), levelItem.tempRiseRate);
425         }
426         levelItems.push_back(levelItem);
427         xmlFree(tempRiseRates);
428     }
429     return true;
430 }
431 
ParseLevelThreshold(const xmlNodePtr & subNode,LevelItem & levelItem,std::vector<std::string> & sensors,const uint32_t sensorIdx)432 bool ThermalSrvConfigParser::ParseLevelThreshold(const xmlNodePtr& subNode, LevelItem& levelItem,
433     std::vector<std::string>& sensors, const uint32_t sensorIdx)
434 {
435     std::vector<std::string> thresholds;
436     std::vector<std::string> thresholdClrs;
437     xmlChar* xmlThreshold = xmlGetProp(subNode, BAD_CAST("threshold"));
438     if (xmlThreshold != nullptr) {
439         StringOperation::SplitString(reinterpret_cast<char*>(xmlThreshold), thresholds, ",");
440         xmlFree(xmlThreshold);
441     } else {
442         THERMAL_HILOGE(COMP_SVC, "threshold is null");
443         return false;
444     }
445     xmlChar* xmlThresholdClr = xmlGetProp(subNode, BAD_CAST("threshold_clr"));
446     if (xmlThresholdClr != nullptr) {
447         StringOperation::SplitString(reinterpret_cast<char*>(xmlThresholdClr), thresholdClrs, ",");
448         xmlFree(xmlThresholdClr);
449     } else {
450         THERMAL_HILOGE(COMP_SVC, "threshold_clr is null");
451         return false;
452     }
453     if (sensors.size() != thresholds.size() || sensors.size() != thresholdClrs.size()) {
454         THERMAL_HILOGE(COMP_SVC,
455             "sensor size (%{public}zu) don't match threshold (%{public}zu) or clr (%{public}zu)",
456             sensors.size(), thresholds.size(), thresholdClrs.size());
457         return false;
458     }
459     xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
460     if (xmlLevel != nullptr) {
461         StringOperation::StrToUint(reinterpret_cast<char*>(xmlLevel), levelItem.level);
462         xmlFree(xmlLevel);
463     } else {
464         THERMAL_HILOGE(COMP_SVC, "level is null");
465         return false;
466     }
467 
468     StrToInt(thresholds.at(sensorIdx), levelItem.threshold);
469     StrToInt(thresholdClrs.at(sensorIdx), levelItem.thresholdClr);
470     return true;
471 }
472 
ParseStateNode(const xmlNodePtr & node)473 bool ThermalSrvConfigParser::ParseStateNode(const xmlNodePtr& node)
474 {
475     auto cur = node->xmlChildrenNode;
476     std::vector<StateItem> stateItems;
477     while (cur != nullptr) {
478         if (xmlStrcmp(cur->name, BAD_CAST"item")) {
479             cur = cur->next;
480             continue;
481         }
482         StateItem si;
483         xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
484         if (xmlName != nullptr) {
485             si.name = reinterpret_cast<char*>(xmlName);
486             xmlFree(xmlName);
487         } else {
488             THERMAL_HILOGE(COMP_SVC, "state name is null");
489             return false;
490         }
491 
492         xmlChar* param = xmlGetProp(cur, BAD_CAST("param"));
493         if (param != nullptr) {
494             si.params = reinterpret_cast<char*>(param);
495             si.isExistParam = true;
496             xmlFree(param);
497         }
498 
499         xmlChar* delayTime = xmlGetProp(cur, BAD_CAST("delaytime"));
500         if (delayTime != nullptr) {
501             si.params = reinterpret_cast<char*>(delayTime);
502             si.isExistParam = true;
503             xmlFree(delayTime);
504         }
505 
506         stateItems.push_back(si);
507         THERMAL_HILOGD(COMP_SVC, "state: %{public}s, params: %{public}s", si.name.c_str(), si.params.c_str());
508         cur = cur->next;
509     }
510     auto tms = ThermalService::GetInstance();
511     tms->GetStateMachineObj()->SetStateItem(stateItems);
512     return true;
513 }
514 
ParseActionNode(const xmlNodePtr & node)515 bool ThermalSrvConfigParser::ParseActionNode(const xmlNodePtr& node)
516 {
517     auto cur = node->xmlChildrenNode;
518     std::vector<ActionItem> actionItems;
519     while (cur != nullptr) {
520         if (xmlStrcmp(cur->name, BAD_CAST"item")) {
521             cur = cur->next;
522             continue;
523         }
524 
525         ActionItem ai;
526         xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
527         if (xmlName != nullptr) {
528             ai.name = reinterpret_cast<char*>(xmlName);
529             xmlFree(xmlName);
530         } else {
531             THERMAL_HILOGE(COMP_SVC, "action name is null");
532             return false;
533         }
534 
535         ParseActionInfo(cur, ai);
536         actionItems.push_back(ai);
537         cur = cur->next;
538     }
539     auto tms = ThermalService::GetInstance();
540     tms->GetActionManagerObj()->SetActionItem(actionItems);
541     return true;
542 }
543 
ParseActionInfo(const xmlNodePtr & cur,ActionItem & ai)544 bool ThermalSrvConfigParser::ParseActionInfo(const xmlNodePtr& cur, ActionItem& ai)
545 {
546     xmlChar* param = xmlGetProp(cur, BAD_CAST("param"));
547     if (param != nullptr) {
548         ai.params = reinterpret_cast<char*>(param);
549         xmlFree(param);
550     }
551     xmlChar* uid = xmlGetProp(cur, BAD_CAST("uid"));
552     if (uid != nullptr) {
553         ai.uid = reinterpret_cast<char*>(uid);
554         xmlFree(uid);
555     }
556     xmlChar* protocol = xmlGetProp(cur, BAD_CAST("protocol"));
557     if (protocol != nullptr) {
558         ai.protocol = reinterpret_cast<char*>(protocol);
559         xmlFree(protocol);
560     }
561     xmlChar* strict = xmlGetProp(cur, BAD_CAST("strict"));
562     if (strict != nullptr) {
563         ai.strict = (TrimStr(reinterpret_cast<char*>(strict)) == TRUE_STR);
564         xmlFree(strict);
565     }
566     xmlChar* event = xmlGetProp(cur, BAD_CAST("event"));
567     if (event != nullptr) {
568         ai.enableEvent = (TrimStr(reinterpret_cast<char*>(event)) == TRUE_STR);
569         xmlFree(event);
570     }
571     THERMAL_HILOGD(COMP_SVC,
572         "ai.name: %{public}s, ai.strict: %{public}d, ai.params: %{public}s, ai.uid: %{public}s,"    \
573         "ai.strict: %{public}s, ai.enableEvent: %{public}d",
574         ai.name.c_str(), ai.strict, ai.params.c_str(), ai.uid.c_str(), ai.protocol.c_str(), ai.enableEvent);
575     return true;
576 }
577 
ParsePolicyNode(const xmlNodePtr & node)578 bool ThermalSrvConfigParser::ParsePolicyNode(const xmlNodePtr& node)
579 {
580     auto cur = node->xmlChildrenNode;
581     ThermalPolicy::PolicyConfigMap clusterPolicyMap;
582     while (cur != nullptr) {
583         if (xmlStrcmp(cur->name, BAD_CAST"config")) {
584             cur = cur->next;
585             continue;
586         }
587         PolicyConfig policyConfig;
588         std::string clusterName;
589         xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name");
590         if (xmlName != nullptr) {
591             clusterName = reinterpret_cast<char*>(xmlName);
592             xmlFree(xmlName);
593         } else {
594             THERMAL_HILOGE(COMP_SVC, "policy config name is null");
595             return false;
596         }
597 
598         xmlChar* xmlLevel = xmlGetProp(cur, BAD_CAST"level");
599         if (xmlLevel != nullptr) {
600             StringOperation::StrToUint(reinterpret_cast<char*>(xmlLevel), policyConfig.level);
601             THERMAL_HILOGD(COMP_SVC, "policyConfig.name: %{public}s, policyConfig.level: %{public}u",
602                 clusterName.c_str(), policyConfig.level);
603             xmlFree(xmlLevel);
604         } else {
605             THERMAL_HILOGE(COMP_SVC, "policy [%{public}s] level is null", clusterName.c_str());
606             return false;
607         }
608 
609         ParsePolicyActionInfo(cur, policyConfig);
610 
611         const auto& clusterIter = clusterPolicyMap.find(clusterName);
612         if (clusterIter == clusterPolicyMap.end()) {
613             std::vector<PolicyConfig> policyList;
614             policyList.push_back(policyConfig);
615             clusterPolicyMap.emplace(clusterName, policyList);
616         } else {
617             clusterIter->second.push_back(policyConfig);
618         }
619         cur = cur->next;
620     }
621     auto tms = ThermalService::GetInstance();
622     tms->GetPolicy()->SetPolicyMap(clusterPolicyMap);
623     return true;
624 }
625 
ParsePolicyActionInfo(const xmlNodePtr & cur,PolicyConfig & policyConfig)626 bool ThermalSrvConfigParser::ParsePolicyActionInfo(const xmlNodePtr& cur, PolicyConfig& policyConfig)
627 {
628     for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
629         if (!xmlStrcmp(subNode->name, BAD_CAST"comment")) {
630             continue;
631         }
632         PolicyAction policyAction;
633         policyAction.actionName = reinterpret_cast<const char*>(subNode->name);
634         xmlChar* actionValue = xmlNodeGetContent(subNode);
635         if (actionValue != nullptr) {
636             policyAction.actionValue = reinterpret_cast<char*>(actionValue);
637             THERMAL_HILOGD(COMP_SVC,
638                 "policyAction.actionNodeName: %{public}s, policyAction.value: %{public}s",
639                 policyAction.actionName.c_str(), policyAction.actionValue.c_str());
640             xmlFree(actionValue);
641         } else {
642             THERMAL_HILOGE(COMP_SVC, "action [%{public}s] value is null", policyAction.actionName.c_str());
643             return false;
644         }
645 
646         if (subNode->properties == nullptr) {
647             policyAction.isProp = false;
648             policyConfig.policyActionList.push_back(policyAction);
649             continue;
650         }
651         for (auto actionProp = subNode->properties; actionProp != nullptr; actionProp = actionProp->next) {
652             std::string propName = reinterpret_cast<const char*>(actionProp->name);
653             xmlChar* xmlPropValue = xmlGetProp(subNode, actionProp->name);
654             if (xmlPropValue != nullptr) {
655                 std::string propValue = reinterpret_cast<char*>(xmlPropValue);
656                 THERMAL_HILOGD(COMP_SVC, "propName.name: %{public}s, propValue:%{public}s",
657                     propName.c_str(), propValue.c_str());
658                 policyAction.actionPropMap.emplace(std::pair(propName, propValue));
659                 xmlFree(xmlPropValue);
660             } else {
661                 THERMAL_HILOGE(COMP_SVC, "prop [%{public}s] value is null", propName.c_str());
662                 return false;
663             }
664             policyAction.isProp = true;
665         }
666         policyConfig.policyActionList.push_back(policyAction);
667     }
668     return true;
669 }
670 
ParseIdleNode(const xmlNodePtr & node)671 bool ThermalSrvConfigParser::ParseIdleNode(const xmlNodePtr& node)
672 {
673     IdleState idleState;
674     for (xmlNodePtr subNode = node->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
675         if (!xmlStrcmp(subNode->name, BAD_CAST"thermallevel")) {
676             xmlChar* value = xmlNodeGetContent(subNode);
677             if (value != nullptr) {
678                 StrToInt(reinterpret_cast<char*>(value), idleState.level);
679                 xmlFree(value);
680             }
681         } else if (!xmlStrcmp(subNode->name, BAD_CAST"soc")) {
682             xmlChar* value = xmlNodeGetContent(subNode);
683             if (value != nullptr) {
684                 StrToInt(reinterpret_cast<char*>(value), idleState.soc);
685                 xmlFree(value);
686             }
687         } else if (!xmlStrcmp(subNode->name, BAD_CAST"charging")) {
688             xmlChar* value = xmlNodeGetContent(subNode);
689             if (value != nullptr) {
690                 StrToInt(reinterpret_cast<char*>(value), idleState.charging);
691                 xmlFree(value);
692             }
693         } else if (!xmlStrcmp(subNode->name, BAD_CAST"current")) {
694             xmlChar* value = xmlNodeGetContent(subNode);
695             if (value != nullptr) {
696                 StrToInt(reinterpret_cast<char*>(value), idleState.current);
697                 xmlFree(value);
698             }
699         } else {
700             THERMAL_HILOGD(COMP_SVC, "not supported node, name=%{public}s", subNode->name);
701         }
702     }
703     THERMAL_HILOGI(COMP_SVC, "level=%{public}d, soc=%{public}d, charging=%{public}d, current=%{public}d",
704                    idleState.level, idleState.soc, idleState.charging, idleState.current);
705     auto tms = ThermalService::GetInstance();
706     tms->GetStateMachineObj()->SetIdleStateConfig(idleState);
707     return true;
708 }
709 
ParseFanNode(const xmlNodePtr & node)710 bool ThermalSrvConfigParser::ParseFanNode(const xmlNodePtr &node)
711 {
712     FanFaultInfoMap fanFaultInfoMap;
713     xmlNodePtr cur = node->xmlChildrenNode;
714 
715     while (cur != nullptr) {
716         if (xmlStrcmp(cur->name, BAD_CAST"sensor_cluster")) {
717             cur = cur->next;
718             continue;
719         }
720         xmlChar* xmlSensor = xmlGetProp(cur, BAD_CAST"sensor");
721         if (xmlSensor == nullptr) {
722             return false;
723         }
724         std::vector<std::string> sensors;
725         std::string sensorStr = reinterpret_cast<char*>(xmlSensor);
726         StringOperation::SplitString(sensorStr, sensors, ",");
727         xmlFree(xmlSensor);
728         if (!ParseFanFaultInfo(cur, sensors, fanFaultInfoMap)) {
729             THERMAL_HILOGE(COMP_SVC, "ParseFanFaultInfo failed");
730             return false;
731         }
732         cur = cur->next;
733     }
734 
735     auto tms = ThermalService::GetInstance();
736     tms->GetFanFaultDetect()->SetFaultInfoMap(fanFaultInfoMap);
737     return true;
738 }
739 
ParseFanFaultInfo(const xmlNodePtr & node,std::vector<std::string> & sensors,FanFaultInfoMap & fanFaultInfoMap)740 bool ThermalSrvConfigParser::ParseFanFaultInfo(const xmlNodePtr& node,
741     std::vector<std::string> &sensors, FanFaultInfoMap &fanFaultInfoMap)
742 {
743     uint32_t sensorNum = sensors.size();
744     xmlNodePtr cur = node->xmlChildrenNode;
745 
746     while (cur != nullptr) {
747         if (xmlStrcmp(cur->name, BAD_CAST"item")) {
748             cur = cur->next;
749             continue;
750         }
751         FanSensorInfo fanSensorInfo;
752         xmlChar* xmlFault = xmlGetProp(cur, BAD_CAST"fault");
753         if (xmlFault == nullptr) {
754             return false;
755         }
756         std::string faultStr = reinterpret_cast<char*>(xmlFault);
757         xmlFree(xmlFault);
758         int32_t faultNum;
759         StrToInt(faultStr, faultNum);
760         xmlChar* xmlThreshold = xmlGetProp(cur, BAD_CAST"threshold");
761         if (xmlThreshold == nullptr) {
762             return false;
763         }
764         std::string thresholdStr = reinterpret_cast<char*>(xmlThreshold);
765         std::vector<std::string> thresholds;
766         StringOperation::SplitString(thresholdStr, thresholds, ",");
767         xmlFree(xmlThreshold);
768         if (thresholds.size() != sensorNum) {
769             return false;
770         }
771         for (uint32_t i = 0; i < sensorNum; i++) {
772             int32_t value;
773             StrToInt(thresholds[i], value);
774             fanSensorInfo.insert(std::make_pair(sensors[i], value));
775         }
776         fanFaultInfoMap.insert(std::make_pair(faultNum, fanSensorInfo));
777         cur = cur->next;
778     }
779 
780     return true;
781 }
782 
ParseTempDiffInfo(const xmlNodePtr & cur,SensorClusterPtr & sc)783 bool ThermalSrvConfigParser::ParseTempDiffInfo(const xmlNodePtr& cur, SensorClusterPtr& sc)
784 {
785     xmlChar* xmlTempDiff = xmlGetProp(cur, BAD_CAST"temp_diff");
786     if (xmlTempDiff == nullptr) {
787         THERMAL_HILOGD(COMP_SVC, "temp_diff does not exist!");
788         return true;
789     }
790 
791     std::vector<std::string> sensors;
792     StringOperation::SplitString(reinterpret_cast<char*>(xmlTempDiff), sensors, ",");
793     if (sensors.size() != TEMPDIFF_SENSOR_SIZE) {
794         THERMAL_HILOGE(COMP_SVC, "temp_diff sensors parameter size is not 2.");
795         xmlFree(xmlTempDiff);
796         return false;
797     }
798 
799     auto& sensor1 = sensors[0];
800     auto& sensor2 = sensors[1];
801     TempDiffInfoList infoList;
802     if (!ParseTempDiffLevInfo(cur, sensor1, sensor2, infoList)) {
803         THERMAL_HILOGE(COMP_SVC, "parse temp diff level info failed in ParseTempDiffInfo.");
804         xmlFree(xmlTempDiff);
805         return false;
806     }
807 
808     sc->SetTempDiffInfo(infoList);
809     sc->SetTempDiffFlag(true);
810     xmlFree(xmlTempDiff);
811     return true;
812 }
813 
ParseTempDiffLevInfo(const xmlNodePtr & cur,const std::string & sensor1,const std::string & sensor2,TempDiffInfoList & infoList)814 bool ThermalSrvConfigParser::ParseTempDiffLevInfo(const xmlNodePtr& cur,
815     const std::string& sensor1, const std::string& sensor2, TempDiffInfoList& infoList)
816 {
817     for (xmlNodePtr subNode = cur->xmlChildrenNode; subNode != nullptr; subNode = subNode->next) {
818         if (xmlStrcmp(subNode->name, BAD_CAST"item") != 0) {
819             continue;
820         }
821         TempDiffItem item;
822         if (!ParseTempDiffValue(subNode, sensor1, sensor2, item)) {
823             THERMAL_HILOGE(COMP_SVC, "parse temp diff value failed");
824             return false;
825         }
826         xmlChar* xmlLevel = xmlGetProp(subNode, BAD_CAST("level"));
827         if (xmlLevel == nullptr) {
828             THERMAL_HILOGE(COMP_SVC, "temp diff level is null");
829             return false;
830         }
831         if (!StrToInt(reinterpret_cast<char*>(xmlLevel), item.level)) {
832             THERMAL_HILOGE(COMP_SVC, "temp diff item level is illegal positive number.");
833             xmlFree(xmlLevel);
834             return false;
835         }
836         xmlFree(xmlLevel);
837         THERMAL_HILOGD(COMP_SVC, "temp diff level: %{public}d, temp diff: %{public}d",
838             item.level, item.tempDiff);
839         infoList.push_back(item);
840     }
841     return true;
842 }
843 
ParseTempDiffValue(const xmlNodePtr & cur,const std::string & sensor1,const std::string & sensor2,TempDiffItem & item)844 bool ThermalSrvConfigParser::ParseTempDiffValue(const xmlNodePtr& cur,
845     const std::string& sensor1, const std::string& sensor2, TempDiffItem& item)
846 {
847     xmlChar* xmlTempDiffTrigger = xmlGetProp(cur, BAD_CAST("temp_diff_trigger"));
848     if (xmlTempDiffTrigger == nullptr) {
849         THERMAL_HILOGE(COMP_SVC, "temp diff trigger value is null");
850         return false;
851     }
852 
853     if (!StrToInt(reinterpret_cast<char*>(xmlTempDiffTrigger), item.tempDiff)) {
854         THERMAL_HILOGE(COMP_SVC, "temp diff value is a illegal number");
855         xmlFree(xmlTempDiffTrigger);
856         return false;
857     }
858     item.sensor1 = sensor1;
859     item.sensor2 = sensor2;
860     xmlFree(xmlTempDiffTrigger);
861     return true;
862 }
863 } // namespace PowerMgr
864 } // namespace OHOS
865