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