Add SBE timeout handling

Add an Error instance to detect SBE timeouts in the driver.
Refactor the PLDM code to handle another requeset type (the HRESET) and
another type of sensor event (success or failure of the HRESET).
Handle the timeout and the PLDM event state change in the Manager by
changing the SBE state and requesting an SBE dump if necessary.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Change-Id: I30d8f9de1914d9808ddb7b547cc57085a5e5779e
diff --git a/pldm.hpp b/pldm.hpp
index 811ed47..3add821 100644
--- a/pldm.hpp
+++ b/pldm.hpp
@@ -17,11 +17,11 @@
 using EntityType = uint16_t;
 using EntityInstance = uint16_t;
 using EventState = uint8_t;
-using OccInstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>;
+using InstanceToEffecter = std::map<open_power::occ::instanceID, EffecterID>;
 using PdrList = std::vector<std::vector<uint8_t>>;
 using SensorID = uint16_t;
 using SensorOffset = uint8_t;
-using SensorToOCCInstance = std::map<SensorID, open_power::occ::instanceID>;
+using SensorToInstance = std::map<SensorID, open_power::occ::instanceID>;
 using TerminusID = uint8_t;
 
 /** @brief Hardcoded TID */
@@ -53,8 +53,10 @@
      *                        changes.
      */
     explicit Interface(
-        std::function<bool(open_power::occ::instanceID, bool)> callBack) :
+        std::function<bool(open_power::occ::instanceID, bool)> callBack,
+        std::function<void(open_power::occ::instanceID, bool)> sbeCallBack) :
         callBack(callBack),
+        sbeCallBack(sbeCallBack),
         pldmEventSignal(
             open_power::occ::utils::getBus(),
             MatchRules::type::signal() +
@@ -71,45 +73,46 @@
                       std::placeholders::_1))
     {}
 
-    /** @brief Fetch the OCC state sensor PDRs and populate the cache with
-     *         sensorId to OCC instance mapping information and the sensor
-     *         offset for Operational Running Status.
+    /** @brief Fetch the state sensor PDRs and populate the cache with
+     *         sensorId to OCC/SBE instance mapping information and the sensor
+     *         offset for the relevent state set.
      *
-     *  @param[in] pdrs - OCC state sensor PDRs
-     *  @param[out] sensorInstanceMap - map of sensorID to OCC instance
+     *  @param[in] stateSetId - the state set ID to look for
+     *  @param[out] sensorInstanceMap - map of sensorID to instance
      *  @param[out] sensorOffset - sensor offset of interested state set ID
      */
-    void fetchOCCSensorInfo(const PdrList& pdrs,
-                            SensorToOCCInstance& sensorInstanceMap,
-                            SensorOffset& sensorOffset);
+    void fetchSensorInfo(uint16_t stateSetId,
+                         SensorToInstance& sensorInstanceMap,
+                         SensorOffset& sensorOffset);
 
-    /** @brief Fetch the OCC state effecter PDRs and populate the cache with
-     *         OCC instance to EffecterID information.
+    /** @brief Fetch the OCC/SBE state effecter PDRs and populate the cache
+     *         with OCC/SBE instance to EffecterID information.
      *
-     *  @param[in] pdrs - OCC state effecter PDRs
-     *  @param[out] instanceToEffecterMap - map of OCC instance to effecterID
+     *  @param[in] entityId - the entity ID to query
+     *  @param[in] stateSetId - the state set ID to look for
+     *  @param[out] instanceToEffecterMap - map of instance to effecterID
      *  @param[out] count - sensor offset of interested state set ID
-     *  @param[out] bootRestartPos - position of Boot/Restart Cause stateSetID
+     *  @param[out] stateIdPos - position of the stateSetID
      */
