Add PLDM GetTypes, GetCmds, GetVersion handlers

Google-Bug-Id: 311697203
Change-Id: Ibb430403a3a1663f0f7dee856531eea3a27f5fab
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 efb2035..d52cb39 100644
--- a/util/state_machine/discovery/base/base_disc_state_machine.cpp
+++ b/util/state_machine/discovery/base/base_disc_state_machine.cpp
@@ -22,7 +22,7 @@
 
 OperationStatus BaseDiscoveryStateMachine::run()
 {
-    stdplus::print(stderr, "Trigeering PLDM Base discovery for device {}...",
+    stdplus::print(stderr, "Triggering PLDM Base discovery for device {}...\n",
                    this->deviceName);
     if (!this->initialized &&
         this->requesterStatus != StateMachineStatus::NoPendingAction)
@@ -81,9 +81,10 @@
 
 OperationStatus BaseDiscoveryStateMachine::processGetTidRequest()
 {
-    int requestBytes = baseCommandRequestSize.at(PLDM_GET_TID);
-    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
+    std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+                                    baseCommandRequestSize.at(PLDM_GET_TID));
     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
     int rc = encode_get_tid_req(this->instanceId, request);
     if (rc)
     {
@@ -95,9 +96,8 @@
         return OperationStatus::EncodingRequestFailure;
     }
 
-    rc = pldmSendAtNetwork(this->eid, this->netId, this->fd, requestMsg.data(),
-                           requestMsg.size());
-    if (rc)
+    if (pldmSendAtNetwork(this->eid, this->netId, this->fd, requestMsg.data(),
+                          requestMsg.size()))
     {
         this->requesterStatus = StateMachineStatus::RequestFailed;
         return OperationStatus::PldmSendFailure;
@@ -107,9 +107,9 @@
     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)
+
+    if (pldmRecvAtNetwork(this->eid, this->netId, this->fd, this->instanceId,
+                          &responseMsg, &responseMsgSize))
     {
         this->requesterStatus = StateMachineStatus::RequestFailed;
         return OperationStatus::PldmRecvFailure;
@@ -130,20 +130,164 @@
 
 OperationStatus BaseDiscoveryStateMachine::processGetPldmTypesRequest()
 {
-    // TODO(@harshtya): Implement processGetPldmTypesRequest
-    return OperationStatus::Success;
+    std::vector<uint8_t> requestMsg(
+        sizeof(pldm_msg_hdr) + baseCommandRequestSize.at(PLDM_GET_PLDM_TYPES));
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    int rc = encode_get_types_req(this->instanceId, request);
+    if (rc)
+    {
+        stdplus::print(
+            stderr,
+            "Encoding PLDM Types request failed in base discovery with rc: {} "
+            "for device {}\n",
+            rc, this->deviceName);
+        return OperationStatus::EncodingRequestFailure;
+    }
+
+    if (pldmSendAtNetwork(this->eid, this->netId, this->fd, requestMsg.data(),
+                          requestMsg.size()))
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmSendFailure;
+    }
+    std::vector<uint8_t> response(
+        sizeof(pldm_msg_hdr) + PLDM_GET_TYPES_RESP_BYTES, 0);
+    uint8_t* responseMsg = response.data();
+    size_t responseMsgSize = response.size();
+    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
+
+    if (pldmRecvAtNetwork(this->eid, this->netId, this->fd, this->instanceId,
+                          &responseMsg, &responseMsgSize))
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmRecvFailure;
+    }
+    stdplus::print(stderr,
+                   "Pushing response for GET_PLDM_TYPES for device: "
+                   "{}\n",
+                   this->deviceName);
+    OperationStatus status = pushCommandResponse(responsePtr, responseMsgSize);
+    if (status != OperationStatus::Success)
+    {
+        stdplus::print(stderr,
+                       "Failed to push response for Get PLDM TYPES in base "
+                       "discovery with status: {} for device: {}\n",
+                       static_cast<int>(status), this->deviceName);
+    }
+    return status;
 }
 
 OperationStatus BaseDiscoveryStateMachine::processGetPldmVersionRequest()
 {
-    // TODO(@harshtya): Implement processGetPldmVersionRequest
-    return OperationStatus::Success;
+    std::vector<uint8_t> requestMsg(
+        sizeof(pldm_msg_hdr) +
+        baseCommandRequestSize.at(PLDM_GET_PLDM_VERSION));
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    int rc = encode_get_version_req(this->instanceId, /*transfer_handle=*/0,
+                                    PLDM_GET_FIRSTPART, this->commandPldmType,
+                                    request);
+    if (rc)
+    {
+        stdplus::print(
+            stderr,
+            "Encoding PLDM Version request failed in base discovery with rc: "
+            "{} for device {} and pldmType: {}\n",
+            rc, this->deviceName, std::to_string(this->commandPldmType));
+        return OperationStatus::EncodingRequestFailure;
+    }
+
+    if (pldmSendAtNetwork(this->eid, this->netId, this->fd, requestMsg.data(),
+                          requestMsg.size()))
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmSendFailure;
+    }
+
+    std::vector<uint8_t> response(
+        sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_RESP_BYTES, 0);
+    uint8_t* responseMsg = response.data();
+    size_t responseMsgSize = response.size();
+    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
+
+    if (pldmRecvAtNetwork(this->eid, this->netId, this->fd, this->instanceId,
+                          &responseMsg, &responseMsgSize))
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmRecvFailure;
+    }
+    stdplus::print(stderr,
+                   "Pushing response for GET_PLDM_VERSION for device: "
+                   "{} with pldmType: {}\n",
+                   this->deviceName, std::to_string(this->commandPldmType));
+    OperationStatus status = pushCommandResponse(responsePtr, responseMsgSize);
+    if (status != OperationStatus::Success)
+    {
+        stdplus::print(stderr,
+                       "Failed to push response for Get PLDM Version in base "
+                       "discovery with status: {} for device: {} for pldm Type:"
+                       " {}\n",
+                       static_cast<int>(status), this->deviceName,
+                       std::to_string(this->commandPldmType));
+    }
+    return status;
 }
 
 OperationStatus BaseDiscoveryStateMachine::processGetPldmCommandsRequest()
 {
-    // TODO(@harshtya): Implement processGetPldmCommandsRequest
-    return OperationStatus::Success;
+    std::vector<uint8_t> requestMsg(
+        sizeof(pldm_msg_hdr) +
+        baseCommandRequestSize.at(PLDM_GET_PLDM_COMMANDS));
+    auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+    int rc = encode_get_commands_req(this->instanceId, this->commandPldmType,
+                                     this->pldmVersions[this->commandPldmType],
+                                     request);
+    if (rc)
+    {
+        stdplus::print(
+            stderr,
+            "Encoding PLDM Commands request failed in base discovery with rc: "
+            "{} for device {} and pldmType: {}\n",
+            rc, this->deviceName, std::to_string(this->commandPldmType));
+        return OperationStatus::EncodingRequestFailure;
+    }
+
+    if (pldmSendAtNetwork(this->eid, this->netId, this->fd, requestMsg.data(),
+                          requestMsg.size()))
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmSendFailure;
+    }
+    std::vector<uint8_t> response(
+        sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_RESP_BYTES, 0);
+    uint8_t* responseMsg = response.data();
+    size_t responseMsgSize = response.size();
+    auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
+
+    if (pldmRecvAtNetwork(this->eid, this->netId, this->fd, this->instanceId,
+                          &responseMsg, &responseMsgSize))
+    {
+        this->requesterStatus = StateMachineStatus::RequestFailed;
+        return OperationStatus::PldmRecvFailure;
+    }
+
+    stdplus::print(stderr,
+                   "Pushing response for GET_PLDM_COMMANDS for device: "
+                   "{} with pldmType: {}\n",
+                   this->deviceName, std::to_string(this->commandPldmType));
+    OperationStatus status = pushCommandResponse(responsePtr, responseMsgSize);
+    if (status != OperationStatus::Success)
+    {
+        stdplus::print(stderr,
+                       "Failed to push response for Get PLDM Command in base "
+                       "discovery with status: {} for device: {} for pldm Type:"
+                       " {}\n",
+                       static_cast<int>(status), this->deviceName,
+                       std::to_string(this->commandPldmType));
+    }
+    return status;
 }
 
 OperationStatus BaseDiscoveryStateMachine::pushCommandResponse(