Map state effecter id to D-Bus object path

Add a way to map state effecter ids to D-Bus object paths (multiple
paths in case the effecter is composite).

The mapping is specified in the state effecter PDR JSON (because the
mapping is system specific), and is stored in a map in memory. This will
be used by the get/set state effecter commands to route effecter ids to
D-Bus.

Change-Id: Ic79fae2445fd257302dd1298830f58b91fed9a1f
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/libpldmresponder/effecters.cpp b/libpldmresponder/effecters.cpp
index ecc63bc..a48582b 100644
--- a/libpldmresponder/effecters.cpp
+++ b/libpldmresponder/effecters.cpp
@@ -1,5 +1,7 @@
 #include "effecters.hpp"
 
+#include <map>
+
 namespace pldm
 {
 
@@ -15,6 +17,28 @@
     return ++id;
 }
 
+namespace dbus_mapping
+{
+
+namespace internal
+{
+
+std::map<Id, Paths> idToDbus{};
+
+} // namespace internal
+
+void add(Id id, Paths&& paths)
+{
+    internal::idToDbus.emplace(id, std::move(paths));
+}
+
+Paths get(Id id)
+{
+    return internal::idToDbus.at(id);
+}
+
+} // namespace dbus_mapping
+
 } // namespace effecter
 } // namespace responder
 } // namespace pldm
diff --git a/libpldmresponder/effecters.hpp b/libpldmresponder/effecters.hpp
index a0704df..2dfa1f5 100644
--- a/libpldmresponder/effecters.hpp
+++ b/libpldmresponder/effecters.hpp
@@ -2,6 +2,9 @@
 
 #include <stdint.h>
 
+#include <string>
+#include <vector>
+
 namespace pldm
 {
 
@@ -19,6 +22,26 @@
  */
 Id nextId();
 
+namespace dbus_mapping
+{
+using Paths = std::vector<std::string>;
+
+/** @brief Add an effecter id -> D-Bus objects mapping
+ *
+ *  @param[in] id - effecter id
+ *  @param[in] paths - list of D-Bus object paths
+ */
+void add(Id id, Paths&& paths);
+
+/** @brief Retrieve an effecter id -> D-Bus objects mapping
+ *
+ *  @param[in] id - effecter id
+ *
+ *  @return Paths - list of D-Bus object paths
+ */
+Paths get(Id id);
+} // namespace dbus_mapping
+
 } // namespace effecter
 } // namespace responder
 } // namespace pldm
diff --git a/libpldmresponder/examples/pdr/11.json b/libpldmresponder/examples/pdr/11.json
index 7410ab9..a037ad4 100644
--- a/libpldmresponder/examples/pdr/11.json
+++ b/libpldmresponder/examples/pdr/11.json
@@ -8,7 +8,8 @@
                 "id" : 196,
                 "size" : 1,
                 "states" : [1]
-            }
+            },
+            "dbus" : "/foo/bar"
         }]
     },
     {
@@ -20,14 +21,16 @@
                 "id" : 197,
                 "size" : 1,
                 "states" : [1]
-            }
+            },
+            "dbus" : "/foo/bar"
         },
         {
             "set" : {
                 "id" : 198,
                 "size" : 2,
                 "states" : [1,2,5,15]
-            }
+            },
+            "dbus" : "/foo/bar/baz"
         }]
     }]
 }
diff --git a/libpldmresponder/pdr.hpp b/libpldmresponder/pdr.hpp
index 9cbfbac..71d8aee 100644
--- a/libpldmresponder/pdr.hpp
+++ b/libpldmresponder/pdr.hpp
@@ -238,6 +238,8 @@
                   pdr->has_description_pdr = false;
                   pdr->composite_effecter_count = effecters.size();
 
+                  using namespace effecter::dbus_mapping;
+                  Paths paths{};
                   uint8_t* start = pdrEntry.data() +
                                    sizeof(pldm_state_effecter_pdr) -
                                    sizeof(uint8_t);
@@ -264,7 +266,11 @@
                           bf->byte |= 1 << bit;
                       }
                       start += possibleStates->possible_states_size;
+
+                      auto dbus = effecter.value("dbus", empty);
+                      paths.emplace_back(std::move(dbus));
                   }
+                  add(pdr->effecter_id, std::move(paths));
                   repo.add(std::move(pdrEntry));
               }
           }}};
diff --git a/test/libpldmresponder_pdr_state_effecter_test.cpp b/test/libpldmresponder_pdr_state_effecter_test.cpp
index fb8af01..24eea41 100644
--- a/test/libpldmresponder_pdr_state_effecter_test.cpp
+++ b/test/libpldmresponder_pdr_state_effecter_test.cpp
@@ -1,3 +1,4 @@
+#include "libpldmresponder/effecters.hpp"
 #include "libpldmresponder/pdr.hpp"
 
 #include "libpldm/platform.h"
@@ -9,6 +10,7 @@
 TEST(GeneratePDR, testGoodJson)
 {
     using namespace pdr;
+    using namespace effecter::dbus_mapping;
     Repo& pdrRepo = get("./pdr_jsons/good");
 
     // 2 entries
@@ -42,6 +44,9 @@
     bf1.byte = 2;
     ASSERT_EQ(states->states[0].byte, bf1.byte);
 
+    auto paths = get(pdr->effecter_id);
+    ASSERT_EQ(paths[0], "/foo/bar");
+
     // Check second PDR
     e = pdrRepo.at(2);
     pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data());
@@ -76,6 +81,12 @@
     bf2[1].byte = 128;
     ASSERT_EQ(states->states[0].byte, bf2[0].byte);
     ASSERT_EQ(states->states[1].byte, bf2[1].byte);
+
+    paths = get(pdr->effecter_id);
+    ASSERT_EQ(paths[0], "/foo/bar");
+    ASSERT_EQ(paths[1], "/foo/bar/baz");
+
+    ASSERT_THROW(get(0xDEAD), std::exception);
 }
 
 TEST(GeneratePDR, testNoJson)
diff --git a/test/pdr_jsons/good/11.json b/test/pdr_jsons/good/11.json
index 7410ab9..a037ad4 100644
--- a/test/pdr_jsons/good/11.json
+++ b/test/pdr_jsons/good/11.json
@@ -8,7 +8,8 @@
                 "id" : 196,
                 "size" : 1,
                 "states" : [1]
-            }
+            },
+            "dbus" : "/foo/bar"
         }]
     },
     {
@@ -20,14 +21,16 @@
                 "id" : 197,
                 "size" : 1,
                 "states" : [1]
-            }
+            },
+            "dbus" : "/foo/bar"
         },
         {
             "set" : {
                 "id" : 198,
                 "size" : 2,
                 "states" : [1,2,5,15]
-            }
+            },
+            "dbus" : "/foo/bar/baz"
         }]
     }]
 }