| Gilbert Chen | 6c7fed4 | 2022-02-22 15:40:17 +0000 | [diff] [blame] | 1 | #include "terminus.hpp" | 
|  | 2 |  | 
| Dung Cao | b6d3943 | 2024-06-05 03:46:47 +0000 | [diff] [blame] | 3 | #include "dbus_impl_fru.hpp" | 
| Gilbert Chen | 6c7fed4 | 2022-02-22 15:40:17 +0000 | [diff] [blame] | 4 | #include "terminus_manager.hpp" | 
|  | 5 |  | 
| Manojkiran Eda | fe25279 | 2025-03-13 19:24:19 +0530 | [diff] [blame] | 6 | #include <libpldm/platform.h> | 
|  | 7 |  | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 8 | #include <common/utils.hpp> | 
|  | 9 |  | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 10 | #include <ranges> | 
|  | 11 |  | 
| Gilbert Chen | 6c7fed4 | 2022-02-22 15:40:17 +0000 | [diff] [blame] | 12 | namespace pldm | 
|  | 13 | { | 
|  | 14 | namespace platform_mc | 
|  | 15 | { | 
|  | 16 |  | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 17 | Terminus::Terminus(pldm_tid_t tid, uint64_t supportedTypes, | 
|  | 18 | sdeventplus::Event& event) : | 
| Gilbert Chen | 77e6fe7 | 2024-08-06 09:23:30 +0000 | [diff] [blame] | 19 | initialized(false), maxBufferSize(PLDM_PLATFORM_EVENT_MSG_MAX_BUFFER_SIZE), | 
| Dung Cao | f48015b | 2023-11-21 04:38:29 +0000 | [diff] [blame] | 20 | synchronyConfigurationSupported(0), pollEvent(false), tid(tid), | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 21 | supportedTypes(supportedTypes), event(event) | 
| Gilbert Chen | 6c7fed4 | 2022-02-22 15:40:17 +0000 | [diff] [blame] | 22 | {} | 
|  | 23 |  | 
|  | 24 | bool Terminus::doesSupportType(uint8_t type) | 
|  | 25 | { | 
|  | 26 | return supportedTypes.test(type); | 
|  | 27 | } | 
|  | 28 |  | 
|  | 29 | bool Terminus::doesSupportCommand(uint8_t type, uint8_t command) | 
|  | 30 | { | 
|  | 31 | if (!doesSupportType(type)) | 
|  | 32 | { | 
|  | 33 | return false; | 
|  | 34 | } | 
|  | 35 |  | 
|  | 36 | try | 
|  | 37 | { | 
|  | 38 | const size_t idx = type * (PLDM_MAX_CMDS_PER_TYPE / 8) + (command / 8); | 
|  | 39 | if (idx >= supportedCmds.size()) | 
|  | 40 | { | 
|  | 41 | return false; | 
|  | 42 | } | 
|  | 43 |  | 
|  | 44 | if (supportedCmds[idx] & (1 << (command % 8))) | 
|  | 45 | { | 
|  | 46 | lg2::info( | 
|  | 47 | "PLDM type {TYPE} command {CMD} is supported by terminus {TID}", | 
|  | 48 | "TYPE", type, "CMD", command, "TID", getTid()); | 
|  | 49 | return true; | 
|  | 50 | } | 
|  | 51 | } | 
|  | 52 | catch (const std::exception& e) | 
|  | 53 | { | 
|  | 54 | return false; | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | return false; | 
|  | 58 | } | 
|  | 59 |  | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 60 | std::optional<std::string_view> Terminus::findTerminusName() | 
|  | 61 | { | 
|  | 62 | auto it = std::find_if( | 
|  | 63 | entityAuxiliaryNamesTbl.begin(), entityAuxiliaryNamesTbl.end(), | 
|  | 64 | [](const std::shared_ptr<EntityAuxiliaryNames>& entityAuxiliaryNames) { | 
| Patrick Williams | 16c2a0a | 2024-08-16 15:20:59 -0400 | [diff] [blame] | 65 | const auto& [key, entityNames] = *entityAuxiliaryNames; | 
|  | 66 | /** | 
| Manojkiran Eda | 04ac997 | 2024-09-06 10:57:12 +0530 | [diff] [blame] | 67 | * There is only one Overall system container entity in one | 
|  | 68 | * terminus. The entity auxiliary name PDR of that terminus with the | 
|  | 69 | * that type of containerID will include terminus name. | 
|  | 70 | */ | 
| Patrick Williams | 16c2a0a | 2024-08-16 15:20:59 -0400 | [diff] [blame] | 71 | return ( | 
|  | 72 | entityAuxiliaryNames && | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 73 | key.containerId == PLDM_PLATFORM_ENTITY_SYSTEM_CONTAINER_ID && | 
|  | 74 | entityNames.size()); | 
| Patrick Williams | 16c2a0a | 2024-08-16 15:20:59 -0400 | [diff] [blame] | 75 | }); | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 76 |  | 
|  | 77 | if (it != entityAuxiliaryNamesTbl.end()) | 
|  | 78 | { | 
|  | 79 | const auto& [key, entityNames] = **it; | 
|  | 80 | if (!entityNames.size()) | 
|  | 81 | { | 
|  | 82 | return std::nullopt; | 
|  | 83 | } | 
|  | 84 | return entityNames[0].second; | 
|  | 85 | } | 
|  | 86 |  | 
|  | 87 | return std::nullopt; | 
|  | 88 | } | 
|  | 89 |  | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 90 | bool Terminus::createInventoryPath(std::string tName) | 
|  | 91 | { | 
|  | 92 | if (tName.empty()) | 
|  | 93 | { | 
|  | 94 | return false; | 
|  | 95 | } | 
|  | 96 |  | 
| Dung Cao | b6d3943 | 2024-06-05 03:46:47 +0000 | [diff] [blame] | 97 | /* inventory object is created */ | 
|  | 98 | if (inventoryItemBoardInft) | 
|  | 99 | { | 
|  | 100 | return false; | 
|  | 101 | } | 
|  | 102 |  | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 103 | inventoryPath = "/xyz/openbmc_project/inventory/system/board/" + tName; | 
|  | 104 | try | 
|  | 105 | { | 
| Dung Cao | b6d3943 | 2024-06-05 03:46:47 +0000 | [diff] [blame] | 106 | inventoryItemBoardInft = | 
|  | 107 | std::make_unique<pldm::dbus_api::PldmEntityReq>( | 
|  | 108 | utils::DBusHandler::getBus(), inventoryPath.c_str()); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 109 | return true; | 
|  | 110 | } | 
|  | 111 | catch (const sdbusplus::exception_t& e) | 
|  | 112 | { | 
|  | 113 | lg2::error( | 
|  | 114 | "Failed to create Inventory Board interface for device {PATH}", | 
|  | 115 | "PATH", inventoryPath); | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | return false; | 
|  | 119 | } | 
|  | 120 |  | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 121 | void Terminus::parseTerminusPDRs() | 
|  | 122 | { | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 123 | for (auto& pdr : pdrs) | 
|  | 124 | { | 
| Pavithra Barithaya | 36b3693 | 2025-01-30 10:33:05 +0530 | [diff] [blame] | 125 | auto pdrHdr = new (pdr.data()) pldm_pdr_hdr; | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 126 | switch (pdrHdr->type) | 
|  | 127 | { | 
|  | 128 | case PLDM_SENSOR_AUXILIARY_NAMES_PDR: | 
|  | 129 | { | 
|  | 130 | auto sensorAuxNames = parseSensorAuxiliaryNamesPDR(pdr); | 
|  | 131 | if (!sensorAuxNames) | 
|  | 132 | { | 
|  | 133 | lg2::error( | 
|  | 134 | "Failed to parse PDR with type {TYPE} handle {HANDLE}", | 
|  | 135 | "TYPE", pdrHdr->type, "HANDLE", | 
|  | 136 | static_cast<uint32_t>(pdrHdr->record_handle)); | 
|  | 137 | continue; | 
|  | 138 | } | 
|  | 139 | sensorAuxiliaryNamesTbl.emplace_back(std::move(sensorAuxNames)); | 
|  | 140 | break; | 
|  | 141 | } | 
|  | 142 | case PLDM_NUMERIC_SENSOR_PDR: | 
|  | 143 | { | 
|  | 144 | auto parsedPdr = parseNumericSensorPDR(pdr); | 
|  | 145 | if (!parsedPdr) | 
|  | 146 | { | 
|  | 147 | lg2::error( | 
|  | 148 | "Failed to parse PDR with type {TYPE} handle {HANDLE}", | 
|  | 149 | "TYPE", pdrHdr->type, "HANDLE", | 
|  | 150 | static_cast<uint32_t>(pdrHdr->record_handle)); | 
|  | 151 | continue; | 
|  | 152 | } | 
|  | 153 | numericSensorPdrs.emplace_back(std::move(parsedPdr)); | 
|  | 154 | break; | 
|  | 155 | } | 
|  | 156 | case PLDM_COMPACT_NUMERIC_SENSOR_PDR: | 
|  | 157 | { | 
|  | 158 | auto parsedPdr = parseCompactNumericSensorPDR(pdr); | 
|  | 159 | if (!parsedPdr) | 
|  | 160 | { | 
|  | 161 | lg2::error( | 
|  | 162 | "Failed to parse PDR with type {TYPE} handle {HANDLE}", | 
|  | 163 | "TYPE", pdrHdr->type, "HANDLE", | 
|  | 164 | static_cast<uint32_t>(pdrHdr->record_handle)); | 
|  | 165 | continue; | 
|  | 166 | } | 
|  | 167 | auto sensorAuxNames = parseCompactNumericSensorNames(pdr); | 
|  | 168 | if (!sensorAuxNames) | 
|  | 169 | { | 
|  | 170 | lg2::error( | 
|  | 171 | "Failed to parse sensor name PDR with type {TYPE} handle {HANDLE}", | 
|  | 172 | "TYPE", pdrHdr->type, "HANDLE", | 
|  | 173 | static_cast<uint32_t>(pdrHdr->record_handle)); | 
|  | 174 | continue; | 
|  | 175 | } | 
|  | 176 | compactNumericSensorPdrs.emplace_back(std::move(parsedPdr)); | 
|  | 177 | sensorAuxiliaryNamesTbl.emplace_back(std::move(sensorAuxNames)); | 
|  | 178 | break; | 
|  | 179 | } | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 180 | case PLDM_ENTITY_AUXILIARY_NAMES_PDR: | 
|  | 181 | { | 
|  | 182 | auto entityNames = parseEntityAuxiliaryNamesPDR(pdr); | 
|  | 183 | if (!entityNames) | 
|  | 184 | { | 
|  | 185 | lg2::error( | 
|  | 186 | "Failed to parse sensor name PDR with type {TYPE} handle {HANDLE}", | 
|  | 187 | "TYPE", pdrHdr->type, "HANDLE", | 
|  | 188 | static_cast<uint32_t>(pdrHdr->record_handle)); | 
|  | 189 | continue; | 
|  | 190 | } | 
|  | 191 | entityAuxiliaryNamesTbl.emplace_back(std::move(entityNames)); | 
|  | 192 | break; | 
|  | 193 | } | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 194 | default: | 
|  | 195 | { | 
|  | 196 | lg2::error("Unsupported PDR with type {TYPE} handle {HANDLE}", | 
|  | 197 | "TYPE", pdrHdr->type, "HANDLE", | 
|  | 198 | static_cast<uint32_t>(pdrHdr->record_handle)); | 
|  | 199 | break; | 
|  | 200 | } | 
|  | 201 | } | 
|  | 202 | } | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 203 |  | 
|  | 204 | auto tName = findTerminusName(); | 
|  | 205 | if (tName && !tName.value().empty()) | 
|  | 206 | { | 
|  | 207 | lg2::info("Terminus {TID} has Auxiliary Name {NAME}.", "TID", tid, | 
|  | 208 | "NAME", tName.value()); | 
|  | 209 | terminusName = static_cast<std::string>(tName.value()); | 
|  | 210 | } | 
| Aditya Kurdunkar | 8eedaa6 | 2025-08-18 21:21:08 +0530 | [diff] [blame] | 211 | else | 
|  | 212 | { | 
|  | 213 | terminusName = std::format("Terminus_{}", tid); | 
|  | 214 | } | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 215 |  | 
|  | 216 | if (terminusName.empty() && | 
|  | 217 | (numericSensorPdrs.size() || compactNumericSensorPdrs.size())) | 
|  | 218 | { | 
|  | 219 | lg2::error( | 
|  | 220 | "Terminus ID {TID}: DOES NOT have name. Skip Adding sensors.", | 
|  | 221 | "TID", tid); | 
|  | 222 | return; | 
|  | 223 | } | 
|  | 224 |  | 
|  | 225 | if (createInventoryPath(terminusName)) | 
|  | 226 | { | 
| Konstantin Aladyshev | 12daa10 | 2025-08-04 17:42:06 +0300 | [diff] [blame] | 227 | lg2::info("Terminus ID {TID}: Created Inventory path {PATH}.", "TID", | 
|  | 228 | tid, "PATH", inventoryPath); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 229 | } | 
|  | 230 |  | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 231 | addNextSensorFromPDRs(); | 
|  | 232 | } | 
|  | 233 |  | 
|  | 234 | void Terminus::addNextSensorFromPDRs() | 
|  | 235 | { | 
|  | 236 | sensorCreationEvent.reset(); | 
|  | 237 |  | 
|  | 238 | if (terminusName.empty()) | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 239 | { | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 240 | lg2::error( | 
|  | 241 | "Terminus ID {TID}: DOES NOT have name. Skip Adding sensors.", | 
|  | 242 | "TID", tid); | 
|  | 243 | return; | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 244 | } | 
|  | 245 |  | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 246 | auto pdrIt = sensorPdrIt; | 
|  | 247 |  | 
|  | 248 | if (pdrIt < numericSensorPdrs.size()) | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 249 | { | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 250 | const auto& pdr = numericSensorPdrs[pdrIt]; | 
|  | 251 | // Defer adding the next Numeric Sensor | 
|  | 252 | sensorCreationEvent = std::make_unique<sdeventplus::source::Defer>( | 
|  | 253 | event, | 
|  | 254 | std::bind(std::mem_fn(&Terminus::addNumericSensor), this, pdr)); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 255 | } | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 256 | else if (pdrIt < numericSensorPdrs.size() + compactNumericSensorPdrs.size()) | 
|  | 257 | { | 
|  | 258 | pdrIt -= numericSensorPdrs.size(); | 
|  | 259 | const auto& pdr = compactNumericSensorPdrs[pdrIt]; | 
|  | 260 | // Defer adding the next Compact Numeric Sensor | 
|  | 261 | sensorCreationEvent = std::make_unique<sdeventplus::source::Defer>( | 
|  | 262 | event, std::bind(std::mem_fn(&Terminus::addCompactNumericSensor), | 
|  | 263 | this, pdr)); | 
|  | 264 | } | 
|  | 265 | else | 
|  | 266 | { | 
|  | 267 | sensorPdrIt = 0; | 
|  | 268 | return; | 
|  | 269 | } | 
|  | 270 |  | 
|  | 271 | // Move the iteration to the next sensor PDR | 
|  | 272 | sensorPdrIt++; | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 273 | } | 
|  | 274 |  | 
| Patrick Williams | 366507c | 2025-02-03 14:28:01 -0500 | [diff] [blame] | 275 | std::shared_ptr<SensorAuxiliaryNames> Terminus::getSensorAuxiliaryNames( | 
| Chau Ly | 3419e18 | 2025-07-29 07:11:32 +0000 | [diff] [blame] | 276 | SensorID id) | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 277 | { | 
|  | 278 | auto it = std::find_if( | 
|  | 279 | sensorAuxiliaryNamesTbl.begin(), sensorAuxiliaryNamesTbl.end(), | 
|  | 280 | [id]( | 
|  | 281 | const std::shared_ptr<SensorAuxiliaryNames>& sensorAuxiliaryNames) { | 
| Patrick Williams | 16c2a0a | 2024-08-16 15:20:59 -0400 | [diff] [blame] | 282 | const auto& [sensorId, sensorCnt, sensorNames] = | 
|  | 283 | *sensorAuxiliaryNames; | 
|  | 284 | return sensorId == id; | 
|  | 285 | }); | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 286 |  | 
|  | 287 | if (it != sensorAuxiliaryNamesTbl.end()) | 
|  | 288 | { | 
|  | 289 | return *it; | 
|  | 290 | } | 
|  | 291 | return nullptr; | 
|  | 292 | }; | 
|  | 293 |  | 
| Patrick Williams | 366507c | 2025-02-03 14:28:01 -0500 | [diff] [blame] | 294 | std::shared_ptr<SensorAuxiliaryNames> Terminus::parseSensorAuxiliaryNamesPDR( | 
|  | 295 | const std::vector<uint8_t>& pdrData) | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 296 | { | 
|  | 297 | constexpr uint8_t nullTerminator = 0; | 
|  | 298 | auto pdr = reinterpret_cast<const struct pldm_sensor_auxiliary_names_pdr*>( | 
|  | 299 | pdrData.data()); | 
|  | 300 | const uint8_t* ptr = pdr->names; | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 301 | std::vector<AuxiliaryNames> sensorAuxNames{}; | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 302 | char16_t alignedBuffer[PLDM_STR_UTF_16_MAX_LEN]; | 
|  | 303 | for ([[maybe_unused]] const auto& sensor : | 
|  | 304 | std::views::iota(0, static_cast<int>(pdr->sensor_count))) | 
|  | 305 | { | 
|  | 306 | const uint8_t nameStringCount = static_cast<uint8_t>(*ptr); | 
|  | 307 | ptr += sizeof(uint8_t); | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 308 | AuxiliaryNames nameStrings{}; | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 309 | for ([[maybe_unused]] const auto& count : | 
|  | 310 | std::views::iota(0, static_cast<int>(nameStringCount))) | 
|  | 311 | { | 
|  | 312 | std::string_view nameLanguageTag( | 
|  | 313 | reinterpret_cast<const char*>(ptr)); | 
|  | 314 | ptr += nameLanguageTag.size() + sizeof(nullTerminator); | 
|  | 315 |  | 
|  | 316 | int u16NameStringLen = 0; | 
|  | 317 | for (int i = 0; ptr[i] != 0 || ptr[i + 1] != 0; i += 2) | 
|  | 318 | { | 
|  | 319 | u16NameStringLen++; | 
|  | 320 | } | 
|  | 321 | /* include terminator */ | 
|  | 322 | u16NameStringLen++; | 
|  | 323 |  | 
|  | 324 | std::fill(std::begin(alignedBuffer), std::end(alignedBuffer), 0); | 
|  | 325 | if (u16NameStringLen > PLDM_STR_UTF_16_MAX_LEN) | 
|  | 326 | { | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 327 | lg2::error("Sensor name too long."); | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 328 | return nullptr; | 
|  | 329 | } | 
|  | 330 | memcpy(alignedBuffer, ptr, u16NameStringLen * sizeof(uint16_t)); | 
|  | 331 | std::u16string u16NameString(alignedBuffer, u16NameStringLen); | 
| tal-yac | f1e32c1 | 2024-08-12 13:12:30 +0300 | [diff] [blame] | 332 | ptr += u16NameString.size() * sizeof(uint16_t); | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 333 | std::transform(u16NameString.cbegin(), u16NameString.cend(), | 
|  | 334 | u16NameString.begin(), | 
|  | 335 | [](uint16_t utf16) { return be16toh(utf16); }); | 
| Patrick Williams | 15d42c5 | 2025-07-03 16:46:40 -0400 | [diff] [blame] | 336 | #pragma GCC diagnostic push | 
|  | 337 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 338 | std::string nameString = | 
|  | 339 | std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, | 
|  | 340 | char16_t>{} | 
|  | 341 | .to_bytes(u16NameString); | 
| Patrick Williams | 15d42c5 | 2025-07-03 16:46:40 -0400 | [diff] [blame] | 342 | #pragma GCC diagnostic pop | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 343 | nameStrings.emplace_back(std::make_pair( | 
|  | 344 | nameLanguageTag, pldm::utils::trimNameForDbus(nameString))); | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 345 | } | 
|  | 346 | sensorAuxNames.emplace_back(std::move(nameStrings)); | 
|  | 347 | } | 
|  | 348 | return std::make_shared<SensorAuxiliaryNames>( | 
|  | 349 | pdr->sensor_id, pdr->sensor_count, std::move(sensorAuxNames)); | 
|  | 350 | } | 
|  | 351 |  | 
| Patrick Williams | 366507c | 2025-02-03 14:28:01 -0500 | [diff] [blame] | 352 | std::shared_ptr<EntityAuxiliaryNames> Terminus::parseEntityAuxiliaryNamesPDR( | 
|  | 353 | const std::vector<uint8_t>& pdrData) | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 354 | { | 
|  | 355 | auto names_offset = sizeof(struct pldm_pdr_hdr) + | 
|  | 356 | PLDM_PDR_ENTITY_AUXILIARY_NAME_PDR_MIN_LENGTH; | 
|  | 357 | auto names_size = pdrData.size() - names_offset; | 
|  | 358 |  | 
| Patrick Williams | 16c2a0a | 2024-08-16 15:20:59 -0400 | [diff] [blame] | 359 | size_t decodedPdrSize = | 
|  | 360 | sizeof(struct pldm_entity_auxiliary_names_pdr) + names_size; | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 361 | auto vPdr = std::vector<char>(decodedPdrSize); | 
| Pavithra Barithaya | 36b3693 | 2025-01-30 10:33:05 +0530 | [diff] [blame] | 362 | auto decodedPdr = new (vPdr.data()) pldm_entity_auxiliary_names_pdr; | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 363 |  | 
|  | 364 | auto rc = decode_entity_auxiliary_names_pdr(pdrData.data(), pdrData.size(), | 
|  | 365 | decodedPdr, decodedPdrSize); | 
|  | 366 |  | 
|  | 367 | if (rc) | 
|  | 368 | { | 
|  | 369 | lg2::error( | 
|  | 370 | "Failed to decode Entity Auxiliary Name PDR data, error {RC}.", | 
|  | 371 | "RC", rc); | 
|  | 372 | return nullptr; | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | auto vNames = | 
|  | 376 | std::vector<pldm_entity_auxiliary_name>(decodedPdr->name_string_count); | 
|  | 377 | decodedPdr->names = vNames.data(); | 
|  | 378 |  | 
|  | 379 | rc = decode_pldm_entity_auxiliary_names_pdr_index(decodedPdr); | 
|  | 380 | if (rc) | 
|  | 381 | { | 
|  | 382 | lg2::error("Failed to decode Entity Auxiliary Name, error {RC}.", "RC", | 
|  | 383 | rc); | 
|  | 384 | return nullptr; | 
|  | 385 | } | 
|  | 386 |  | 
|  | 387 | AuxiliaryNames nameStrings{}; | 
|  | 388 | for (const auto& count : | 
|  | 389 | std::views::iota(0, static_cast<int>(decodedPdr->name_string_count))) | 
|  | 390 | { | 
|  | 391 | std::string_view nameLanguageTag = | 
|  | 392 | static_cast<std::string_view>(decodedPdr->names[count].tag); | 
|  | 393 | const size_t u16NameStringLen = | 
|  | 394 | std::char_traits<char16_t>::length(decodedPdr->names[count].name); | 
|  | 395 | std::u16string u16NameString(decodedPdr->names[count].name, | 
|  | 396 | u16NameStringLen); | 
|  | 397 | std::transform(u16NameString.cbegin(), u16NameString.cend(), | 
|  | 398 | u16NameString.begin(), | 
|  | 399 | [](uint16_t utf16) { return be16toh(utf16); }); | 
| Patrick Williams | 15d42c5 | 2025-07-03 16:46:40 -0400 | [diff] [blame] | 400 | #pragma GCC diagnostic push | 
|  | 401 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 402 | std::string nameString = | 
|  | 403 | std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{} | 
|  | 404 | .to_bytes(u16NameString); | 
| Patrick Williams | 15d42c5 | 2025-07-03 16:46:40 -0400 | [diff] [blame] | 405 | #pragma GCC diagnostic pop | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 406 | nameStrings.emplace_back(std::make_pair( | 
|  | 407 | nameLanguageTag, pldm::utils::trimNameForDbus(nameString))); | 
|  | 408 | } | 
|  | 409 |  | 
|  | 410 | EntityKey key{decodedPdr->container.entity_type, | 
|  | 411 | decodedPdr->container.entity_instance_num, | 
|  | 412 | decodedPdr->container.entity_container_id}; | 
|  | 413 |  | 
|  | 414 | return std::make_shared<EntityAuxiliaryNames>(key, nameStrings); | 
|  | 415 | } | 
|  | 416 |  | 
| Patrick Williams | 366507c | 2025-02-03 14:28:01 -0500 | [diff] [blame] | 417 | std::shared_ptr<pldm_numeric_sensor_value_pdr> Terminus::parseNumericSensorPDR( | 
|  | 418 | const std::vector<uint8_t>& pdr) | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 419 | { | 
|  | 420 | const uint8_t* ptr = pdr.data(); | 
|  | 421 | auto parsedPdr = std::make_shared<pldm_numeric_sensor_value_pdr>(); | 
|  | 422 | auto rc = decode_numeric_sensor_pdr_data(ptr, pdr.size(), parsedPdr.get()); | 
|  | 423 | if (rc) | 
|  | 424 | { | 
|  | 425 | return nullptr; | 
|  | 426 | } | 
|  | 427 | return parsedPdr; | 
|  | 428 | } | 
|  | 429 |  | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 430 | void Terminus::addNumericSensor( | 
|  | 431 | const std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr) | 
|  | 432 | { | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 433 | if (!pdr) | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 434 | { | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 435 | lg2::error( | 
|  | 436 | "Terminus ID {TID}: Skip adding Numeric Sensor - invalid pointer to PDR.", | 
|  | 437 | "TID", tid); | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 438 | addNextSensorFromPDRs(); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 439 | } | 
|  | 440 |  | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 441 | auto sensorId = pdr->sensor_id; | 
|  | 442 | auto sensorNames = getSensorNames(sensorId); | 
|  | 443 |  | 
|  | 444 | if (sensorNames.empty()) | 
|  | 445 | { | 
|  | 446 | lg2::error( | 
|  | 447 | "Terminus ID {TID}: Failed to get name for Numeric Sensor {SID}", | 
|  | 448 | "TID", tid, "SID", sensorId); | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 449 | addNextSensorFromPDRs(); | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 450 | } | 
|  | 451 |  | 
|  | 452 | std::string sensorName = sensorNames.front(); | 
|  | 453 |  | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 454 | try | 
|  | 455 | { | 
|  | 456 | auto sensor = std::make_shared<NumericSensor>( | 
|  | 457 | tid, true, pdr, sensorName, inventoryPath); | 
|  | 458 | lg2::info("Created NumericSensor {NAME}", "NAME", sensorName); | 
|  | 459 | numericSensors.emplace_back(sensor); | 
|  | 460 | } | 
|  | 461 | catch (const sdbusplus::exception_t& e) | 
|  | 462 | { | 
|  | 463 | lg2::error( | 
|  | 464 | "Failed to create NumericSensor. error - {ERROR} sensorname - {NAME}", | 
|  | 465 | "ERROR", e, "NAME", sensorName); | 
|  | 466 | } | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 467 |  | 
|  | 468 | addNextSensorFromPDRs(); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 469 | } | 
|  | 470 |  | 
| Patrick Williams | 366507c | 2025-02-03 14:28:01 -0500 | [diff] [blame] | 471 | std::shared_ptr<SensorAuxiliaryNames> Terminus::parseCompactNumericSensorNames( | 
|  | 472 | const std::vector<uint8_t>& sPdr) | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 473 | { | 
|  | 474 | std::vector<std::vector<std::pair<NameLanguageTag, SensorName>>> | 
|  | 475 | sensorAuxNames{}; | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 476 | AuxiliaryNames nameStrings{}; | 
| Pavithra Barithaya | 36b3693 | 2025-01-30 10:33:05 +0530 | [diff] [blame] | 477 |  | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 478 | auto pdr = | 
|  | 479 | reinterpret_cast<const pldm_compact_numeric_sensor_pdr*>(sPdr.data()); | 
|  | 480 |  | 
|  | 481 | if (sPdr.size() < | 
|  | 482 | (sizeof(pldm_compact_numeric_sensor_pdr) - sizeof(uint8_t))) | 
|  | 483 | { | 
|  | 484 | return nullptr; | 
|  | 485 | } | 
|  | 486 |  | 
|  | 487 | if (!pdr->sensor_name_length || | 
|  | 488 | (sPdr.size() < (sizeof(pldm_compact_numeric_sensor_pdr) - | 
|  | 489 | sizeof(uint8_t) + pdr->sensor_name_length))) | 
|  | 490 | { | 
|  | 491 | return nullptr; | 
|  | 492 | } | 
|  | 493 |  | 
|  | 494 | std::string nameString(reinterpret_cast<const char*>(pdr->sensor_name), | 
|  | 495 | pdr->sensor_name_length); | 
| Thu Nguyen | b8cf46b | 2024-06-15 02:44:35 +0000 | [diff] [blame] | 496 | nameStrings.emplace_back( | 
|  | 497 | std::make_pair("en", pldm::utils::trimNameForDbus(nameString))); | 
| Gilbert Chen | de2a132 | 2022-05-24 15:35:21 +0100 | [diff] [blame] | 498 | sensorAuxNames.emplace_back(std::move(nameStrings)); | 
|  | 499 |  | 
|  | 500 | return std::make_shared<SensorAuxiliaryNames>(pdr->sensor_id, 1, | 
|  | 501 | std::move(sensorAuxNames)); | 
|  | 502 | } | 
|  | 503 |  | 
|  | 504 | std::shared_ptr<pldm_compact_numeric_sensor_pdr> | 
|  | 505 | Terminus::parseCompactNumericSensorPDR(const std::vector<uint8_t>& sPdr) | 
|  | 506 | { | 
|  | 507 | auto pdr = | 
|  | 508 | reinterpret_cast<const pldm_compact_numeric_sensor_pdr*>(sPdr.data()); | 
|  | 509 | if (sPdr.size() < sizeof(pldm_compact_numeric_sensor_pdr)) | 
|  | 510 | { | 
|  | 511 | // Handle error: input data too small to contain valid pdr | 
|  | 512 | return nullptr; | 
|  | 513 | } | 
|  | 514 | auto parsedPdr = std::make_shared<pldm_compact_numeric_sensor_pdr>(); | 
|  | 515 |  | 
|  | 516 | parsedPdr->hdr = pdr->hdr; | 
|  | 517 | parsedPdr->terminus_handle = pdr->terminus_handle; | 
|  | 518 | parsedPdr->sensor_id = pdr->sensor_id; | 
|  | 519 | parsedPdr->entity_type = pdr->entity_type; | 
|  | 520 | parsedPdr->entity_instance = pdr->entity_instance; | 
|  | 521 | parsedPdr->container_id = pdr->container_id; | 
|  | 522 | parsedPdr->sensor_name_length = pdr->sensor_name_length; | 
|  | 523 | parsedPdr->base_unit = pdr->base_unit; | 
|  | 524 | parsedPdr->unit_modifier = pdr->unit_modifier; | 
|  | 525 | parsedPdr->occurrence_rate = pdr->occurrence_rate; | 
|  | 526 | parsedPdr->range_field_support = pdr->range_field_support; | 
|  | 527 | parsedPdr->warning_high = pdr->warning_high; | 
|  | 528 | parsedPdr->warning_low = pdr->warning_low; | 
|  | 529 | parsedPdr->critical_high = pdr->critical_high; | 
|  | 530 | parsedPdr->critical_low = pdr->critical_low; | 
|  | 531 | parsedPdr->fatal_high = pdr->fatal_high; | 
|  | 532 | parsedPdr->fatal_low = pdr->fatal_low; | 
|  | 533 | return parsedPdr; | 
|  | 534 | } | 
|  | 535 |  | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 536 | void Terminus::addCompactNumericSensor( | 
|  | 537 | const std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr) | 
|  | 538 | { | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 539 | if (!pdr) | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 540 | { | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 541 | lg2::error( | 
|  | 542 | "Terminus ID {TID}: Skip adding Compact Numeric Sensor - invalid pointer to PDR.", | 
|  | 543 | "TID", tid); | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 544 | addNextSensorFromPDRs(); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 545 | } | 
|  | 546 |  | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 547 | auto sensorId = pdr->sensor_id; | 
|  | 548 | auto sensorNames = getSensorNames(sensorId); | 
|  | 549 |  | 
|  | 550 | if (sensorNames.empty()) | 
|  | 551 | { | 
|  | 552 | lg2::error( | 
|  | 553 | "Terminus ID {TID}: Failed to get name for Compact Numeric Sensor {SID}", | 
|  | 554 | "TID", tid, "SID", sensorId); | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 555 | addNextSensorFromPDRs(); | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 556 | } | 
|  | 557 |  | 
|  | 558 | std::string sensorName = sensorNames.front(); | 
|  | 559 |  | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 560 | try | 
|  | 561 | { | 
|  | 562 | auto sensor = std::make_shared<NumericSensor>( | 
|  | 563 | tid, true, pdr, sensorName, inventoryPath); | 
|  | 564 | lg2::info("Created Compact NumericSensor {NAME}", "NAME", sensorName); | 
|  | 565 | numericSensors.emplace_back(sensor); | 
|  | 566 | } | 
|  | 567 | catch (const sdbusplus::exception_t& e) | 
|  | 568 | { | 
|  | 569 | lg2::error( | 
|  | 570 | "Failed to create Compact NumericSensor. error - {ERROR} sensorname - {NAME}", | 
|  | 571 | "ERROR", e, "NAME", sensorName); | 
|  | 572 | } | 
| Chaul Ly | fdf61cc | 2025-01-22 07:55:45 +0000 | [diff] [blame] | 573 |  | 
|  | 574 | addNextSensorFromPDRs(); | 
| Thu Nguyen | 3c5486d | 2024-08-01 08:03:08 +0000 | [diff] [blame] | 575 | } | 
|  | 576 |  | 
| Chau Ly | 3419e18 | 2025-07-29 07:11:32 +0000 | [diff] [blame] | 577 | std::shared_ptr<NumericSensor> Terminus::getSensorObject(SensorID id) | 
| Gilbert Chen | 77e6fe7 | 2024-08-06 09:23:30 +0000 | [diff] [blame] | 578 | { | 
|  | 579 | if (terminusName.empty()) | 
|  | 580 | { | 
|  | 581 | lg2::error( | 
|  | 582 | "Terminus ID {TID}: DOES NOT have terminus name. No numeric sensor object.", | 
|  | 583 | "TID", tid); | 
|  | 584 | return nullptr; | 
|  | 585 | } | 
|  | 586 | if (!numericSensors.size()) | 
|  | 587 | { | 
|  | 588 | lg2::error("Terminus ID {TID} name {NAME}: DOES NOT have sensor.", | 
|  | 589 | "TID", tid, "NAME", terminusName); | 
|  | 590 | return nullptr; | 
|  | 591 | } | 
|  | 592 |  | 
|  | 593 | for (auto& sensor : numericSensors) | 
|  | 594 | { | 
|  | 595 | if (!sensor) | 
|  | 596 | { | 
|  | 597 | continue; | 
|  | 598 | } | 
|  | 599 |  | 
|  | 600 | if (sensor->sensorId == id) | 
|  | 601 | { | 
|  | 602 | return sensor; | 
|  | 603 | } | 
|  | 604 | } | 
|  | 605 |  | 
|  | 606 | return nullptr; | 
|  | 607 | } | 
| Dung Cao | b6d3943 | 2024-06-05 03:46:47 +0000 | [diff] [blame] | 608 |  | 
|  | 609 | /** @brief Check if a pointer is go through end of table | 
|  | 610 | *  @param[in] table - pointer to FRU record table | 
|  | 611 | *  @param[in] p - pointer to each record of FRU record table | 
|  | 612 | *  @param[in] tableSize - FRU table size | 
|  | 613 | */ | 
|  | 614 | static bool isTableEnd(const uint8_t* table, const uint8_t* p, | 
|  | 615 | const size_t tableSize) | 
|  | 616 | { | 
|  | 617 | auto offset = p - table; | 
|  | 618 | return (tableSize - offset) < sizeof(struct pldm_fru_record_data_format); | 
|  | 619 | } | 
|  | 620 |  | 
|  | 621 | void Terminus::updateInventoryWithFru(const uint8_t* fruData, | 
|  | 622 | const size_t fruLen) | 
|  | 623 | { | 
|  | 624 | auto tmp = getTerminusName(); | 
|  | 625 | if (!tmp || tmp.value().empty()) | 
|  | 626 | { | 
|  | 627 | lg2::error( | 
|  | 628 | "Terminus ID {TID}: Failed to update Inventory with Fru Data - error : Terminus name is empty.", | 
|  | 629 | "TID", tid); | 
|  | 630 | return; | 
|  | 631 | } | 
|  | 632 |  | 
|  | 633 | if (createInventoryPath(static_cast<std::string>(tmp.value()))) | 
|  | 634 | { | 
|  | 635 | lg2::info("Terminus ID {TID}: Created Inventory path.", "TID", tid); | 
|  | 636 | } | 
|  | 637 |  | 
|  | 638 | auto ptr = fruData; | 
|  | 639 | while (!isTableEnd(fruData, ptr, fruLen)) | 
|  | 640 | { | 
|  | 641 | auto record = reinterpret_cast<const pldm_fru_record_data_format*>(ptr); | 
|  | 642 | ptr += sizeof(pldm_fru_record_data_format) - | 
|  | 643 | sizeof(pldm_fru_record_tlv); | 
|  | 644 |  | 
|  | 645 | if (!record->num_fru_fields) | 
|  | 646 | { | 
|  | 647 | lg2::error( | 
|  | 648 | "Invalid number of fields {NUM} of Record ID Type {TYPE} of terminus {TID}", | 
|  | 649 | "NUM", record->num_fru_fields, "TYPE", record->record_type, | 
|  | 650 | "TID", tid); | 
|  | 651 | return; | 
|  | 652 | } | 
|  | 653 |  | 
|  | 654 | if (record->record_type != PLDM_FRU_RECORD_TYPE_GENERAL) | 
|  | 655 | { | 
|  | 656 | lg2::error( | 
|  | 657 | "Does not support Fru Record ID Type {TYPE} of terminus {TID}", | 
|  | 658 | "TYPE", record->record_type, "TID", tid); | 
|  | 659 |  | 
|  | 660 | for ([[maybe_unused]] const auto& idx : | 
|  | 661 | std::views::iota(0, static_cast<int>(record->num_fru_fields))) | 
|  | 662 | { | 
|  | 663 | auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(ptr); | 
|  | 664 | ptr += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; | 
|  | 665 | } | 
|  | 666 | continue; | 
|  | 667 | } | 
|  | 668 | /* FRU General record type */ | 
|  | 669 | for ([[maybe_unused]] const auto& idx : | 
|  | 670 | std::views::iota(0, static_cast<int>(record->num_fru_fields))) | 
|  | 671 | { | 
|  | 672 | auto tlv = reinterpret_cast<const pldm_fru_record_tlv*>(ptr); | 
|  | 673 | std::string fruField{}; | 
|  | 674 | if (tlv->type != PLDM_FRU_FIELD_TYPE_IANA) | 
|  | 675 | { | 
|  | 676 | auto strOptional = | 
|  | 677 | pldm::utils::fruFieldValuestring(tlv->value, tlv->length); | 
|  | 678 | if (!strOptional) | 
|  | 679 | { | 
|  | 680 | ptr += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; | 
|  | 681 | continue; | 
|  | 682 | } | 
|  | 683 | fruField = strOptional.value(); | 
|  | 684 |  | 
|  | 685 | if (fruField.empty()) | 
|  | 686 | { | 
|  | 687 | ptr += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; | 
|  | 688 | continue; | 
|  | 689 | } | 
|  | 690 | } | 
|  | 691 |  | 
|  | 692 | switch (tlv->type) | 
|  | 693 | { | 
|  | 694 | case PLDM_FRU_FIELD_TYPE_MODEL: | 
|  | 695 | inventoryItemBoardInft->model(fruField); | 
|  | 696 | break; | 
|  | 697 | case PLDM_FRU_FIELD_TYPE_PN: | 
|  | 698 | inventoryItemBoardInft->partNumber(fruField); | 
|  | 699 | break; | 
|  | 700 | case PLDM_FRU_FIELD_TYPE_SN: | 
|  | 701 | inventoryItemBoardInft->serialNumber(fruField); | 
|  | 702 | break; | 
|  | 703 | case PLDM_FRU_FIELD_TYPE_MANUFAC: | 
|  | 704 | inventoryItemBoardInft->manufacturer(fruField); | 
|  | 705 | break; | 
|  | 706 | case PLDM_FRU_FIELD_TYPE_NAME: | 
|  | 707 | inventoryItemBoardInft->names({fruField}); | 
|  | 708 | break; | 
|  | 709 | case PLDM_FRU_FIELD_TYPE_VERSION: | 
|  | 710 | inventoryItemBoardInft->version(fruField); | 
|  | 711 | break; | 
|  | 712 | case PLDM_FRU_FIELD_TYPE_ASSET_TAG: | 
|  | 713 | inventoryItemBoardInft->assetTag(fruField); | 
|  | 714 | break; | 
|  | 715 | case PLDM_FRU_FIELD_TYPE_VENDOR: | 
|  | 716 | case PLDM_FRU_FIELD_TYPE_CHASSIS: | 
|  | 717 | case PLDM_FRU_FIELD_TYPE_SKU: | 
|  | 718 | case PLDM_FRU_FIELD_TYPE_DESC: | 
|  | 719 | case PLDM_FRU_FIELD_TYPE_EC_LVL: | 
|  | 720 | case PLDM_FRU_FIELD_TYPE_OTHER: | 
|  | 721 | break; | 
|  | 722 | case PLDM_FRU_FIELD_TYPE_IANA: | 
|  | 723 | auto iana = | 
|  | 724 | pldm::utils::fruFieldParserU32(tlv->value, tlv->length); | 
|  | 725 | if (!iana) | 
|  | 726 | { | 
|  | 727 | ptr += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; | 
|  | 728 | continue; | 
|  | 729 | } | 
|  | 730 | break; | 
|  | 731 | } | 
|  | 732 | ptr += sizeof(pldm_fru_record_tlv) - 1 + tlv->length; | 
|  | 733 | } | 
|  | 734 | } | 
|  | 735 | } | 
|  | 736 |  | 
| Chau Ly | 3419e18 | 2025-07-29 07:11:32 +0000 | [diff] [blame] | 737 | std::vector<std::string> Terminus::getSensorNames(const SensorID& sensorId) | 
| Chau Ly | 38a09d2 | 2025-03-05 05:47:43 +0000 | [diff] [blame] | 738 | { | 
|  | 739 | std::vector<std::string> sensorNames; | 
|  | 740 | std::string defaultName = | 
|  | 741 | std::format("{}_Sensor_{}", terminusName, unsigned(sensorId)); | 
|  | 742 | // To ensure there's always a default name at offset 0 | 
|  | 743 | sensorNames.emplace_back(defaultName); | 
|  | 744 |  | 
|  | 745 | auto sensorAuxiliaryNames = getSensorAuxiliaryNames(sensorId); | 
|  | 746 | if (!sensorAuxiliaryNames) | 
|  | 747 | { | 
|  | 748 | return sensorNames; | 
|  | 749 | } | 
|  | 750 |  | 
|  | 751 | const auto& [id, sensorCount, nameMap] = *sensorAuxiliaryNames; | 
|  | 752 | for (const unsigned int& i : | 
|  | 753 | std::views::iota(0, static_cast<int>(sensorCount))) | 
|  | 754 | { | 
|  | 755 | auto sensorName = defaultName; | 
|  | 756 | if (i > 0) | 
|  | 757 | { | 
|  | 758 | // Sensor name at offset 0 will be the default name | 
|  | 759 | sensorName += "_" + std::to_string(i); | 
|  | 760 | } | 
|  | 761 |  | 
|  | 762 | for (const auto& [languageTag, name] : nameMap[i]) | 
|  | 763 | { | 
|  | 764 | if (languageTag == "en" && !name.empty()) | 
|  | 765 | { | 
|  | 766 | sensorName = std::format("{}_{}", terminusName, name); | 
|  | 767 | } | 
|  | 768 | } | 
|  | 769 |  | 
|  | 770 | if (i >= sensorNames.size()) | 
|  | 771 | { | 
|  | 772 | sensorNames.emplace_back(sensorName); | 
|  | 773 | } | 
|  | 774 | else | 
|  | 775 | { | 
|  | 776 | sensorNames[i] = sensorName; | 
|  | 777 | } | 
|  | 778 | } | 
|  | 779 |  | 
|  | 780 | return sensorNames; | 
|  | 781 | } | 
|  | 782 |  | 
| Gilbert Chen | 6c7fed4 | 2022-02-22 15:40:17 +0000 | [diff] [blame] | 783 | } // namespace platform_mc | 
|  | 784 | } // namespace pldm |