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