blob: fae52c5bff58af713192a30e250b5a3a40a6e4a8 [file] [log] [blame]
#pragma once
#include "libpldm/instance-id.h"
#include <phosphor-logging/lg2.hpp>
#include <cerrno>
#include <cstdint>
#include <exception>
#include <string>
#include <system_error>
PHOSPHOR_LOG2_USING;
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()
{
int rc = pldm_instance_db_destroy(pldmInstanceIdDb);
if (rc)
{
error("pldm_instance_db_destroy failed, rc= {RC}", "RC", rc);
}
}
/** @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