Add pldm base discovery get tid support

Google-Bug-Id: 311479326
Change-Id: I4f0db0837a65d14bdbffee650922aee3a377d78b
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 5018ab2..efb2035 100644
--- a/util/state_machine/discovery/base/base_disc_state_machine.cpp
+++ b/util/state_machine/discovery/base/base_disc_state_machine.cpp
@@ -1,5 +1,10 @@
 #include "base_disc_state_machine.hpp"
 
+#include "libpldm/base.h"
+#include "libpldm/pldm.h"
+
+#include "interface/pldm_interface.hpp"
+
 #include <stdplus/print.hpp>
 #include <util/common.hpp>
 
@@ -17,13 +22,127 @@
 
 OperationStatus BaseDiscoveryStateMachine::run()
 {
-    // TODO(@harshtya): Implement run function for state machine
+    stdplus::print(stderr, "Trigeering PLDM Base discovery for device {}...",
+                   this->deviceName);
+    if (!this->initialized &&
+        this->requesterStatus != StateMachineStatus::NoPendingAction)
+    {
+        return OperationStatus::StateMachineInitializationError;
+    }
+
+    // Setting up the initial command set
+    this->nextCommand = PLDM_GET_TID;
+    this->requesterStatus = StateMachineStatus::ReadyToPickNextRequest;
+    for (int processCounter = 0; processCounter < BASE_REQUEST_RETRIES;
+         processCounter++)
+    {
+        if (this->requesterStatus == StateMachineStatus::NoPendingAction)
+        {
+            stdplus::print(stderr, "Base discovery successfully completed\n");
+            break;
+        }
+        OperationStatus status = triggerNextCommand();
+        if (status != OperationStatus::Success)
+        {
+            stdplus::print(stderr,
+                           "Base discovery failed at command {} with "
+                           "status: {}\n",
+                           std::to_string(this->nextCommand),
+                           static_cast<int>(status));
+            return status;
+        }
+
+        if (processCounter == (BASE_REQUEST_RETRIES - 1))
+        {
+            stdplus::print(stderr, "Base discovery failed due infinite loop\n");
+            return OperationStatus::OperationFailure;
+        }
+    }
     return OperationStatus::Success;
 }
 
 OperationStatus BaseDiscoveryStateMachine::triggerNextCommand()
 {
-    // TODO(@harshtya): Implement State Machine
+    switch (this->nextCommand)
+    {
+        case PLDM_GET_TID:
+            return processGetTidRequest();
+        case PLDM_GET_PLDM_TYPES:
+            return processGetPldmTypesRequest();
+        case PLDM_GET_PLDM_VERSION:
+            return processGetPldmVersionRequest();
+        case PLDM_GET_PLDM_COMMANDS:
+            return processGetPldmCommandsRequest();
+        default:
+            return OperationStatus::NoNextCommandFound;
+    }
+    return OperationStatus::Success;
+}
+
+OperationStatus BaseDiscoveryStateMachine::processGetTidRequest()
+{
+    int requestBytes = baseCommandRequestSize.at(PLDM_GET_TID);
+    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+    int rc = encode_get_tid_req(this->instanceId, request);
+    if (rc)
+    {
+        stdplus::print(
+            stderr,
+            "Encoding TID request failed in base discovery with rc: {} for "
+            "device {}\n",
+            rc, this->deviceName);
+        return OperationStatus::EncodingRequestFailure;
+    }
+
+    rc = pldmSendAtNetwork(this->eid, this->netId, this->fd, requestMsg.data(),
+                           requestMsg.size());
+    if (rc)
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmSendFailure;
+    }
+    std::vector<uint8_t> response(
+        sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES, 0);
+    uint8_t* responseMsg = response.data();
+    size_t responseMsgSize = sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES;
+    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
+    rc = pldmRecvAtNetwork(this->eid, this->netId, this->fd, this->instanceId,
+                           &responseMsg, &responseMsgSize);
+    if (rc)
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmRecvFailure;
+    }
+
+    stdplus::print(stderr, "Pushing response for GET_TID for device {}\n",
+                   this->deviceName);
+    OperationStatus status = pushCommandResponse(responsePtr, responseMsgSize);
+    if (status != OperationStatus::Success)
+    {
+        stdplus::print(stderr,
+                       "Failed to push response for Get TID in base "
+                       "discovery with status: {} for device: {}\n",
+                       static_cast<int>(status), this->deviceName);
+    }
+    return status;
+}
+
+OperationStatus BaseDiscoveryStateMachine::processGetPldmTypesRequest()
+{
+    // TODO(@harshtya): Implement processGetPldmTypesRequest
+    return OperationStatus::Success;
+}
+
+OperationStatus BaseDiscoveryStateMachine::processGetPldmVersionRequest()
+{
+    // TODO(@harshtya): Implement processGetPldmVersionRequest
+    return OperationStatus::Success;
+}
+
+OperationStatus BaseDiscoveryStateMachine::processGetPldmCommandsRequest()
+{
+    // TODO(@harshtya): Implement processGetPldmCommandsRequest
     return OperationStatus::Success;
 }
 
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 a6bf4c4..d1b15f9 100644
--- a/util/state_machine/discovery/base/base_disc_state_machine.hpp
+++ b/util/state_machine/discovery/base/base_disc_state_machine.hpp
@@ -8,11 +8,18 @@
 
 #include <array>
 #include <optional>
+#include <unordered_map>
 
 #define PLDM_TYPES 6
 #define MAX_DEV_NAME_SIZE 32
 #define BASE_REQUEST_RETRIES 50
 
+const std::unordered_map<uint8_t, int> baseCommandRequestSize = {
+    {PLDM_GET_TID, 0},
+    {PLDM_GET_PLDM_TYPES, 0},
+    {PLDM_GET_PLDM_VERSION, PLDM_GET_VERSION_REQ_BYTES},
+    {PLDM_GET_PLDM_COMMANDS, PLDM_GET_COMMANDS_REQ_BYTES}};
+
 /**
  * @brief Perform base discovery
  */