1 #pragma once
2 
3 #include "occ_errors.hpp"
4 #include "utils.hpp"
5 
6 #include <org/open_power/OCC/PassThrough/server.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/server/object.hpp>
9 #include <string>
10 
11 namespace open_power
12 {
13 namespace occ
14 {
15 
16 // For waiting on signals
17 namespace sdbusRule = sdbusplus::bus::match::rules;
18 
19 enum class CmdStatus
20 {
21     SUCCESS,
22     OPEN_FAILURE,
23     FAILURE,
24     INVALID_CHECKSUM
25 };
26 
27 /** @brief Trace block of data in hex with log<level:INFO>
28  *
29  *  @param[in] data - vector containing data to trace
30  *  @param[in] data_len - optional number of bytes to trace
31  *  If 0, entire vector will be traced.
32  */
33 void dump_hex(const std::vector<std::uint8_t>& data,
34               const unsigned int data_len = 0);
35 
36 /** @class OccCommand
37  *  @brief Send commands and process respsonses from the OCC
38  */
39 class OccCommand
40 {
41   public:
42     OccCommand() = delete;
43     OccCommand(const OccCommand&) = delete;
44     OccCommand& operator=(const OccCommand&) = delete;
45     OccCommand(OccCommand&&) = default;
46     OccCommand& operator=(OccCommand&&) = default;
47 
48     /** @brief Ctor to set up which OCC the command will go to
49      *
50      *  @param[in] instance - OCC instance
51      *  @param[in] path - Path to attach at
52      */
53     OccCommand(uint8_t instance, const char* path);
54 
55     /** @brief Dtor to clean up and close device */
56     ~OccCommand()
57     {
58         closeDevice();
59     }
60 
61     /** @brief Send the command to the OCC and collect the response.
62      * The checksum will be validated and removed from the response.
63      *
64      *  @param[in] command - command to pass-through
65      *  @param[out] response - response
66      *  returns SUCCESS if response was received
67      */
68     CmdStatus send(const std::vector<std::uint8_t>& command,
69                    std::vector<std::uint8_t>& response);
70 
71   private:
72     /** @brief Instance number of the target OCC */
73     uint8_t occInstance;
74 
75     /** @brief OCC path on the bus */
76     std::string path;
77 
78     /** @brief OCC device path
79      *  For now, here is the hard-coded mapping until
80      *  the udev rule is in.
81      *  occ0 --> /dev/occ1
82      *  occ1 --> /dev/occ2
83      *  ...
84      */
85     std::string devicePath;
86 
87     /** @brief Indicates whether or not the OCC is currently active */
88     bool occActive = false;
89 
90     /** brief file descriptor associated with occ device */
91     int fd = -1;
92 
93     /** @brief Subscribe to OCC Status signal
94      *
95      *  Once the OCC status gets to active, only then we will get /dev/occ2
96      *  populated and hence need to wait on that before opening that
97      */
98     sdbusplus::bus::match_t activeStatusSignal;
99 
100     /** Opens devicePath and populates file descriptor */
101     void openDevice();
102 
103     /** Closed the fd associated with opened device */
104     void closeDevice();
105 
106     /** @brief Callback function on OCC Status change signals
107      *
108      *  @param[in]  msg - Data associated with subscribed signal
109      */
110     void activeStatusEvent(sdbusplus::message::message& msg);
111 };
112 
113 } // namespace occ
114 } // namespace open_power
115