| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 1 | /** | 
 | 2 |  * Copyright © 2019 IBM Corporation | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 | #include "pldm_interface.hpp" | 
 | 17 |  | 
 | 18 | #include <libpldm/base.h> | 
| Andrew Jeffery | 7cc55b5 | 2024-06-19 20:45:13 +0930 | [diff] [blame] | 19 | #include <libpldm/oem/ibm/file_io.h> | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 20 | #include <libpldm/transport.h> | 
 | 21 | #include <libpldm/transport/mctp-demux.h> | 
 | 22 | #include <poll.h> | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 23 | #include <unistd.h> | 
 | 24 |  | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 25 | #include <phosphor-logging/lg2.hpp> | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 26 |  | 
| Patrick Williams | 2544b41 | 2022-10-04 08:41:06 -0500 | [diff] [blame] | 27 | #include <fstream> | 
 | 28 |  | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 29 | namespace openpower::pels | 
 | 30 | { | 
 | 31 |  | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 32 | using namespace sdeventplus; | 
 | 33 | using namespace sdeventplus::source; | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 34 | using TerminusID = uint8_t; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 35 |  | 
 | 36 | constexpr auto eidPath = "/usr/share/pldm/host_eid"; | 
 | 37 | constexpr mctp_eid_t defaultEIDValue = 9; | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 38 | constexpr TerminusID tid = defaultEIDValue; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 39 |  | 
 | 40 | constexpr uint16_t pelFileType = 0; | 
 | 41 |  | 
 | 42 | PLDMInterface::~PLDMInterface() | 
 | 43 | { | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 44 |     freeIID(); | 
 | 45 |     pldm_instance_db_destroy(_pldm_idb); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 46 |     closeFD(); | 
 | 47 | } | 
 | 48 |  | 
 | 49 | void PLDMInterface::closeFD() | 
 | 50 | { | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 51 |     pldm_transport_mctp_demux_destroy(mctpDemux); | 
 | 52 |     mctpDemux = nullptr; | 
 | 53 |     _fd = -1; | 
 | 54 |     pldmTransport = nullptr; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 55 | } | 
 | 56 |  | 
 | 57 | void PLDMInterface::readEID() | 
 | 58 | { | 
 | 59 |     _eid = defaultEIDValue; | 
 | 60 |  | 
 | 61 |     std::ifstream eidFile{eidPath}; | 
 | 62 |     if (!eidFile.good()) | 
 | 63 |     { | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 64 |         lg2::error("Could not open host EID file"); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 65 |     } | 
 | 66 |     else | 
 | 67 |     { | 
 | 68 |         std::string eid; | 
 | 69 |         eidFile >> eid; | 
 | 70 |         if (!eid.empty()) | 
 | 71 |         { | 
 | 72 |             _eid = atoi(eid.c_str()); | 
 | 73 |         } | 
 | 74 |         else | 
 | 75 |         { | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 76 |             lg2::error("EID file was empty"); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 77 |         } | 
 | 78 |     } | 
 | 79 | } | 
 | 80 |  | 
 | 81 | void PLDMInterface::open() | 
 | 82 | { | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 83 |     if (pldmTransport) | 
 | 84 |     { | 
 | 85 |         lg2::error("open: pldmTransport already setup!"); | 
 | 86 |         throw std::runtime_error{"open failed"}; | 
 | 87 |     } | 
 | 88 |  | 
 | 89 |     _fd = openMctpDemuxTransport(); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 90 |     if (_fd < 0) | 
 | 91 |     { | 
 | 92 |         auto e = errno; | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 93 |         lg2::error("Transport open failed. errno = {ERRNO}, rc = {RC}", "ERRNO", | 
 | 94 |                    e, "RC", _fd); | 
 | 95 |         throw std::runtime_error{"Transport open failed"}; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 96 |     } | 
 | 97 | } | 
 | 98 |  | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 99 | int PLDMInterface::openMctpDemuxTransport() | 
 | 100 | { | 
 | 101 |     int rc = pldm_transport_mctp_demux_init(&mctpDemux); | 
 | 102 |     if (rc) | 
 | 103 |     { | 
 | 104 |         lg2::error( | 
 | 105 |             "openMctpDemuxTransport: Failed to init MCTP demux transport. rc = {RC}", | 
 | 106 |             "RC", rc); | 
 | 107 |         return rc; | 
 | 108 |     } | 
 | 109 |  | 
 | 110 |     rc = pldm_transport_mctp_demux_map_tid(mctpDemux, tid, tid); | 
 | 111 |     if (rc) | 
 | 112 |     { | 
 | 113 |         lg2::error( | 
 | 114 |             "openMctpDemuxTransport: Failed to setup tid to eid mapping. rc = {RC}", | 
 | 115 |             "RC", rc); | 
 | 116 |         cleanupCmd(); | 
 | 117 |         return rc; | 
 | 118 |     } | 
 | 119 |     pldmTransport = pldm_transport_mctp_demux_core(mctpDemux); | 
 | 120 |  | 
 | 121 |     struct pollfd pollfd; | 
 | 122 |     rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd); | 
 | 123 |     if (rc) | 
 | 124 |     { | 
 | 125 |         lg2::error("openMctpDemuxTransport: Failed to get pollfd. rc = {RC}", | 
 | 126 |                    "RC", rc); | 
 | 127 |         cleanupCmd(); | 
 | 128 |         return rc; | 
 | 129 |     } | 
 | 130 |     return pollfd.fd; | 
 | 131 | } | 
 | 132 |  | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 133 | void PLDMInterface::startCommand() | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 134 | { | 
 | 135 |     try | 
 | 136 |     { | 
 | 137 |         closeFD(); | 
 | 138 |  | 
 | 139 |         open(); | 
 | 140 |  | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 141 |         registerReceiveCallback(); | 
 | 142 |  | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 143 |         doSend(); | 
 | 144 |  | 
 | 145 |         _receiveTimer.restartOnce(_receiveTimeout); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 146 |     } | 
 | 147 |     catch (const std::exception& e) | 
 | 148 |     { | 
| Matt Spinler | 527ff34 | 2023-06-29 12:52:34 -0500 | [diff] [blame] | 149 |         lg2::error("startCommand exception: {ERROR}", "ERROR", e); | 
 | 150 |  | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 151 |         cleanupCmd(); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 152 |  | 
| Matt Spinler | 527ff34 | 2023-06-29 12:52:34 -0500 | [diff] [blame] | 153 |         throw; | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 154 |     } | 
 | 155 | } | 
 | 156 |  | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 157 | void PLDMInterface::allocIID() | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 158 | { | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 159 |     if (_instanceID) | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 160 |     { | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 161 |         return; | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 162 |     } | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 163 |  | 
 | 164 |     pldm_instance_id_t iid = 0; | 
 | 165 |     auto rc = pldm_instance_id_alloc(_pldm_idb, _eid, &iid); | 
 | 166 |  | 
 | 167 |     if (rc == -EAGAIN) | 
 | 168 |     { | 
 | 169 |         throw std::runtime_error("No free instance ids"); | 
 | 170 |     } | 
 | 171 |     else if (rc) | 
 | 172 |     { | 
 | 173 |         throw std::system_category().default_error_condition(rc); | 
 | 174 |     } | 
 | 175 |  | 
 | 176 |     _instanceID = iid; | 
 | 177 | } | 
 | 178 |  | 
 | 179 | void PLDMInterface::freeIID() | 
 | 180 | { | 
 | 181 |     if (!_instanceID) | 
 | 182 |     { | 
 | 183 |         return; | 
 | 184 |     } | 
 | 185 |  | 
 | 186 |     auto rc = pldm_instance_id_free(_pldm_idb, _eid, *_instanceID); | 
 | 187 |  | 
 | 188 |     if (rc == -EINVAL) | 
 | 189 |     { | 
| Patrick Williams | 075c792 | 2024-08-16 15:19:49 -0400 | [diff] [blame] | 190 |         throw std::runtime_error( | 
 | 191 |             "Instance ID " + std::to_string(*_instanceID) + " for TID " + | 
 | 192 |             std::to_string(_eid) + " was not previously allocated"); | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 193 |     } | 
 | 194 |     else if (rc) | 
 | 195 |     { | 
 | 196 |         throw std::system_category().default_error_condition(rc); | 
 | 197 |     } | 
 | 198 |  | 
 | 199 |     _instanceID = std::nullopt; | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 200 | } | 
 | 201 |  | 
 | 202 | CmdStatus PLDMInterface::sendNewLogCmd(uint32_t id, uint32_t size) | 
 | 203 | { | 
 | 204 |     _pelID = id; | 
 | 205 |     _pelSize = size; | 
 | 206 |     _inProgress = true; | 
 | 207 |  | 
 | 208 |     try | 
 | 209 |     { | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 210 |         // Allocate the instance ID, as needed. | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 211 |         if (!_instanceID) | 
 | 212 |         { | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 213 |             allocIID(); | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 214 |         } | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 215 |         startCommand(); | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 216 |     } | 
 | 217 |     catch (const std::exception& e) | 
 | 218 |     { | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 219 |         _inProgress = false; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 220 |         return CmdStatus::failure; | 
 | 221 |     } | 
 | 222 |  | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 223 |     return CmdStatus::success; | 
 | 224 | } | 
 | 225 |  | 
 | 226 | void PLDMInterface::registerReceiveCallback() | 
 | 227 | { | 
 | 228 |     _source = std::make_unique<IO>( | 
 | 229 |         _event, _fd, EPOLLIN, | 
 | 230 |         std::bind(std::mem_fn(&PLDMInterface::receive), this, | 
 | 231 |                   std::placeholders::_1, std::placeholders::_2, | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 232 |                   std::placeholders::_3, pldmTransport)); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 233 | } | 
 | 234 |  | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 235 | void PLDMInterface::doSend() | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 236 | { | 
 | 237 |     std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(pelFileType) + | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 238 |                             sizeof(_pelID) + sizeof(uint64_t)> | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 239 |         requestMsg; | 
 | 240 |  | 
 | 241 |     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); | 
 | 242 |  | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 243 |     auto rc = encode_new_file_req(*_instanceID, pelFileType, _pelID, _pelSize, | 
 | 244 |                                   request); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 245 |     if (rc != PLDM_SUCCESS) | 
 | 246 |     { | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 247 |         lg2::error("encode_new_file_req failed, rc = {RC}", "RC", rc); | 
| Matt Spinler | 527ff34 | 2023-06-29 12:52:34 -0500 | [diff] [blame] | 248 |         throw std::runtime_error{"encode_new_file_req failed"}; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 249 |     } | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 250 |     pldm_tid_t pldmTID = static_cast<pldm_tid_t>(_eid); | 
 | 251 |     rc = pldm_transport_send_msg(pldmTransport, pldmTID, requestMsg.data(), | 
 | 252 |                                  requestMsg.size()); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 253 |     if (rc < 0) | 
 | 254 |     { | 
 | 255 |         auto e = errno; | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 256 |         lg2::error("pldm_transport_send_msg failed, rc = {RC}, errno = {ERRNO}", | 
 | 257 |                    "RC", rc, "ERRNO", e); | 
 | 258 |         throw std::runtime_error{"pldm_transport_send_msg failed"}; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 259 |     } | 
| Matt Spinler | 9fdcad5 | 2025-02-07 10:12:43 -0600 | [diff] [blame] | 260 |  | 
 | 261 |     memcpy(&_requestHeader, request, sizeof(pldm_msg_hdr)); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 262 | } | 
 | 263 |  | 
| Matt Spinler | f045e83 | 2025-03-13 11:07:10 -0500 | [diff] [blame] | 264 | struct Response | 
 | 265 | { | 
 | 266 |     Response(void* r) : response(r) {} | 
 | 267 |     ~Response() | 
 | 268 |     { | 
 | 269 |         if (response != nullptr) | 
 | 270 |         { | 
 | 271 |             free(response); | 
 | 272 |         } | 
 | 273 |     } | 
 | 274 |     void* response = nullptr; | 
 | 275 | }; | 
 | 276 |  | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 277 | void PLDMInterface::receive(IO& /*io*/, int /*fd*/, uint32_t revents, | 
 | 278 |                             pldm_transport* transport) | 
 | 279 |  | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 280 | { | 
 | 281 |     if (!(revents & EPOLLIN)) | 
 | 282 |     { | 
 | 283 |         return; | 
 | 284 |     } | 
 | 285 |  | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 286 |     void* responseMsg = nullptr; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 287 |     size_t responseSize = 0; | 
 | 288 |     ResponseStatus status = ResponseStatus::success; | 
 | 289 |  | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 290 |     pldm_tid_t pldmTID; | 
 | 291 |     auto rc = pldm_transport_recv_msg(transport, &pldmTID, &responseMsg, | 
 | 292 |                                       &responseSize); | 
| Eddie James | ec6f141 | 2024-10-17 10:55:55 -0500 | [diff] [blame] | 293 |     struct pldm_msg_hdr* hdr = (struct pldm_msg_hdr*)responseMsg; | 
| Matt Spinler | f045e83 | 2025-03-13 11:07:10 -0500 | [diff] [blame] | 294 |     Response r{responseMsg}; | 
 | 295 |  | 
 | 296 |     if (rc == PLDM_REQUESTER_SUCCESS) | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 297 |     { | 
| Matt Spinler | f045e83 | 2025-03-13 11:07:10 -0500 | [diff] [blame] | 298 |         if ((pldmTID != _eid) || | 
 | 299 |             !pldm_msg_hdr_correlate_response(&_requestHeader, hdr)) | 
 | 300 |         { | 
 | 301 |             // We got a response to someone else's message. Ignore it. | 
 | 302 |             return; | 
 | 303 |         } | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 304 |     } | 
| Matt Spinler | f045e83 | 2025-03-13 11:07:10 -0500 | [diff] [blame] | 305 |     else | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 306 |     { | 
 | 307 |         if (rc == PLDM_REQUESTER_NOT_RESP_MSG) | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 308 |         { | 
 | 309 |             // Due to the MCTP loopback, we may get notified of the message | 
 | 310 |             // we just sent. | 
 | 311 |             return; | 
 | 312 |         } | 
 | 313 |  | 
 | 314 |         auto e = errno; | 
| Lakshmi Yadlapati | 0387a74 | 2024-07-01 17:04:37 -0500 | [diff] [blame] | 315 |         lg2::error("pldm_transport_recv_msg failed, rc = {RC}, errno = {ERRNO}", | 
 | 316 |                    "RC", | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 317 |                    static_cast<std::underlying_type_t<pldm_requester_rc_t>>(rc), | 
 | 318 |                    "ERRNO", e); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 319 |         status = ResponseStatus::failure; | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 320 |     } | 
| Eddie James | ec6f141 | 2024-10-17 10:55:55 -0500 | [diff] [blame] | 321 |     if (hdr && (hdr->request || hdr->datagram)) | 
 | 322 |     { | 
| Eddie James | ec6f141 | 2024-10-17 10:55:55 -0500 | [diff] [blame] | 323 |         return; | 
 | 324 |     } | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 325 |  | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 326 |     cleanupCmd(); | 
 | 327 |  | 
 | 328 |     // Can't use this instance ID anymore. | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 329 |     freeIID(); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 330 |  | 
 | 331 |     if (status == ResponseStatus::success) | 
 | 332 |     { | 
 | 333 |         uint8_t completionCode = 0; | 
 | 334 |         auto response = reinterpret_cast<pldm_msg*>(responseMsg); | 
 | 335 |  | 
| Patrick Williams | 075c792 | 2024-08-16 15:19:49 -0400 | [diff] [blame] | 336 |         auto decodeRC = | 
 | 337 |             decode_new_file_resp(response, responseSize, &completionCode); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 338 |         if (decodeRC < 0) | 
 | 339 |         { | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 340 |             lg2::error("decode_new_file_resp failed, rc = {RC}", "RC", | 
 | 341 |                        decodeRC); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 342 |             status = ResponseStatus::failure; | 
 | 343 |         } | 
 | 344 |         else | 
 | 345 |         { | 
 | 346 |             if (completionCode != PLDM_SUCCESS) | 
 | 347 |             { | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 348 |                 lg2::error("Bad PLDM completion code {CODE}", "CODE", | 
 | 349 |                            completionCode); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 350 |                 status = ResponseStatus::failure; | 
 | 351 |             } | 
 | 352 |         } | 
 | 353 |     } | 
 | 354 |  | 
| Matt Spinler | a44efe4 | 2020-03-03 10:30:16 -0600 | [diff] [blame] | 355 |     callResponseFunc(status); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 356 | } | 
 | 357 |  | 
 | 358 | void PLDMInterface::receiveTimerExpired() | 
 | 359 | { | 
| Matt Spinler | 1b41886 | 2023-06-29 12:37:41 -0500 | [diff] [blame] | 360 |     lg2::error("Timed out waiting for PLDM response"); | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 361 |  | 
 | 362 |     // Cleanup, but keep the instance ID because the host didn't | 
 | 363 |     // respond so we can still use it. | 
 | 364 |     cleanupCmd(); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 365 |  | 
| Matt Spinler | a44efe4 | 2020-03-03 10:30:16 -0600 | [diff] [blame] | 366 |     callResponseFunc(ResponseStatus::failure); | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 367 | } | 
 | 368 |  | 
 | 369 | void PLDMInterface::cancelCmd() | 
 | 370 | { | 
| Patrick Williams | 49bcbe9 | 2024-06-26 23:06:54 -0500 | [diff] [blame] | 371 |     freeIID(); | 
| Matt Spinler | 2843ba2 | 2020-03-03 16:36:32 -0600 | [diff] [blame] | 372 |     cleanupCmd(); | 
 | 373 | } | 
 | 374 |  | 
 | 375 | void PLDMInterface::cleanupCmd() | 
 | 376 | { | 
| Matt Spinler | 5c350fd | 2019-12-12 13:53:53 -0600 | [diff] [blame] | 377 |     _inProgress = false; | 
 | 378 |     _source.reset(); | 
 | 379 |  | 
 | 380 |     if (_receiveTimer.isEnabled()) | 
 | 381 |     { | 
 | 382 |         _receiveTimer.setEnabled(false); | 
 | 383 |     } | 
 | 384 |  | 
 | 385 |     closeFD(); | 
 | 386 | } | 
 | 387 |  | 
 | 388 | } // namespace openpower::pels |