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; /**