| #pragma once |
| |
| #include "libpldm/instance-id.h" |
| |
| #include <cerrno> |
| #include <cstdint> |
| #include <exception> |
| #include <string> |
| #include <system_error> |
| |
| namespace pldm |
| { |
| |
| /** @class InstanceId |
| * @brief Implementation of PLDM instance id as per DSP0240 v1.0.0 |
| */ |
| class InstanceIdDb |
| { |
| public: |
| InstanceIdDb() |
| { |
| int rc = pldm_instance_db_init_default(&pldmInstanceIdDb); |
| if (rc) |
| { |
| throw std::system_category().default_error_condition(rc); |
| } |
| } |
| |
| /** @brief Constructor |
| * |
| * @param[in] path - instance ID database path |
| */ |
| InstanceIdDb(const std::string& path) |
| { |
| int rc = pldm_instance_db_init(&pldmInstanceIdDb, path.c_str()); |
| if (rc) |
| { |
| throw std::system_category().default_error_condition(rc); |
| } |
| } |
| |
| ~InstanceIdDb() |
| { |
| /* |
| * Abandon error-reporting. We shouldn't throw an exception from the |
| * destructor, and the class has multiple consumers using incompatible |
| * logging strategies. |
| * |
| * Broadly, it should be possible to use strace to investigate. |
| */ |
| pldm_instance_db_destroy(pldmInstanceIdDb); |
| } |
| |
| /** @brief Allocate an instance ID for the given terminus |
| * @param[in] tid - the terminus ID the instance ID is associated with |
| * @return - PLDM instance id or -EAGAIN if there are no available instance |
| * IDs |
| */ |
| uint8_t next(uint8_t tid) |
| { |
| uint8_t id; |
| int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id); |
| |
| if (rc == -EAGAIN) |
| { |
| throw std::runtime_error("No free instance ids"); |
| } |
| |
| if (rc) |
| { |
| throw std::system_category().default_error_condition(rc); |
| } |
| |
| return id; |
| } |
| |
| /** @brief Mark an instance id as unused |
| * @param[in] tid - the terminus ID the instance ID is associated with |
| * @param[in] instanceId - PLDM instance id to be freed |
| */ |
| void free(uint8_t tid, uint8_t instanceId) |
| { |
| int rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceId); |
| if (rc == -EINVAL) |
| { |
| throw std::runtime_error( |
| "Instance ID " + std::to_string(instanceId) + " for TID " + |
| std::to_string(tid) + " was not previously allocated"); |
| } |
| if (rc) |
| { |
| throw std::system_category().default_error_condition(rc); |
| } |
| } |
| |
| private: |
| pldm_instance_db* pldmInstanceIdDb = nullptr; |
| }; |
| |
| } // namespace pldm |