Add response handlers for base discovery
Google-Bug-Id: 312354702
Change-Id: I2ad257111579ddb1ed6486345a6034bd53b98ac6
Signed-off-by: Harsh Tyagi <harshtya@google.com>
diff --git a/util/state_machine/discovery/base/base_disc_state_machine.cpp b/util/state_machine/discovery/base/base_disc_state_machine.cpp
index d52cb39..76f5725 100644
--- a/util/state_machine/discovery/base/base_disc_state_machine.cpp
+++ b/util/state_machine/discovery/base/base_disc_state_machine.cpp
@@ -291,10 +291,194 @@
}
OperationStatus BaseDiscoveryStateMachine::pushCommandResponse(
- [[maybe_unused]] struct pldm_msg* respMsg, [[maybe_unused]] size_t respSize)
+ const struct pldm_msg* respMsg, size_t respSize)
{
- // TODO(@harshtya): Implement pushCommandResponse
- return OperationStatus::Success;
+ switch (this->nextCommand)
+ {
+ case PLDM_GET_TID:
+ {
+ uint8_t completionCode = DEFAULT_INITIAL_VAL;
+ uint8_t tid = DEFAULT_INITIAL_VAL;
+ int rc = decode_get_tid_resp(respMsg,
+ respSize - sizeof(struct pldm_msg_hdr),
+ &completionCode, &tid);
+ if (rc || completionCode)
+ {
+ this->requesterStatus = StateMachineStatus::RequestFailed;
+ stdplus::print(stderr,
+ "Get TID response decode failed with rc:"
+ " {} and completion code: {}\n",
+ rc, std::to_string(completionCode));
+ return OperationStatus::IncorrectResponseMsg;
+ }
+ this->tid = tid;
+ this->nextCommand = PLDM_GET_PLDM_TYPES;
+ this->requesterStatus = StateMachineStatus::ReadyToPickNextRequest;
+ return OperationStatus::Success;
+ }
+
+ case PLDM_GET_PLDM_TYPES:
+ {
+ uint8_t completionCode = DEFAULT_INITIAL_VAL;
+ int rc = decode_get_types_resp(
+ respMsg, respSize - sizeof(struct pldm_msg_hdr),
+ &completionCode, this->pldmTypes.data());
+ if (rc || completionCode)
+ {
+ this->requesterStatus = StateMachineStatus::RequestFailed;
+ stdplus::print(
+ stderr,
+ "Get PLDM Type response decoded for "
+ "pldm GetTypes failed with rc: {} and completion code: {}\n",
+ rc, std::to_string(completionCode));
+ return OperationStatus::IncorrectResponseMsg;
+ }
+
+ // Setting the initial pldm_type as PLDM_BASE
+ this->commandPldmType = PLDM_BASE;
+ this->nextCommand = PLDM_GET_PLDM_VERSION;
+ this->requesterStatus = StateMachineStatus::ReadyToPickNextRequest;
+ return OperationStatus::Success;
+ }
+ case PLDM_GET_PLDM_VERSION:
+ {
+ ver32_t versionOut;
+ uint8_t completionCode = DEFAULT_INITIAL_VAL;
+ uint8_t retFlag = DEFAULT_INITIAL_VAL;
+ uint32_t retTransferHandle = DEFAULT_INITIAL_VAL;
+ int rc = decode_get_version_resp(
+ respMsg, respSize - sizeof(struct pldm_msg_hdr),
+ &completionCode, &retTransferHandle, &retFlag, &versionOut);
+
+ if (rc || completionCode)
+ {
+ this->requesterStatus = StateMachineStatus::RequestFailed;
+ stdplus::print(
+ stderr,
+ "Get PLDM Versions response decoded for "
+ "pldm get versions failed on pldm type: {} with rc: {} and "
+ "completion code: {}\n",
+ std::to_string(this->commandPldmType), rc,
+ std::to_string(completionCode));
+ return OperationStatus::IncorrectResponseMsg;
+ }
+ uint8_t currentPldmType = this->commandPldmType;
+ this->pldmVersions[currentPldmType] = versionOut;
+
+ std::optional<uint8_t> nextPldmType =
+ getNextPldmTypeToBeProcessed(currentPldmType);
+
+ if (nextPldmType.has_value())
+ {
+ // get the version for the next pldm type
+ this->commandPldmType = nextPldmType.value();
+ this->nextCommand = PLDM_GET_PLDM_VERSION;
+ this->requesterStatus =
+ StateMachineStatus::ReadyToPickNextRequest;
+ }
+ else
+ {
+ // All available pldm types processed
+ this->nextCommand = PLDM_GET_PLDM_COMMANDS;
+ this->requesterStatus =
+ StateMachineStatus::ReadyToPickNextRequest;
+ this->commandPldmType = PLDM_BASE;
+ }
+ return OperationStatus::Success;
+ }
+ case PLDM_GET_PLDM_COMMANDS:
+ {
+ uint8_t completionCode = DEFAULT_INITIAL_VAL;
+ bitfield8_t pldmCmds[PLDM_MAX_CMDS_PER_TYPE / 8];
+ int rc = decode_get_commands_resp(
+ respMsg, respSize - sizeof(struct pldm_msg_hdr),
+ &completionCode, pldmCmds);
+ if (rc || completionCode)
+ {
+ this->requesterStatus = StateMachineStatus::RequestFailed;
+ stdplus::print(
+ stderr,
+ "Get PLDM Cmds response decoded for "
+ "pldm get cmds failed on pldm type: {} with rc: {} and "
+ "completion code: {}\n",
+ std::to_string(this->commandPldmType), rc,
+ std::to_string(completionCode));
+ return OperationStatus::IncorrectResponseMsg;
+ }
+ uint8_t currentPldmType = this->commandPldmType;
+
+ for (int i = 0; i < (PLDM_MAX_CMDS_PER_TYPE / 8); i++)
+ {
+ this->pldmCommands[currentPldmType][i] = pldmCmds[i].byte;
+ }
+
+ std::optional<uint8_t> nextPldmType =
+ getNextPldmTypeToBeProcessed(currentPldmType);
+
+ if (nextPldmType.has_value())
+ {
+ this->commandPldmType = nextPldmType.value();
+ this->nextCommand = PLDM_GET_PLDM_COMMANDS;
+ this->requesterStatus =
+ StateMachineStatus::ReadyToPickNextRequest;
+ }
+ else
+ {
+ // All available pldm types processed
+ this->nextCommand =
+ static_cast<int>(OperationStatus::NoNextCommandFound);
+ this->requesterStatus = StateMachineStatus::NoPendingAction;
+ // Setting base PLDM type the PLDM Commands - default
+ this->commandPldmType = PLDM_BASE;
+ }
+ return OperationStatus::Success;
+ }
+ default:
+ return OperationStatus::OperationFailure;
+ }
+}
+
+std::optional<uint8_t>
+ BaseDiscoveryStateMachine::getNextPldmTypeToBeProcessed(uint8_t currentType)
+{
+ // Each bit in a byte returned in pldm type response represents a pldm type
+ // Hence we process each bit to get the corresponding versions and commands
+ // for that bit
+ int byte = currentType / 8;
+ int bit = currentType % 8;
+ bool isBitSet = false;
+
+ while (byte < 8 && !isBitSet)
+ {
+ uint8_t currentByte = this->pldmTypes[byte].byte;
+ int index = bit + 1;
+
+ // Skip already traversed bits of the current byte
+ currentByte = currentByte >> (bit + 1);
+ while (currentByte)
+ {
+ if (currentByte & 1)
+ {
+ isBitSet = true;
+ bit = index;
+ break;
+ }
+ index++;
+ currentByte = currentByte >> 1;
+ }
+
+ if (!isBitSet)
+ {
+ byte++;
+ bit = -1; // We need to start from 0th bit of
+ // the next byte
+ }
+ }
+ if (byte == 8 && !isBitSet)
+ {
+ return std::nullopt;
+ }
+ return (bit + byte * 8);
}
void BaseDiscoveryStateMachine::printState()
diff --git a/util/state_machine/discovery/base/base_disc_state_machine.hpp b/util/state_machine/discovery/base/base_disc_state_machine.hpp
index d1b15f9..55091bb 100644
--- a/util/state_machine/discovery/base/base_disc_state_machine.hpp
+++ b/util/state_machine/discovery/base/base_disc_state_machine.hpp
@@ -32,7 +32,7 @@
OperationStatus triggerNextCommand() override;
- OperationStatus pushCommandResponse(struct pldm_msg* respMsg,
+ OperationStatus pushCommandResponse(const struct pldm_msg* respMsg,
size_t respSize) override;
void printState() override;
diff --git a/util/state_machine/state_machine_factory.hpp b/util/state_machine/state_machine_factory.hpp
index 0539fb6..d00a065 100644
--- a/util/state_machine/state_machine_factory.hpp
+++ b/util/state_machine/state_machine_factory.hpp
@@ -59,7 +59,7 @@
/**
* @brief Updates the state machine after receiving a response
*/
- virtual OperationStatus pushCommandResponse(struct pldm_msg* respMsg,
+ virtual OperationStatus pushCommandResponse(const struct pldm_msg* respMsg,
size_t respSize) = 0;
/**