summaryrefslogtreecommitdiffstats
path: root/occ_status.hpp
blob: 74839d0eccc64f763f85c1f642ce74cbf17080b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#pragma once

#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
#include <org/open_power/OCC/Status/server.hpp>
#include <org/open_power/Control/Host/server.hpp>
#include "occ_events.hpp"
#include "occ_device.hpp"
namespace open_power
{
namespace occ
{

namespace Base = sdbusplus::org::open_power::OCC::server;
using Interface = sdbusplus::server::object::object<Base::Status>;

// IPMID's host control application
namespace Control = sdbusplus::org::open_power::Control::server;

// For waiting on signals
namespace sdbusRule = sdbusplus::bus::match::rules;

// OCC status instance. Ex. for "occ0", the instance is 0
using instanceID = int;

// IPMI sensor ID for a given OCC instance
using sensorID = uint8_t;

/** @class Status
 *  @brief Implementation of OCC Active Status
 */
class Status : public Interface
{
    public:
        Status() = delete;
        ~Status() = default;
        Status(const Status&) = delete;
        Status& operator=(const Status&) = delete;
        Status(Status&&) = default;
        Status& operator=(Status&&) = default;

        /** @brief Constructs the Status object and
         *         the underlying device object
         *
         *  @param[in] bus  - DBus bus to attach to
         *  @param[in] path - DBus object path
         */
        Status(sdbusplus::bus::bus& bus, EventPtr& event, const char* path)
            : Interface(bus, path),
              bus(bus),
              path(path),
              instance(((this->path.back() - '0'))),
              device(event,
                     name + std::to_string(instance + 1),
                     std::bind(&Status::deviceErrorHandler, this)),
              hostControlSignal(
                     bus,
                     sdbusRule::type::signal() +
                     sdbusRule::member("CommandComplete") +
                     sdbusRule::path("/org/open_power/control/host0") +
                     sdbusRule::interface("org.open_power.Control.Host") +
                     sdbusRule::argN(0, Control::convertForMessage(
                             Control::Host::Command::OCCReset)),
                     std::bind(std::mem_fn(&Status::hostControlEvent),
                            this, std::placeholders::_1))
        {
            // Nothing to do here
        }

        /** @brief Since we are overriding the setter-occActive but not the
         *         getter-occActive, we need to have this using in order to
         *         allow passthrough usage of the getter-occActive
         */
        using Base::Status::occActive;

        /** @brief SET OccActive to True or False
         *
         *  @param[in] value - Intended value
         *
         *  @return          - Updated value of the property
         */
        bool occActive(bool value) override;

    private:

        /** @brief sdbus handle */
        sdbusplus::bus::bus& bus;

        /** @brief OCC dbus object path */
        std::string path;

        /** @brief occ name prefix */
        std::string name = OCC_NAME;

        /** @brief OCC instance number. Ex, 0,1, etc */
        int instance;

        /** @brief OCC instance to Sensor ID mapping */
        static const std::map<instanceID, sensorID> sensorMap;

        /** @brief OCC device object to do bind and unbind */
        Device device;

        /** @brief Subscribe to host control signal
         *
         *  Once the OCC reset is requested, BMC sends that message to host.
         *  If the host does not ack the message, then there would be a timeout
         *  and we need to catch that to log an error
         **/
        sdbusplus::bus::match_t hostControlSignal;

        /** @brief Indicates whether a hub FSI scan has been attempted or not */
        static bool hubFsiScanDone;

        /** @brief Callback handler when device errors are detected */
        void deviceErrorHandler();

        /** @brief Callback function on host control signals
         *
         *  @param[in]  msg - Data associated with subscribed signal
         */
        void hostControlEvent(sdbusplus::message::message& msg);

        /** @brief Sends a message to host control command handler to reset OCC
         */
        void resetOCC();

        /** @brief Initiates hub FSI scan so that /dev/occ files are created
         */
        void scanHubFSI();
};

} // namespace occ
} // namespace open_power
OpenPOWER on IntegriCloud