1 #pragma once
2 
3 #include "common/instance_id.hpp"
4 #include "xyz/openbmc_project/Common/error.hpp"
5 #include "xyz/openbmc_project/PLDM/Requester/server.hpp"
6 
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/server/object.hpp>
9 
10 #include <map>
11 
12 namespace pldm
13 {
14 namespace dbus_api
15 {
16 
17 using RequesterIntf = sdbusplus::server::object_t<
18     sdbusplus::xyz::openbmc_project::PLDM::server::Requester>;
19 
20 /** @class Requester
21  *  @brief OpenBMC PLDM.Requester implementation.
22  *  @details A concrete implementation for the
23  *  xyz.openbmc_project.PLDM.Requester DBus APIs.
24  */
25 class Requester : public RequesterIntf
26 {
27   public:
28     Requester() = delete;
29     Requester(const Requester&) = delete;
30     Requester& operator=(const Requester&) = delete;
31     Requester(Requester&&) = delete;
32     Requester& operator=(Requester&&) = delete;
33     virtual ~Requester() = default;
34 
35     /** @brief Constructor to put object onto bus at a dbus path.
36      *  @param[in] bus - Bus to attach to.
37      *  @param[in] path - Path to attach at.
38      *  @param[in] db - The database to use for allocating instance IDs
39      *  @note will throw TooManyResources() if there were no free instance IDs
40      *  Throws std::system_category().default_error_condition if there is
41      *  something wrong with the instance ID database.
42      */
43     Requester(sdbusplus::bus_t& bus, const std::string& path,
44               InstanceIdDb& db) :
45         RequesterIntf(bus, path.c_str()),
46         pldmInstanceIdDb(db){};
47 
48     /** @brief Implementation for RequesterIntf.GetInstanceId */
49     uint8_t getInstanceId(uint8_t eid) override
50     {
51         int id;
52 
53         // Ideally we would be able to look up the TID for a given EID. We don't
54         // have that infrastructure in place yet. So use the EID value for the
55         // TID. This is an interim step towards the PLDM requester logic moving
56         // into libpldm, and eventually this won't be needed.
57         try
58         {
59             id = pldmInstanceIdDb.next(eid);
60         }
61         catch (const std::runtime_error& e)
62         {
63             throw sdbusplus::xyz::openbmc_project::Common::Error::
64                 TooManyResources();
65         }
66 
67         return id;
68     }
69 
70     /** @brief Mark an instance id as unused
71      *  @param[in] eid - MCTP eid to which this instance id belongs
72      *  @param[in] instanceId - PLDM instance id to be freed
73      *  @note will throw std::runtime_error if the instance ID was not
74      *  previously allocated.
75      *  Throws std::system_category().default_error_condition if there is
76      *  something wrong with the instance ID database.
77      */
78     void markFree(uint8_t eid, uint8_t instanceId)
79     {
80         pldmInstanceIdDb.free(eid, instanceId);
81     }
82 
83   private:
84     InstanceIdDb& pldmInstanceIdDb;
85 };
86 
87 } // namespace dbus_api
88 } // namespace pldm
89