1 #pragma once
2 #include "libpldm/entity.h"
3 #include "libpldm/platform.h"
4 
5 #include "inband_code_update.hpp"
6 #include "libpldmresponder/oem_handler.hpp"
7 #include "libpldmresponder/pdr_utils.hpp"
8 #include "libpldmresponder/platform.hpp"
9 
10 namespace pldm
11 {
12 namespace responder
13 {
14 namespace oem_ibm_platform
15 {
16 
17 #define PLDM_OEM_IBM_FIRMWARE_UPDATE_STATE 32768
18 #define PLDM_OEM_IBM_BOOT_STATE 32769
19 #define PLDM_OEM_IBM_SYSTEM_POWER_STATE 32771
20 
21 static constexpr auto PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE = 24577;
22 static constexpr auto PLDM_OEM_IBM_VERIFICATION_STATE = 32770;
23 constexpr uint16_t ENTITY_INSTANCE_0 = 0;
24 constexpr uint16_t ENTITY_INSTANCE_1 = 1;
25 
26 enum class CodeUpdateState : uint8_t
27 {
28     START = 0x1,
29     END = 0x2,
30     FAIL = 0x3,
31     ABORT = 0x4,
32     ACCEPT = 0x5,
33     REJECT = 0x6
34 };
35 
36 enum VerificationStateValues
37 {
38     VALID = 0x0,
39     ENTITLEMENT_FAIL = 0x1,
40     BANNED_PLATFORM_FAIL = 0x2,
41     MIN_MIF_FAIL = 0x4,
42 };
43 
44 enum SystemPowerStates
45 {
46     POWER_CYCLE_HARD = 0x1,
47 };
48 
49 class Handler : public oem_platform::Handler
50 {
51   public:
52     Handler(const pldm::utils::DBusHandler* dBusIntf,
53             pldm::responder::CodeUpdate* codeUpdate, int mctp_fd,
54             uint8_t mctp_eid, Requester& requester, sdeventplus::Event& event) :
55         oem_platform::Handler(dBusIntf),
56         codeUpdate(codeUpdate), platformHandler(nullptr), mctp_fd(mctp_fd),
57         mctp_eid(mctp_eid), requester(requester), event(event)
58     {
59         codeUpdate->setVersions();
60     }
61 
62     int getOemStateSensorReadingsHandler(
63         EntityType entityType, EntityInstance entityInstance,
64         StateSetId stateSetId, CompositeCount compSensorCnt,
65         std::vector<get_sensor_state_field>& stateField);
66 
67     int oemSetStateEffecterStatesHandler(
68         uint16_t entityType, uint16_t entityInstance, uint16_t stateSetId,
69         uint8_t compEffecterCnt,
70         std::vector<set_effecter_state_field>& stateField, uint16_t effecterId);
71 
72     /** @brief Method to set the platform handler in the
73      *         oem_ibm_handler class
74      *  @param[in] handler - pointer to PLDM platform handler
75      */
76     void setPlatformHandler(pldm::responder::platform::Handler* handler);
77 
78     /** @brief Method to fetch the effecter ID of the code update PDRs
79      *
80      * @return platformHandler->getNextEffecterId() - returns the
81      *             effecter ID from the platform handler
82      */
83     virtual uint16_t getNextEffecterId()
84     {
85         return platformHandler->getNextEffecterId();
86     }
87 
88     /** @brief Method to fetch the sensor ID of the code update PDRs
89      *
90      * @return platformHandler->getNextSensorId() - returns the
91      *             Sensor ID from the platform handler
92      */
93     virtual uint16_t getNextSensorId()
94     {
95         return platformHandler->getNextSensorId();
96     }
97 
98     /** @brief Method to Generate the OEM PDRs
99      *
100      * @param[in] repo - instance of concrete implementation of Repo
101      */
102     void buildOEMPDR(pdr_utils::Repo& repo);
103 
104     /** @brief Method to send code update event to host
105      * @param[in] sensorId - sendor ID
106      * @param[in] sensorEventClass - event class of sensor
107      * @param[in] sensorOffset - sensor offset
108      * @param[in] eventState - new code update event state
109      * @param[in] prevEventState - previous code update event state
110      * @return none
111      */
112     void sendStateSensorEvent(uint16_t sensorId,
113                               enum sensor_event_class_states sensorEventClass,
114                               uint8_t sensorOffset, uint8_t eventState,
115                               uint8_t prevEventState);
116 
117     /** @brief Method to send encoded request msg of code update event to host
118      *  @param[in] requestMsg - encoded request msg
119      *  @return PLDM status code
120      */
121     int sendEventToHost(std::vector<uint8_t>& requestMsg);
122 
123     /** @brief _processEndUpdate processes the actual work that needs
124      *  to be carried out after EndUpdate effecter is set. This is done async
125      *  after sending response for EndUpdate set effecter
126      *  @param[in] source - sdeventplus event source
127      */
128     void _processEndUpdate(sdeventplus::source::EventBase& source);
129 
130     /** @brief _processStartUpdate processes the actual work that needs
131      *  to be carried out after StartUpdate effecter is set. This is done async
132      *  after sending response for StartUpdate set effecter
133      *  @param[in] source - sdeventplus event source
134      */
135     void _processStartUpdate(sdeventplus::source::EventBase& source);
136 
137     /** @brief _processSystemReboot processes the actual work that needs to be
138      *  carried out after the System Power State effecter is set to reboot
139      *  the system
140      *  @param[in] source - sdeventplus event source
141      */
142     void _processSystemReboot(sdeventplus::source::EventBase& source);
143 
144     ~Handler() = default;
145 
146     pldm::responder::CodeUpdate* codeUpdate; //!< pointer to CodeUpdate object
147     pldm::responder::platform::Handler*
148         platformHandler; //!< pointer to PLDM platform handler
149 
150     /** @brief fd of MCTP communications socket */
151     int mctp_fd;
152 
153     /** @brief MCTP EID of host firmware */
154     uint8_t mctp_eid;
155 
156     /** @brief reference to Requester object, primarily used to access API to
157      *  obtain PLDM instance id.
158      */
159     Requester& requester;
160     /** @brief sdeventplus event source */
161     std::unique_ptr<sdeventplus::source::Defer> assembleImageEvent;
162     std::unique_ptr<sdeventplus::source::Defer> startUpdateEvent;
163     std::unique_ptr<sdeventplus::source::Defer> systemRebootEvent;
164 
165     /** @brief reference of main event loop of pldmd, primarily used to schedule
166      *  work
167      */
168     sdeventplus::Event& event;
169 
170   private:
171     /** @brief D-Bus property changed signal match for CurrentPowerState*/
172     std::unique_ptr<sdbusplus::bus::match::match> chassisOffMatch;
173 };
174 
175 /** @brief Method to encode code update event msg
176  *  @param[in] eventType - type of event
177  *  @param[in] eventDataVec - vector of event data to be sent to host
178  *  @param[in/out] requestMsg - request msg to be encoded
179  *  @param[in] instanceId - instance ID
180  *  @return PLDM status code
181  */
182 int encodeEventMsg(uint8_t eventType, const std::vector<uint8_t>& eventDataVec,
183                    std::vector<uint8_t>& requestMsg, uint8_t instanceId);
184 
185 } // namespace oem_ibm_platform
186 
187 } // namespace responder
188 
189 } // namespace pldm
190