1  /*
2   * Copyright (c) 2022 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_simulation_node.h"
17  
18  #include <iostream>
19  #include <cstring>
20  #include <dirent.h>
21  #include <fcntl.h>
22  #include <unistd.h>
23  #include <sys/stat.h>
24  
25  #include "hdf_base.h"
26  #include "securec.h"
27  #include "thermal_log.h"
28  
29  namespace OHOS {
30  namespace HDI {
31  namespace Thermal {
32  namespace V1_1 {
33  namespace {
34  const int32_t MAX_PATH = 256;
35  const int32_t ARG_0 = 0;
36  const int32_t ARG_1 = 1;
37  const int32_t ARG_2 = 2;
38  const int32_t ARG_3 = 3;
39  const int32_t ARG_4 = 4;
40  const int32_t NUM_ZERO = 0;
41  const std::string THERMAL_DIR = "/data/service/el0/thermal/sensor/";
42  const std::string THERMAL_NODE_DIR = "/data/service/el0/thermal/sensor/%s";
43  const std::string THERMAL_TYPE_DIR = "/data/service/el0/thermal/sensor/%s/type";
44  const std::string THERMAL_TEMP_DIR = "/data/service/el0/thermal/sensor/%s/temp";
45  const std::string MITIGATION_DIR = "/data/service/el0/thermal/cooling";
46  const std::string MITIGATION_NODE_DIR = "/data/service/el0/thermal/cooling/%s";
47  const std::string MITIGATION_NODE_FILE = "%s/%s";
48  }
NodeInit()49  int32_t ThermalSimulationNode::NodeInit()
50  {
51      int32_t ret = AddSensorTypeTemp();
52      if (ret != HDF_SUCCESS) {
53          return ret;
54      }
55      ret = AddFanSensorNode();
56      if (ret != HDF_SUCCESS) {
57          return ret;
58      }
59      ret = AddMitigationDevice();
60      if (ret != HDF_SUCCESS) {
61          return ret;
62      }
63      return HDF_SUCCESS;
64  }
65  
CreateNodeDir(std::string dir)66  int32_t ThermalSimulationNode::CreateNodeDir(std::string dir)
67  {
68      if (access(dir.c_str(), 0) != NUM_ZERO) {
69          int32_t flag = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH| S_IXOTH);
70          if (flag == NUM_ZERO) {
71              THERMAL_HILOGI(COMP_HDI, "Create directory successfully.");
72          } else {
73              THERMAL_HILOGE(COMP_HDI, "Fail to create directory, flag: %{public}d", flag);
74              return flag;
75          }
76      } else {
77          THERMAL_HILOGD(COMP_HDI, "This directory already exists.");
78      }
79      return HDF_SUCCESS;
80  }
81  
CreateNodeFile(std::string filePath)82  int32_t ThermalSimulationNode::CreateNodeFile(std::string filePath)
83  {
84      if (access(filePath.c_str(), 0) != 0) {
85          int32_t fd = open(filePath.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH);
86          if (fd < NUM_ZERO) {
87              THERMAL_HILOGE(COMP_HDI, "open failed to file.");
88              return fd;
89          }
90          close(fd);
91      } else {
92          THERMAL_HILOGD(COMP_HDI, "the file already exists.");
93      }
94      return HDF_SUCCESS;
95  }
96  
AddSensorTypeTemp()97  int32_t ThermalSimulationNode::AddSensorTypeTemp()
98  {
99      std::vector<std::string> vFile = {"type", "temp"};
100      std::map<std::string, int32_t> sensor;
101      char nodeBuf[MAX_PATH] = {0};
102      char fileBuf[MAX_PATH] = {0};
103      char typeBuf[MAX_PATH] = {0};
104      char tempBuf[MAX_PATH] = {0};
105      sensor["battery"] = 0;
106      sensor["charger"] = 0;
107      sensor["pa"] = 0;
108      sensor["ap"] = 0;
109      sensor["ambient"] = 0;
110      sensor["cpu"] = 0;
111      sensor["soc"] = 0;
112      sensor["shell"] = 0;
113      sensor["gpu"] = 0;
114      CreateNodeDir(THERMAL_DIR);
115      for (auto dir : sensor) {
116          int32_t ret = snprintf_s(nodeBuf, MAX_PATH, sizeof(nodeBuf) - ARG_1,
117              THERMAL_NODE_DIR.c_str(), dir.first.c_str());
118          if (ret < EOK) {
119              return HDF_FAILURE;
120          }
121          THERMAL_HILOGI(COMP_HDI, "node name: %{public}s", nodeBuf);
122          CreateNodeDir(static_cast<std::string>(nodeBuf));
123          for (const auto& file : vFile) {
124              ret = snprintf_s(fileBuf, MAX_PATH, sizeof(fileBuf) - ARG_1, "%s/%s", nodeBuf, file.c_str());
125              if (ret < EOK) {
126                  return HDF_FAILURE;
127              }
128              THERMAL_HILOGI(COMP_HDI, "file name: %{public}s", fileBuf);
129              CreateNodeFile(static_cast<std::string>(fileBuf));
130          }
131          ret = snprintf_s(typeBuf, MAX_PATH, sizeof(typeBuf) - ARG_1, THERMAL_TYPE_DIR.c_str(), dir.first.c_str());
132          if (ret < EOK) {
133              return HDF_FAILURE;
134          }
135          std::string type = dir.first;
136          WriteFile(typeBuf, type, type.length());
137          ret = snprintf_s(tempBuf, MAX_PATH, sizeof(tempBuf) - ARG_1, THERMAL_TEMP_DIR.c_str(), dir.first.c_str());
138          if (ret < EOK) {
139              return HDF_FAILURE;
140          }
141          std::string temp = std::to_string(dir.second);
142          WriteFile(tempBuf, temp, temp.length());
143      }
144      return HDF_SUCCESS;
145  }
146  
AddFanSensorNode()147  int32_t ThermalSimulationNode::AddFanSensorNode()
148  {
149      char nodePath[MAX_PATH] = {0};
150      char typePath[MAX_PATH] = {0};
151      char speedPath[MAX_PATH] = {0};
152  
153      int32_t ret = snprintf_s(nodePath, MAX_PATH, sizeof(nodePath) - ARG_1,
154          THERMAL_NODE_DIR.c_str(), "fan");
155      if (ret < EOK) {
156          return HDF_FAILURE;
157      }
158      CreateNodeDir(static_cast<std::string>(nodePath));
159  
160      ret = snprintf_s(typePath, MAX_PATH, sizeof(typePath) - ARG_1, "%s/%s", nodePath, "type");
161      if (ret < EOK) {
162          return HDF_FAILURE;
163      }
164      CreateNodeFile(static_cast<std::string>(typePath));
165      std::string type = "fan";
166      WriteFile(typePath, type, type.length());
167  
168      ret = snprintf_s(speedPath, MAX_PATH, sizeof(speedPath) - ARG_1, "%s/%s", nodePath, "speed");
169      if (ret < EOK) {
170          return HDF_FAILURE;
171      }
172      CreateNodeFile(static_cast<std::string>(speedPath));
173      std::string speed = "0";
174      WriteFile(speedPath, speed, speed.length());
175  
176      return HDF_SUCCESS;
177  }
178  
AddMitigationDevice()179  int32_t ThermalSimulationNode::AddMitigationDevice()
180  {
181      int32_t ret;
182      std::string sensor[] = {"cpu", "charger", "gpu", "battery"};
183      std::vector<std::string> vSensor(sensor, sensor + ARG_4);
184      std::string cpu = "freq";
185      std::string charger = "current";
186      std::string gpu = "freq";
187      std::string battery[] = {"current", "voltage"};
188      std::vector<std::string> vFile;
189      char nodeBuf[MAX_PATH] = {0};
190      char fileBuf[MAX_PATH] = {0};
191      int32_t temp = 0;
192      std::string sTemp = std::to_string(temp);
193      CreateNodeDir(MITIGATION_DIR);
194      for (auto dir : vSensor) {
195          ret = snprintf_s(nodeBuf, MAX_PATH, sizeof(nodeBuf) - ARG_1, MITIGATION_NODE_DIR.c_str(), dir.c_str());
196          if (ret < EOK) return HDF_FAILURE;
197          CreateNodeDir(static_cast<std::string>(nodeBuf));
198          vFile.push_back(nodeBuf);
199      }
200      ret = snprintf_s(fileBuf, MAX_PATH, sizeof(fileBuf) - ARG_1, MITIGATION_NODE_FILE.c_str(), vFile[ARG_0].c_str(),
201          cpu.c_str());
202      if (ret < EOK) return HDF_FAILURE;
203      CreateNodeFile(static_cast<std::string>(fileBuf));
204      WriteFile(fileBuf, sTemp, sTemp.length());
205      ret = snprintf_s(fileBuf, MAX_PATH, sizeof(fileBuf) - ARG_1, MITIGATION_NODE_FILE.c_str(), vFile[ARG_1].c_str(),
206          charger.c_str());
207      if (ret < EOK) return HDF_FAILURE;
208      CreateNodeFile(static_cast<std::string>(fileBuf));
209      WriteFile(fileBuf, sTemp, sTemp.length());
210      ret = snprintf_s(fileBuf, MAX_PATH, sizeof(fileBuf) - ARG_1, MITIGATION_NODE_FILE.c_str(), vFile[ARG_2].c_str(),
211          gpu.c_str());
212      if (ret < EOK) {
213          return HDF_FAILURE;
214      }
215      CreateNodeFile(static_cast<std::string>(fileBuf));
216      WriteFile(fileBuf, sTemp, sTemp.length());
217      std::vector<std::string> vBattery(battery, battery + ARG_2);
218      for (auto b : vBattery) {
219          ret = snprintf_s(fileBuf, MAX_PATH, sizeof(fileBuf) - ARG_1, MITIGATION_NODE_FILE.c_str(),
220              vFile[ARG_3].c_str(), b.c_str());
221          if (ret < EOK) {
222              return HDF_FAILURE;
223          }
224          CreateNodeFile(static_cast<std::string>(fileBuf));
225          WriteFile(fileBuf, sTemp, sTemp.length());
226      }
227      return HDF_SUCCESS;
228  }
229  
WriteFile(std::string path,std::string buf,size_t size)230  int32_t ThermalSimulationNode::WriteFile(std::string path, std::string buf, size_t size)
231  {
232      int32_t fd = open(path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
233      if (fd < NUM_ZERO) {
234          THERMAL_HILOGE(COMP_HDI, "open failed to file.");
235      }
236      write(fd, buf.c_str(), size);
237      close(fd);
238      return HDF_SUCCESS;
239  }
240  } // V1_1
241  } // Thermal
242  } // HDI
243  } // OHOS
244