blob: be70740b11c26475a568a7a7f117b33835d578ff [file] [log] [blame]
Gilbert Chen6c7fed42022-02-22 15:40:17 +00001#include "terminus_manager.hpp"
2
3#include "manager.hpp"
4
5#include <phosphor-logging/lg2.hpp>
6
7PHOSPHOR_LOG2_USING;
8
9namespace pldm
10{
11namespace platform_mc
12{
13
14std::optional<MctpInfo> TerminusManager::toMctpInfo(const pldm_tid_t& tid)
15{
16 if (tid == PLDM_TID_UNASSIGNED || tid == PLDM_TID_RESERVED)
17 {
18 return std::nullopt;
19 }
20
21 if ((!this->transportLayerTable.contains(tid)) ||
22 (this->transportLayerTable[tid] != SupportedTransportLayer::MCTP))
23 {
24 return std::nullopt;
25 }
26
27 auto mctpInfoIt = mctpInfoTable.find(tid);
28 if (mctpInfoIt == mctpInfoTable.end())
29 {
30 return std::nullopt;
31 }
32
33 return mctpInfoIt->second;
34}
35
36std::optional<pldm_tid_t> TerminusManager::toTid(const MctpInfo& mctpInfo) const
37{
38 if (!pldm::utils::isValidEID(std::get<0>(mctpInfo)))
39 {
40 return std::nullopt;
41 }
42
43 auto mctpInfoTableIt = std::find_if(
44 mctpInfoTable.begin(), mctpInfoTable.end(), [&mctpInfo](auto& v) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040045 return (std::get<0>(v.second) == std::get<0>(mctpInfo)) &&
46 (std::get<3>(v.second) == std::get<3>(mctpInfo));
47 });
Gilbert Chen6c7fed42022-02-22 15:40:17 +000048 if (mctpInfoTableIt == mctpInfoTable.end())
49 {
50 return std::nullopt;
51 }
52 return mctpInfoTableIt->first;
53}
54
Patrick Williams366507c2025-02-03 14:28:01 -050055std::optional<pldm_tid_t> TerminusManager::storeTerminusInfo(
56 const MctpInfo& mctpInfo, pldm_tid_t tid)
Gilbert Chen6c7fed42022-02-22 15:40:17 +000057{
58 if (tid == PLDM_TID_UNASSIGNED || tid == PLDM_TID_RESERVED)
59 {
60 return std::nullopt;
61 }
62
63 if (!pldm::utils::isValidEID(std::get<0>(mctpInfo)))
64 {
65 return std::nullopt;
66 }
67
68 if (tidPool[tid])
69 {
70 return std::nullopt;
71 }
72
73 tidPool[tid] = true;
74 transportLayerTable[tid] = SupportedTransportLayer::MCTP;
75 mctpInfoTable[tid] = mctpInfo;
76
77 return tid;
78}
79
80std::optional<pldm_tid_t> TerminusManager::mapTid(const MctpInfo& mctpInfo)
81{
82 if (!pldm::utils::isValidEID(std::get<0>(mctpInfo)))
83 {
84 return std::nullopt;
85 }
86
87 auto mctpInfoTableIt = std::find_if(
88 mctpInfoTable.begin(), mctpInfoTable.end(), [&mctpInfo](auto& v) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -040089 return (std::get<0>(v.second) == std::get<0>(mctpInfo)) &&
90 (std::get<3>(v.second) == std::get<3>(mctpInfo));
91 });
Gilbert Chen6c7fed42022-02-22 15:40:17 +000092 if (mctpInfoTableIt != mctpInfoTable.end())
93 {
94 return mctpInfoTableIt->first;
95 }
96
97 auto tidPoolIt = std::find(tidPool.begin(), tidPool.end(), false);
98 if (tidPoolIt == tidPool.end())
99 {
100 return std::nullopt;
101 }
102
103 pldm_tid_t tid = std::distance(tidPool.begin(), tidPoolIt);
104 return storeTerminusInfo(mctpInfo, tid);
105}
106
107bool TerminusManager::unmapTid(const pldm_tid_t& tid)
108{
109 if (tid == PLDM_TID_UNASSIGNED || tid == PLDM_TID_RESERVED)
110 {
111 return false;
112 }
113 tidPool[tid] = false;
114
115 if (transportLayerTable.contains(tid))
116 {
117 transportLayerTable.erase(tid);
118 }
119
120 if (mctpInfoTable.contains(tid))
121 {
122 mctpInfoTable.erase(tid);
123 }
124
125 return true;
126}
127
Chau Ly75e00422024-03-19 12:33:08 +0000128void TerminusManager::updateMctpEndpointAvailability(const MctpInfo& mctpInfo,
129 Availability availability)
130{
131 mctpInfoAvailTable.insert_or_assign(mctpInfo, availability);
132
133 if (manager)
134 {
135 auto tid = toTid(mctpInfo);
136 if (tid)
137 {
138 manager->updateAvailableState(tid.value(), availability);
139 }
140 }
141}
142
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000143void TerminusManager::discoverMctpTerminus(const MctpInfos& mctpInfos)
144{
145 queuedMctpInfos.emplace(mctpInfos);
146 if (discoverMctpTerminusTaskHandle.has_value())
147 {
148 auto& [scope, rcOpt] = *discoverMctpTerminusTaskHandle;
149 if (!rcOpt.has_value())
150 {
151 return;
152 }
153 stdexec::sync_wait(scope.on_empty());
154 discoverMctpTerminusTaskHandle.reset();
155 }
156 auto& [scope, rcOpt] = discoverMctpTerminusTaskHandle.emplace();
157 scope.spawn(discoverMctpTerminusTask() |
158 stdexec::then([&](int rc) { rcOpt.emplace(rc); }),
Patrick Williams61be7342024-07-30 16:55:33 -0500159 exec::default_task_context<void>(exec::inline_scheduler{}));
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000160}
161
Patrick Williams366507c2025-02-03 14:28:01 -0500162TerminiMapper::iterator TerminusManager::findTerminusPtr(
163 const MctpInfo& mctpInfo)
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000164{
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400165 auto foundIter = std::find_if(
166 termini.begin(), termini.end(), [&](const auto& terminusPair) {
167 auto terminusMctpInfo = toMctpInfo(terminusPair.first);
168 return (terminusMctpInfo &&
169 (std::get<0>(terminusMctpInfo.value()) ==
170 std::get<0>(mctpInfo)) &&
171 (std::get<3>(terminusMctpInfo.value()) ==
172 std::get<3>(mctpInfo)));
173 });
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000174
175 return foundIter;
176}
177
178exec::task<int> TerminusManager::discoverMctpTerminusTask()
179{
Gilbert Cheneac61a42022-02-23 20:56:19 +0000180 std::vector<pldm_tid_t> addedTids;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000181 while (!queuedMctpInfos.empty())
182 {
183 if (manager)
184 {
185 co_await manager->beforeDiscoverTerminus();
186 }
187
188 const MctpInfos& mctpInfos = queuedMctpInfos.front();
189 for (const auto& mctpInfo : mctpInfos)
190 {
Patrick Williams29d2f4a2024-07-13 16:44:15 -0500191 auto it = findTerminusPtr(mctpInfo);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000192 if (it == termini.end())
193 {
Chau Ly75e00422024-03-19 12:33:08 +0000194 mctpInfoAvailTable[mctpInfo] = true;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000195 co_await initMctpTerminus(mctpInfo);
196 }
Gilbert Cheneac61a42022-02-23 20:56:19 +0000197
198 /* Get TID of initialized terminus */
199 auto tid = toTid(mctpInfo);
200 if (!tid)
201 {
Chau Ly75e00422024-03-19 12:33:08 +0000202 mctpInfoAvailTable.erase(mctpInfo);
Gilbert Cheneac61a42022-02-23 20:56:19 +0000203 co_return PLDM_ERROR;
204 }
205 addedTids.push_back(tid.value());
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000206 }
207
208 if (manager)
209 {
210 co_await manager->afterDiscoverTerminus();
Gilbert Cheneac61a42022-02-23 20:56:19 +0000211 for (const auto& tid : addedTids)
212 {
213 manager->startSensorPolling(tid);
214 }
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000215 }
216
217 queuedMctpInfos.pop();
218 }
219
220 co_return PLDM_SUCCESS;
221}
222
223void TerminusManager::removeMctpTerminus(const MctpInfos& mctpInfos)
224{
225 // remove terminus
226 for (const auto& mctpInfo : mctpInfos)
227 {
Patrick Williams29d2f4a2024-07-13 16:44:15 -0500228 auto it = findTerminusPtr(mctpInfo);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000229 if (it == termini.end())
230 {
231 continue;
232 }
233
Gilbert Cheneac61a42022-02-23 20:56:19 +0000234 if (manager)
235 {
236 manager->stopSensorPolling(it->second->getTid());
237 }
238
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000239 unmapTid(it->first);
240 termini.erase(it);
Chau Ly75e00422024-03-19 12:33:08 +0000241 mctpInfoAvailTable.erase(mctpInfo);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000242 }
243}
244
245exec::task<int> TerminusManager::initMctpTerminus(const MctpInfo& mctpInfo)
246{
247 mctp_eid_t eid = std::get<0>(mctpInfo);
248 pldm_tid_t tid = 0;
249 bool isMapped = false;
250 auto rc = co_await getTidOverMctp(eid, &tid);
251 if (rc != PLDM_SUCCESS)
252 {
253 lg2::error("Failed to Get Terminus ID, error {ERROR}.", "ERROR", rc);
254 co_return PLDM_ERROR;
255 }
256
257 if (tid == PLDM_TID_RESERVED)
258 {
259 lg2::error("Terminus responses the reserved {TID}.", "TID", tid);
260 co_return PLDM_ERROR;
261 }
262
263 /* Terminus already has TID */
264 if (tid != PLDM_TID_UNASSIGNED)
265 {
266 /* TID is used by one discovered terminus */
267 auto it = termini.find(tid);
268 if (it != termini.end())
269 {
270 auto terminusMctpInfo = toMctpInfo(it->first);
271 /* The discovered terminus has the same MCTP Info */
272 if (terminusMctpInfo &&
273 (std::get<0>(terminusMctpInfo.value()) ==
274 std::get<0>(mctpInfo)) &&
275 (std::get<3>(terminusMctpInfo.value()) ==
276 std::get<3>(mctpInfo)))
277 {
278 co_return PLDM_SUCCESS;
279 }
280 else
281 {
282 /* ToDo:
283 * Maybe the terminus supports multiple medium interfaces
284 * Or the TID is used by other terminus.
285 * Check the UUID to confirm.
286 */
287 isMapped = false;
288 }
289 }
290 /* Use the terminus TID for mapping */
291 else
292 {
293 auto mappedTid = storeTerminusInfo(mctpInfo, tid);
294 if (!mappedTid)
295 {
296 lg2::error("Failed to store Terminus Info for terminus {TID}.",
297 "TID", tid);
298 co_return PLDM_ERROR;
299 }
300 isMapped = true;
301 }
302 }
303
304 if (!isMapped)
305 {
306 // Assigning a tid. If it has been mapped, mapTid()
307 // returns the tid assigned before.
308 auto mappedTid = mapTid(mctpInfo);
309 if (!mappedTid)
310 {
311 lg2::error("Failed to store Terminus Info for terminus {TID}.",
312 "TID", tid);
313 co_return PLDM_ERROR;
314 }
315
316 tid = mappedTid.value();
317 rc = co_await setTidOverMctp(eid, tid);
318 if (rc != PLDM_SUCCESS)
319 {
320 lg2::error("Failed to Set terminus TID, error{ERROR}.", "ERROR",
321 rc);
322 unmapTid(tid);
323 co_return rc;
324 }
325
326 if (rc != PLDM_SUCCESS && rc != PLDM_ERROR_UNSUPPORTED_PLDM_CMD)
327 {
328 lg2::error("Terminus {TID} does not support SetTID command.", "TID",
329 tid);
330 unmapTid(tid);
331 co_return rc;
332 }
333
334 if (termini.contains(tid))
335 {
336 // the terminus has been discovered before
337 co_return PLDM_SUCCESS;
338 }
339 }
340 /* Discovery the mapped terminus */
341 uint64_t supportedTypes = 0;
342 rc = co_await getPLDMTypes(tid, supportedTypes);
343 if (rc)
344 {
345 lg2::error("Failed to Get PLDM Types for terminus {TID}, error {ERROR}",
346 "TID", tid, "ERROR", rc);
Eric Yang1be20722024-10-28 21:34:39 +0800347 unmapTid(tid);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000348 co_return PLDM_ERROR;
349 }
350
351 try
352 {
353 termini[tid] = std::make_shared<Terminus>(tid, supportedTypes);
354 }
355 catch (const sdbusplus::exception_t& e)
356 {
357 lg2::error("Failed to create terminus manager for terminus {TID}",
358 "TID", tid);
Eric Yang1be20722024-10-28 21:34:39 +0800359 unmapTid(tid);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000360 co_return PLDM_ERROR;
361 }
362
363 uint8_t type = PLDM_BASE;
364 auto size = PLDM_MAX_TYPES * (PLDM_MAX_CMDS_PER_TYPE / 8);
365 std::vector<uint8_t> pldmCmds(size);
366 while ((type < PLDM_MAX_TYPES))
367 {
368 if (!termini[tid]->doesSupportType(type))
369 {
370 type++;
371 continue;
372 }
Thu Nguyen6e615622024-06-22 02:10:34 +0000373
374 ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
375 auto rc = co_await getPLDMVersion(tid, type, &version);
376 if (rc)
377 {
378 lg2::error(
379 "Failed to Get PLDM Version for terminus {TID}, PLDM Type {TYPE}, error {ERROR}",
380 "TID", tid, "TYPE", type, "ERROR", rc);
381 }
382 termini[tid]->setSupportedTypeVersions(type, version);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000383 std::vector<bitfield8_t> cmds(PLDM_MAX_CMDS_PER_TYPE / 8);
Thu Nguyen6e615622024-06-22 02:10:34 +0000384 rc = co_await getPLDMCommands(tid, type, version, cmds.data());
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000385 if (rc)
386 {
387 lg2::error(
388 "Failed to Get PLDM Commands for terminus {TID}, error {ERROR}",
389 "TID", tid, "ERROR", rc);
390 }
391
392 for (size_t i = 0; i < cmds.size(); i++)
393 {
394 auto idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + i;
395 if (idx >= pldmCmds.size())
396 {
397 lg2::error(
398 "Calculated index {IDX} out of bounds for pldmCmds, type {TYPE}, command index {CMD_IDX}",
399 "IDX", idx, "TYPE", type, "CMD_IDX", i);
400 continue;
401 }
402 pldmCmds[idx] = cmds[i].byte;
403 }
404 type++;
405 }
406 termini[tid]->setSupportedCommands(pldmCmds);
407
408 co_return PLDM_SUCCESS;
409}
410
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400411exec::task<int> TerminusManager::sendRecvPldmMsgOverMctp(
412 mctp_eid_t eid, Request& request, const pldm_msg** responseMsg,
413 size_t* responseLen)
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000414{
Thu Nguyen6b901e42024-07-10 15:21:10 +0700415 int rc = 0;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000416 try
417 {
Thu Nguyen6b901e42024-07-10 15:21:10 +0700418 std::tie(rc, *responseMsg, *responseLen) =
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000419 co_await handler.sendRecvMsg(eid, std::move(request));
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000420 }
421 catch (const sdbusplus::exception_t& e)
422 {
423 lg2::error(
Thu Nguyen6b901e42024-07-10 15:21:10 +0700424 "Send and Receive PLDM message over MCTP throw error - {ERROR}.",
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000425 "ERROR", e);
426 co_return PLDM_ERROR;
427 }
Thu Nguyen6b901e42024-07-10 15:21:10 +0700428 catch (const int& e)
Jerry C Chen2da113f2024-07-09 16:02:23 +0800429 {
Thu Nguyen6b901e42024-07-10 15:21:10 +0700430 lg2::error(
431 "Send and Receive PLDM message over MCTP throw int error - {ERROR}.",
432 "ERROR", e);
Jerry C Chen2da113f2024-07-09 16:02:23 +0800433 co_return PLDM_ERROR;
434 }
Thu Nguyen6b901e42024-07-10 15:21:10 +0700435
436 co_return rc;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000437}
438
439exec::task<int> TerminusManager::getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid)
440{
441 auto instanceId = instanceIdDb.next(eid);
442 Request request(sizeof(pldm_msg_hdr));
443 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
444 auto rc = encode_get_tid_req(instanceId, requestMsg);
445 if (rc)
446 {
447 instanceIdDb.free(eid, instanceId);
448 lg2::error(
449 "Failed to encode request GetTID for endpoint ID {EID}, error {RC} ",
450 "EID", eid, "RC", rc);
451 co_return rc;
452 }
453
454 const pldm_msg* responseMsg = nullptr;
455 size_t responseLen = 0;
456 rc = co_await sendRecvPldmMsgOverMctp(eid, request, &responseMsg,
457 &responseLen);
458 if (rc)
459 {
460 lg2::error("Failed to send GetTID for Endpoint {EID}, error {RC}",
461 "EID", eid, "RC", rc);
462 co_return rc;
463 }
464
465 uint8_t completionCode = 0;
466 rc = decode_get_tid_resp(responseMsg, responseLen, &completionCode, tid);
467 if (rc)
468 {
469 lg2::error(
470 "Failed to decode response GetTID for Endpoint ID {EID}, error {RC} ",
471 "EID", eid, "RC", rc);
472 co_return rc;
473 }
474
475 if (completionCode != PLDM_SUCCESS)
476 {
477 lg2::error("Error : GetTID for Endpoint ID {EID}, complete code {CC}.",
478 "EID", eid, "CC", completionCode);
479 co_return rc;
480 }
481
482 co_return completionCode;
483}
484
485exec::task<int> TerminusManager::setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid)
486{
487 auto instanceId = instanceIdDb.next(eid);
488 Request request(sizeof(pldm_msg_hdr) + sizeof(pldm_set_tid_req));
489 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
490 auto rc = encode_set_tid_req(instanceId, tid, requestMsg);
491 if (rc)
492 {
493 instanceIdDb.free(eid, instanceId);
494 lg2::error(
495 "Failed to encode request SetTID for endpoint ID {EID}, error {RC} ",
496 "EID", eid, "RC", rc);
497 co_return rc;
498 }
499
500 const pldm_msg* responseMsg = nullptr;
501 size_t responseLen = 0;
502 rc = co_await sendRecvPldmMsgOverMctp(eid, request, &responseMsg,
503 &responseLen);
504 if (rc)
505 {
506 lg2::error("Failed to send SetTID for Endpoint {EID}, error {RC}",
507 "EID", eid, "RC", rc);
508 co_return rc;
509 }
510
Jayanth Othayoth7c14fc42024-12-17 10:24:47 -0600511 if (responseMsg == nullptr || responseLen != PLDM_SET_TID_RESP_BYTES)
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000512 {
513 lg2::error(
514 "Failed to decode response SetTID for Endpoint ID {EID}, error {RC} ",
515 "EID", eid, "RC", rc);
516 co_return PLDM_ERROR_INVALID_LENGTH;
517 }
518
519 co_return responseMsg->payload[0];
520}
521
Patrick Williams366507c2025-02-03 14:28:01 -0500522exec::task<int> TerminusManager::getPLDMTypes(pldm_tid_t tid,
523 uint64_t& supportedTypes)
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000524{
525 Request request(sizeof(pldm_msg_hdr));
526 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
527 auto rc = encode_get_types_req(0, requestMsg);
528 if (rc)
529 {
530 lg2::error(
531 "Failed to encode request getPLDMTypes for terminus ID {TID}, error {RC} ",
532 "TID", tid, "RC", rc);
533 co_return rc;
534 }
535
536 const pldm_msg* responseMsg = nullptr;
537 size_t responseLen = 0;
538
539 rc = co_await sendRecvPldmMsg(tid, request, &responseMsg, &responseLen);
540 if (rc)
541 {
542 lg2::error("Failed to send GetPLDMTypes for terminus {TID}, error {RC}",
543 "TID", tid, "RC", rc);
544 co_return rc;
545 }
546
547 uint8_t completionCode = 0;
548 bitfield8_t* types = reinterpret_cast<bitfield8_t*>(&supportedTypes);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400549 rc =
550 decode_get_types_resp(responseMsg, responseLen, &completionCode, types);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000551 if (rc)
552 {
553 lg2::error(
554 "Failed to decode response GetPLDMTypes for terminus ID {TID}, error {RC} ",
555 "TID", tid, "RC", rc);
556 co_return rc;
557 }
558
559 if (completionCode != PLDM_SUCCESS)
560 {
561 lg2::error(
562 "Error : GetPLDMTypes for terminus ID {TID}, complete code {CC}.",
563 "TID", tid, "CC", completionCode);
564 co_return rc;
565 }
566 co_return completionCode;
567}
568
Thu Nguyen6e615622024-06-22 02:10:34 +0000569exec::task<int> TerminusManager::getPLDMCommands(
570 pldm_tid_t tid, uint8_t type, ver32_t version, bitfield8_t* supportedCmds)
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000571{
572 Request request(sizeof(pldm_msg_hdr) + PLDM_GET_COMMANDS_REQ_BYTES);
573 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000574
575 auto rc = encode_get_commands_req(0, type, version, requestMsg);
576 if (rc)
577 {
578 lg2::error(
579 "Failed to encode request GetPLDMCommands for terminus ID {TID}, error {RC} ",
580 "TID", tid, "RC", rc);
581 co_return rc;
582 }
583
584 const pldm_msg* responseMsg = nullptr;
585 size_t responseLen = 0;
586
587 rc = co_await sendRecvPldmMsg(tid, request, &responseMsg, &responseLen);
588 if (rc)
589 {
590 lg2::error(
591 "Failed to send GetPLDMCommands message for terminus {TID}, error {RC}",
592 "TID", tid, "RC", rc);
593 co_return rc;
594 }
595
596 /* Process response */
597 uint8_t completionCode = 0;
598 rc = decode_get_commands_resp(responseMsg, responseLen, &completionCode,
599 supportedCmds);
600 if (rc)
601 {
602 lg2::error(
603 "Failed to decode response GetPLDMCommands for terminus ID {TID}, error {RC} ",
604 "TID", tid, "RC", rc);
605 co_return rc;
606 }
607
608 if (completionCode != PLDM_SUCCESS)
609 {
610 lg2::error(
611 "Error : GetPLDMCommands for terminus ID {TID}, complete code {CC}.",
612 "TID", tid, "CC", completionCode);
613 co_return rc;
614 }
615
616 co_return completionCode;
617}
618
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400619exec::task<int> TerminusManager::sendRecvPldmMsg(
620 pldm_tid_t tid, Request& request, const pldm_msg** responseMsg,
621 size_t* responseLen)
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000622{
623 /**
624 * Size of tidPool is `std::numeric_limits<pldm_tid_t>::max() + 1`
625 * tidPool[i] always exist
626 */
627 if (!tidPool[tid])
628 {
629 co_return PLDM_ERROR_NOT_READY;
630 }
631
632 if (!transportLayerTable.contains(tid))
633 {
634 co_return PLDM_ERROR_NOT_READY;
635 }
636
637 if (transportLayerTable[tid] != SupportedTransportLayer::MCTP)
638 {
639 co_return PLDM_ERROR_NOT_READY;
640 }
641
642 auto mctpInfo = toMctpInfo(tid);
643 if (!mctpInfo.has_value())
644 {
645 co_return PLDM_ERROR_NOT_READY;
646 }
647
Chau Ly75e00422024-03-19 12:33:08 +0000648 // There's a cost of maintaining another table to hold availability
649 // status as we can't ensure that it always synchronizes with the
650 // mctpInfoTable; std::map operator[] will insert a default of boolean
651 // which is false to the mctpInfoAvailTable if the mctpInfo key doesn't
652 // exist. Once we miss to initialize the availability of an available
653 // endpoint, it will drop all the messages to/from it.
654 if (!mctpInfoAvailTable[mctpInfo.value()])
655 {
656 co_return PLDM_ERROR_NOT_READY;
657 }
658
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000659 auto eid = std::get<0>(mctpInfo.value());
660 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
661 requestMsg->hdr.instance_id = instanceIdDb.next(eid);
662 auto rc = co_await sendRecvPldmMsgOverMctp(eid, request, responseMsg,
663 responseLen);
664
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000665 co_return rc;
666}
667
Thu Nguyen6e615622024-06-22 02:10:34 +0000668exec::task<int> TerminusManager::getPLDMVersion(pldm_tid_t tid, uint8_t type,
669 ver32_t* version)
670{
671 Request request(sizeof(pldm_msg_hdr) + PLDM_GET_VERSION_REQ_BYTES);
672 auto requestMsg = new (request.data()) pldm_msg;
673
674 auto rc =
675 encode_get_version_req(0, 0, PLDM_GET_FIRSTPART, type, requestMsg);
676 if (rc)
677 {
678 lg2::error(
679 "Failed to encode request getPLDMVersion for terminus ID {TID}, error {RC} ",
680 "TID", tid, "RC", rc);
681 co_return rc;
682 }
683
684 const pldm_msg* responseMsg = nullptr;
685 size_t responseLen = 0;
686
687 rc = co_await sendRecvPldmMsg(tid, request, &responseMsg, &responseLen);
688 if (rc)
689 {
690 lg2::error(
691 "Failed to send getPLDMVersion message for terminus {TID}, error {RC}",
692 "TID", tid, "RC", rc);
693 co_return rc;
694 }
695
696 /* Process response */
697 uint8_t completionCode = 0;
698 uint8_t transferFlag = 0;
699 uint32_t transferHandle = 0;
700 rc = decode_get_version_resp(responseMsg, responseLen, &completionCode,
701 &transferHandle, &transferFlag, version);
702 if (rc)
703 {
704 lg2::error(
705 "Failed to decode response getPLDMVersion for terminus ID {TID}, error {RC} ",
706 "TID", tid, "RC", rc);
707 co_return rc;
708 }
709
710 if (completionCode != PLDM_SUCCESS)
711 {
712 lg2::error(
713 "Error : getPLDMVersion for terminus ID {TID}, complete code {CC}.",
714 "TID", tid, "CC", completionCode);
715 co_return completionCode;
716 }
717
718 co_return completionCode;
719}
720
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000721} // namespace platform_mc
722} // namespace pldm