-    void fetchOCCEffecterInfo(const PdrList& pdrs,
-                              OccInstanceToEffecter& instanceToEffecterMap,
-                              CompositeEffecterCount& count,
-                              uint8_t& bootRestartPos);
+    void fetchEffecterInfo(uint16_t entityId, uint16_t stateSetId,
+                           InstanceToEffecter& instanceToEffecterMap,
+                           CompositeEffecterCount& count, uint8_t& stateIdPos);
 
     /** @brief Prepare the request for SetStateEffecterStates command
      *
      *  @param[in] instanceId - PLDM instanceID
-     *  @param[in] instanceToEffecterMap - map of OCC instance to effecterID
-     *  @param[in] count - compositeEffecterCount for OCC reset effecter PDR
-     *  @param[in] bootRestartPos - position of Boot/Restart Cause stateSetID
+     *  @param[in] effecterId - the instance effecter ID
+     *  @param[in] effecterCount - compositeEffecterCount for the effecter PDR
+     *  @param[in] stateIdPos - position of the stateSetID
+     *  @param[in] stateSetValue - the value to set the state set to
      *
-     *  @return PLDM request message to be sent to host for OCC reset, empty
-     *          response in the case of failure.
+     *  @return PLDM request message to be sent to host for OCC reset or SBE
+     *          HRESET, empty response in the case of failure.
      */
     std::vector<uint8_t>
         prepareSetEffecterReq(uint8_t instanceId, EffecterID effecterId,
                               CompositeEffecterCount effecterCount,
-                              uint8_t bootRestartPos);
+                              uint8_t stateIdPos, uint8_t stateSetValue);
 
     /** @brief Send the PLDM message to reset the OCC
      *
@@ -118,12 +121,24 @@
      */
     void resetOCC(open_power::occ::instanceID occInstanceId);
 
+    /** @brief Send the PLDM message to perform the HRESET
+     *
+     *  @param[in] instanceID - SBE instance to HRESET
+     */
+    void sendHRESET(open_power::occ::instanceID sbeInstanceId);
+
   private:
     /** @brief Callback handler to be invoked when the state of the OCC
      *         changes
      */
     std::function<bool(open_power::occ::instanceID, bool)> callBack = nullptr;
 
+    /** @brief Callback handler to be invoked when the maintenance state of the
+     *         SBE changes
+     */
+    std::function<void(open_power::occ::instanceID, bool)> sbeCallBack =
+        nullptr;
+
     /** @brief Used to subscribe to D-Bus PLDM StateSensorEvent signal and
      *         processes if the event corresponds to OCC state change.
      */
@@ -134,25 +149,46 @@
 
     /** @brief PLDM Sensor ID to OCC Instance mapping
      */
-    SensorToOCCInstance sensorToOCCInstance;
+    SensorToInstance sensorToOCCInstance;
 
-    /** @brief Sensor offset of state set ID
+    /** @brief PLDM Sensor ID to SBE Instance mapping
+     */
+    SensorToInstance sensorToSBEInstance;
+
+    /** @brief Sensor offset of OCC state set ID
      * PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS in state sensor PDR.
      */
-    SensorOffset sensorOffset;
+    SensorOffset OCCSensorOffset;
+
+    /** @brief Sensor offset of the SBE state set ID
+     * PLDM_OEM_IBM_SBE_HRESET_STATE in state sensor PDR.
+     */
+    SensorOffset SBESensorOffset;
 
     /** @brief OCC Instance mapping to PLDM Effecter ID
      */
-    OccInstanceToEffecter occInstanceToEffecter;
+    InstanceToEffecter occInstanceToEffecter;
+
+    /** @brief SBE instance mapping to PLDM Effecter ID
+     */
+    InstanceToEffecter sbeInstanceToEffecter;
 
     /** @brief compositeEffecterCount for OCC reset state effecter PDR */
-    CompositeEffecterCount effecterCount = 0;
+    CompositeEffecterCount OCCEffecterCount = 0;
+
+    /** @brief compositeEffecterCount for SBE HRESET state effecter PDR */
+    CompositeEffecterCount SBEEffecterCount = 0;
 
     /** @brief Position of Boot/Restart Cause stateSetID in OCC state
      *         effecter PDR
      */
     uint8_t bootRestartPosition = 0;
 
+    /** @brief Position of the SBE maintenance stateSetID in the state
+     *         effecter PDR
+     */
+    uint8_t sbeMaintenanceStatePosition = 0;
+
     /** @brief When the OCC state changes host sends PlatformEventMessage
      *         StateSensorEvent, this function processes the D-Bus signal
      *         with the sensor event information and invokes the callback
@@ -189,6 +225,20 @@
     {
         return (occInstanceToEffecter.empty() ? false : true);
     }
+
+    /** @brief Query PLDM for the MCTP requester instance id
+     *
+     * @param[out] - the instance id
+     *
+     * @return true if the id was found and false if not
+     */
+    bool getMctpInstanceId(uint8_t& instanceId);
+
+    /** @brief Send the PLDM request
+     *
+     * @param[in] - the request data
+     */
+    void sendPldm(const std::vector<uint8_t>& request);
 };
 
 } // namespace pldm