1 #pragma once 2 3 #include <sdbusplus/bus.hpp> 4 #include <sdbusplus/server/object.hpp> 5 #include <org/open_power/OCC/Status/server.hpp> 6 #include <org/open_power/Control/Host/server.hpp> 7 #include "occ_events.hpp" 8 #include "occ_device.hpp" 9 namespace open_power 10 { 11 namespace occ 12 { 13 14 namespace Base = sdbusplus::org::open_power::OCC::server; 15 using Interface = sdbusplus::server::object::object<Base::Status>; 16 17 // IPMID's host control application 18 namespace Control = sdbusplus::org::open_power::Control::server; 19 20 // For waiting on signals 21 namespace sdbusRule = sdbusplus::bus::match::rules; 22 23 // OCC status instance. Ex. for "occ0", the instance is 0 24 using instanceID = int; 25 26 // IPMI sensor ID for a given OCC instance 27 using sensorID = uint8_t; 28 29 /** @class Status 30 * @brief Implementation of OCC Active Status 31 */ 32 class Status : public Interface 33 { 34 public: 35 Status() = delete; 36 ~Status() = default; 37 Status(const Status&) = delete; 38 Status& operator=(const Status&) = delete; 39 Status(Status&&) = default; 40 Status& operator=(Status&&) = default; 41 42 /** @brief Constructs the Status object and 43 * the underlying device object 44 * 45 * @param[in] bus - DBus bus to attach to 46 * @param[in] path - DBus object path 47 */ 48 Status(sdbusplus::bus::bus& bus, EventPtr& event, const char* path) 49 : Interface(bus, path), 50 bus(bus), 51 path(path), 52 instance(((this->path.back() - '0'))), 53 device(event, 54 name + std::to_string(instance + 1), 55 std::bind(&Status::deviceErrorHandler, this)), 56 hostControlSignal( 57 bus, 58 sdbusRule::type::signal() + 59 sdbusRule::member("CommandComplete") + 60 sdbusRule::path("/org/open_power/control/host0") + 61 sdbusRule::interface("org.open_power.Control.Host") + 62 sdbusRule::argN(0, Control::convertForMessage( 63 Control::Host::Command::OCCReset)), 64 std::bind(std::mem_fn(&Status::hostControlEvent), 65 this, std::placeholders::_1)) 66 { 67 // Nothing to do here 68 } 69 70 /** @brief Since we are overriding the setter-occActive but not the 71 * getter-occActive, we need to have this using in order to 72 * allow passthrough usage of the getter-occActive 73 */ 74 using Base::Status::occActive; 75 76 /** @brief SET OccActive to True or False 77 * 78 * @param[in] value - Intended value 79 * 80 * @return - Updated value of the property 81 */ 82 bool occActive(bool value) override; 83 84 private: 85 86 /** @brief sdbus handle */ 87 sdbusplus::bus::bus& bus; 88 89 /** @brief OCC dbus object path */ 90 std::string path; 91 92 /** @brief occ name prefix */ 93 std::string name = OCC_NAME; 94 95 /** @brief OCC instance number. Ex, 0,1, etc */ 96 int instance; 97 98 /** @brief OCC instance to Sensor ID mapping */ 99 static const std::map<instanceID, sensorID> sensorMap; 100 101 /** @brief OCC device object to do bind and unbind */ 102 Device device; 103 104 /** @brief Subscribe to host control signal 105 * 106 * Once the OCC reset is requested, BMC sends that message to host. 107 * If the host does not ack the message, then there would be a timeout 108 * and we need to catch that to log an error 109 **/ 110 sdbusplus::bus::match_t hostControlSignal; 111 112 /** @brief Callback handler when device errors are detected */ 113 void deviceErrorHandler(); 114 115 /** @brief Callback function on host control signals 116 * 117 * @param[in] msg - Data associated with subscribed signal 118 */ 119 void hostControlEvent(sdbusplus::message::message& msg); 120 121 /** @brief Sends a message to host control command handler to reset OCC 122 */ 123 void resetOCC(); 124 }; 125 126 } // namespace occ 127 } // namespace open_power 128