pldmtool: Support Auxiliary name PDRs in GetPDR

This commit supports sensorAuxName (Section 28.8 DSP0248 Version
1.2.2) and effecterAuxName PDR type (Section 28.15 DSP0248 Version
1.2.2) options in `pldmtool platform GetPDR` command. It will parse
the PDR data and print out the auxiliary name PDR fields.

Tested:
1. Check `pldmtool platform GetPDR -t sensorAuxName`.
2. Check `pldmtool platform GetPDR -t efffecterAuxName`.
3. Check `pldmtool platform GetPDR -d <#effecterAuxName>`.
```
pldmtool platform GetPDR -m 20 -d 0x6e
{
    "nextRecordHandle": 111,
    "responseCount": 45,
    "recordHandle": 110,
    "PDRHeaderVersion": 1,
    "PDRType": "Effecter Auxiliary Names PDR",
    "recordChangeNumber": 0,
    "dataLength": 35,
    "terminusHandle": 0,
    "effecterId": 159,
    "effecterCount": 1,
    "effecter0_nameLanguageTag0": "en",
    "effecter0_entityAuxName0": "PMin Pwr Lmt"
}
```

Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: Ibfca813483f72c8214276e79a1223730814e8a95
diff --git a/pldmtool/pldm_platform_cmd.cpp b/pldmtool/pldm_platform_cmd.cpp
index ba4a3b7..2aa9252 100644
--- a/pldmtool/pldm_platform_cmd.cpp
+++ b/pldmtool/pldm_platform_cmd.cpp
@@ -2,10 +2,13 @@
 #include "pldm_cmd_helper.hpp"
 
 #include <libpldm/entity.h>
+#include <libpldm/platform.h>
 #include <libpldm/state_set.h>
 
+#include <algorithm>
 #include <cstddef>
 #include <map>
+#include <ranges>
 
 #ifdef OEM_IBM
 #include "oem/ibm/oem_ibm_state_set.hpp"
@@ -79,7 +82,8 @@
                                    "supported types:\n"
                                    "[terminusLocator, stateSensor, "
                                    "numericEffecter, stateEffecter, "
-                                   "compactNumericSensor, "
+                                   "compactNumericSensor, sensorauxname, "
+                                   "efffecterAuxName, "
                                    "EntityAssociation, fruRecord, ... ]");
 
         getPDRGroupOption = pdrOptionGroup->add_option(
@@ -586,7 +590,9 @@
     const std::map<std::string, uint8_t> strToPdrType = {
         {"terminuslocator", PLDM_TERMINUS_LOCATOR_PDR},
         {"statesensor", PLDM_STATE_SENSOR_PDR},
+        {"sensorauxname", PLDM_SENSOR_AUXILIARY_NAMES_PDR},
         {"numericeffecter", PLDM_NUMERIC_EFFECTER_PDR},
+        {"efffecterauxname", PLDM_EFFECTER_AUXILIARY_NAMES_PDR},
         {"compactnumericsensor", PLDM_COMPACT_NUMERIC_SENSOR_PDR},
         {"stateeffecter", PLDM_STATE_EFFECTER_PDR},
         {"entityassociation", PLDM_PDR_ENTITY_ASSOCIATION},
@@ -859,6 +865,66 @@
         }
     }
 
+    /** @brief Format the Sensor/Effecter Aux Name PDR types to json output
+     *
+     *  @param[in] data - reference to the Sensor/Effecter Aux Name PDR
+     *  @param[out] output - PDRs data fields in Json format
+     */
+    void printAuxNamePDR(uint8_t* data, ordered_json& output)
+    {
+        constexpr uint8_t nullTerminator = 0;
+        struct pldm_effecter_aux_name_pdr* auxNamePdr =
+            (struct pldm_effecter_aux_name_pdr*)data;
+
+        if (!auxNamePdr)
+        {
+            std::cerr << "Failed to get Aux Name PDR" << std::endl;
+            return;
+        }
+
+        std::string sPrefix = "effecter";
+        if (auxNamePdr->hdr.type == PLDM_SENSOR_AUXILIARY_NAMES_PDR)
+        {
+            sPrefix = "sensor";
+        }
+        output["terminusHandle"] = int(auxNamePdr->terminus_handle);
+        output[sPrefix + "Id"] = int(auxNamePdr->effecter_id);
+        output[sPrefix + "Count"] = int(auxNamePdr->effecter_count);
+
+        const uint8_t* ptr = auxNamePdr->effecter_names;
+        for (auto i : std::views::iota(0, (int)auxNamePdr->effecter_count))
+        {
+            const uint8_t nameStringCount = static_cast<uint8_t>(*ptr);
+            ptr += sizeof(uint8_t);
+            for (auto j : std::views::iota(0, (int)nameStringCount))
+            {
+                std::string nameLanguageTagKey = sPrefix + std::to_string(j) +
+                                                 "_nameLanguageTag" +
+                                                 std::to_string(i);
+                std::string entityAuxNameKey = sPrefix + std::to_string(j) +
+                                               "_entityAuxName" +
+                                               std::to_string(i);
+                std::string nameLanguageTag(reinterpret_cast<const char*>(ptr),
+                                            0, PLDM_STR_UTF_8_MAX_LEN);
+                ptr += nameLanguageTag.size() + sizeof(nullTerminator);
+                std::u16string u16NameString(
+                    reinterpret_cast<const char16_t*>(ptr), 0,
+                    PLDM_STR_UTF_16_MAX_LEN);
+                ptr += (u16NameString.size() + sizeof(nullTerminator)) *
+                       sizeof(uint16_t);
+                std::transform(u16NameString.cbegin(), u16NameString.cend(),
+                               u16NameString.begin(),
+                               [](uint16_t utf16) { return be16toh(utf16); });
+                std::string nameString =
+                    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,
+                                         char16_t>{}
+                        .to_bytes(u16NameString);
+                output[nameLanguageTagKey] = nameLanguageTag;
+                output[entityAuxNameKey] = nameString;
+            }
+        }
+    }
+
     void printNumericEffecterPDR(uint8_t* data, ordered_json& output)
     {
         struct pldm_numeric_effecter_value_pdr* pdr =
@@ -1261,6 +1327,12 @@
             case PLDM_NUMERIC_EFFECTER_PDR:
                 printNumericEffecterPDR(data, output);
                 break;
+            case PLDM_SENSOR_AUXILIARY_NAMES_PDR:
+                printAuxNamePDR(data, output);
+                break;
+            case PLDM_EFFECTER_AUXILIARY_NAMES_PDR:
+                printAuxNamePDR(data, output);
+                break;
             case PLDM_STATE_EFFECTER_PDR:
                 printStateEffecterPDR(data, output);
                 break;