#pragma once #include #include #include #include #include #include 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