1 #pragma once 2 3 #include "sensorhandler.h" 4 #include "types.hpp" 5 #include "utils.hpp" 6 #include "host-ipmid/ipmid-api.h" 7 8 namespace ipmi 9 { 10 namespace sensor 11 { 12 13 using Assertion = uint16_t; 14 using Deassertion = uint16_t; 15 using AssertionSet = std::pair<Assertion, Deassertion>; 16 17 using Service = std::string; 18 using Path = std::string; 19 using Interface = std::string; 20 21 using ServicePath = std::pair<Path, Service>; 22 23 using Interfaces = std::vector<Interface>; 24 25 using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>; 26 27 /** @brief get the D-Bus service and service path 28 * @param[in] bus - The Dbus bus object 29 * @param[in] interface - interface to the service 30 * @param[in] path - interested path in the list of objects 31 * @return pair of service path and service 32 */ 33 ServicePath getServiceAndPath(sdbusplus::bus::bus& bus, 34 const std::string& interface, 35 const std::string& path = std::string()); 36 37 /** @brief Make assertion set from input data 38 * @param[in] cmdData - Input sensor data 39 * @return pair of assertion and deassertion set 40 */ 41 AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData); 42 43 /** @brief send the message to DBus 44 * @param[in] msg - message to send 45 * @return failure status in IPMI error code 46 */ 47 ipmi_ret_t updateToDbus(IpmiUpdateData& msg); 48 49 namespace get 50 { 51 52 /** 53 * @brief Helper function to map the dbus info to sensor's assertion status 54 * for the get sensor reading command. 55 * 56 * @param[in] sensorInfo - Dbus info related to sensor. 57 * @param[in] path - Dbus object path. 58 * @param[in] interface - Dbus interface. 59 * 60 * @return Response for get sensor reading command. 61 */ 62 GetSensorResponse mapDbusToAssertion(const Info& sensorInfo, 63 const InstancePath& path, 64 const DbusInterface& interface); 65 66 /** 67 * @brief Map the Dbus info to sensor's assertion status in the Get sensor 68 * reading command response. 69 * 70 * @param[in] sensorInfo - Dbus info related to sensor. 71 * 72 * @return Response for get sensor reading command. 73 */ 74 GetSensorResponse assertion(const Info& sensorInfo); 75 76 /** 77 * @brief Maps the Dbus info to the reading field in the Get sensor reading 78 * command response. 79 * 80 * @param[in] sensorInfo - Dbus info related to sensor. 81 * 82 * @return Response for get sensor reading command. 83 */ 84 GetSensorResponse eventdata2(const Info& sensorInfo); 85 86 /** 87 * @brief readingAssertion is a case where the entire assertion state field 88 * serves as the sensor value. 89 * 90 * @tparam T - type of the dbus property related to sensor. 91 * @param[in] sensorInfo - Dbus info related to sensor. 92 * 93 * @return Response for get sensor reading command. 94 */ 95 template<typename T> 96 GetSensorResponse readingAssertion(const Info& sensorInfo) 97 { 98 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; 99 GetSensorResponse response {}; 100 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data()); 101 102 auto service = ipmi::getService(bus, 103 sensorInfo.sensorInterface, 104 sensorInfo.sensorPath); 105 106 auto propValue = ipmi::getDbusProperty( 107 bus, 108 service, 109 sensorInfo.sensorPath, 110 sensorInfo.propertyInterfaces.begin()->first, 111 sensorInfo.propertyInterfaces.begin()->second.begin()->first); 112 113 setAssertionBytes(static_cast<uint16_t>(propValue.get<T>()), responseData); 114 115 return response; 116 } 117 118 /** @brief Map the Dbus info to the reading field in the Get sensor reading 119 * command response 120 * 121 * @tparam T - type of the dbus property related to sensor. 122 * @param[in] sensorInfo - Dbus info related to sensor. 123 * 124 * @return Response for get sensor reading command. 125 */ 126 template<typename T> 127 GetSensorResponse readingData(const Info& sensorInfo) 128 { 129 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; 130 GetSensorResponse response {}; 131 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data()); 132 133 enableScanning(responseData); 134 135 auto service = ipmi::getService(bus, 136 sensorInfo.sensorInterface, 137 sensorInfo.sensorPath); 138 139 auto propValue = ipmi::getDbusProperty( 140 bus, 141 service, 142 sensorInfo.sensorPath, 143 sensorInfo.propertyInterfaces.begin()->first, 144 sensorInfo.propertyInterfaces.begin()->second.begin()->first); 145 146 auto value = static_cast<uint8_t>( 147 (propValue.get<T>() - sensorInfo.scaledOffset) / 148 (sensorInfo.coefficientM ? sensorInfo.coefficientM : 1)); 149 150 setReading(value, responseData); 151 152 return response; 153 } 154 155 } //namespace get 156 157 namespace set 158 { 159 160 /** @brief Make a DBus message for a Dbus call 161 * @param[in] updateInterface - Interface name 162 * @param[in] sensorPath - Path of the sensor 163 * @param[in] command - command to be executed 164 * @param[in] sensorInterface - DBus interface of sensor 165 * @return a dbus message 166 */ 167 IpmiUpdateData makeDbusMsg(const std::string& updateInterface, 168 const std::string& sensorPath, 169 const std::string& command, 170 const std::string& sensorInterface); 171 172 /** @brief Update d-bus based on assertion type sensor data 173 * @param[in] cmdData - input sensor data 174 * @param[in] sensorInfo - sensor d-bus info 175 * @return a IPMI error code 176 */ 177 ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, 178 const Info& sensorInfo); 179 180 /** @brief Update d-bus based on a reading assertion 181 * @tparam T - type of d-bus property mapping this sensor 182 * @param[in] cmdData - input sensor data 183 * @param[in] sensorInfo - sensor d-bus info 184 * @return a IPMI error code 185 */ 186 template<typename T> 187 ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData, 188 const Info& sensorInfo) 189 { 190 auto msg = makeDbusMsg( 191 "org.freedesktop.DBus.Properties", 192 sensorInfo.sensorPath, 193 "Set", 194 sensorInfo.sensorInterface); 195 196 const auto& interface = sensorInfo.propertyInterfaces.begin(); 197 msg.append(interface->first); 198 for (const auto& property : interface->second) 199 { 200 msg.append(property.first); 201 sdbusplus::message::variant<T> value = 202 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7; 203 msg.append(value); 204 } 205 return updateToDbus(msg); 206 } 207 208 /** @brief Update d-bus based on a discrete reading 209 * @param[in] cmdData - input sensor data 210 * @param[in] sensorInfo - sensor d-bus info 211 * @return an IPMI error code 212 */ 213 template<typename T> 214 ipmi_ret_t readingData(const SetSensorReadingReq& cmdData, 215 const Info& sensorInfo) 216 { 217 auto msg = makeDbusMsg( 218 "org.freedesktop.DBus.Properties", 219 sensorInfo.sensorPath, 220 "Set", 221 sensorInfo.sensorInterface); 222 223 const auto& interface = sensorInfo.propertyInterfaces.begin(); 224 msg.append(interface->first); 225 226 ipmi::sensor::Multiplier m = sensorInfo.coefficientM; 227 if (0 == m) 228 { 229 m = 1; // Avoid * 0 230 } 231 232 // TODO: Refactor this into a generated function depending on the type 233 // of conversion for the value between IPMI and dbus. 234 T raw_value = (m * cmdData.reading) + sensorInfo.scaledOffset; 235 236 for (const auto& property : interface->second) 237 { 238 msg.append(property.first); 239 sdbusplus::message::variant<T> value = raw_value; 240 msg.append(value); 241 } 242 return updateToDbus(msg); 243 } 244 245 /** @brief Update d-bus based on eventdata type sensor data 246 * @param[in] cmdData - input sensor data 247 * @param[in] sensorInfo - sensor d-bus info 248 * @return a IPMI error code 249 */ 250 ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, 251 const Info& sensorInfo, 252 uint8_t data); 253 254 /** @brief Update d-bus based on eventdata1 type sensor data 255 * @param[in] cmdData - input sensor data 256 * @param[in] sensorInfo - sensor d-bus info 257 * @return a IPMI error code 258 */ 259 inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData, 260 const Info& sensorInfo) 261 { 262 return eventdata(cmdData, sensorInfo, cmdData.eventData1); 263 } 264 265 /** @brief Update d-bus based on eventdata2 type sensor data 266 * @param[in] cmdData - input sensor data 267 * @param[in] sensorInfo - sensor d-bus info 268 * @return a IPMI error code 269 */ 270 inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData, 271 const Info& sensorInfo) 272 { 273 return eventdata(cmdData, sensorInfo, cmdData.eventData2); 274 } 275 276 /** @brief Update d-bus based on eventdata3 type sensor data 277 * @param[in] cmdData - input sensor data 278 * @param[in] sensorInfo - sensor d-bus info 279 * @return a IPMI error code 280 */ 281 inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData, 282 const Info& sensorInfo) 283 { 284 return eventdata(cmdData, sensorInfo, cmdData.eventData3); 285 } 286 287 }//namespace set 288 289 namespace notify 290 { 291 292 /** @brief Make a DBus message for a Dbus call 293 * @param[in] updateInterface - Interface name 294 * @param[in] sensorPath - Path of the sensor 295 * @param[in] command - command to be executed 296 * @param[in] sensorInterface - DBus interface of sensor 297 * @return a dbus message 298 */ 299 IpmiUpdateData makeDbusMsg(const std::string& updateInterface, 300 const std::string& sensorPath, 301 const std::string& command, 302 const std::string& sensorInterface); 303 304 /** @brief Update d-bus based on assertion type sensor data 305 * @param[in] interfaceMap - sensor interface 306 * @param[in] cmdData - input sensor data 307 * @param[in] sensorInfo - sensor d-bus info 308 * @return a IPMI error code 309 */ 310 ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, 311 const Info& sensorInfo); 312 313 }//namespace notify 314 315 namespace inventory 316 { 317 318 namespace get 319 { 320 321 /** 322 * @brief Map the Dbus info to sensor's assertion status in the Get sensor 323 * reading command response. 324 * 325 * @param[in] sensorInfo - Dbus info related to sensor. 326 * 327 * @return Response for get sensor reading command. 328 */ 329 GetSensorResponse assertion(const Info& sensorInfo); 330 331 } // namespace get 332 333 } // namespace inventory 334 }//namespace sensor 335 }//namespace ipmi 336