blob: fae52c5bff58af713192a30e250b5a3a40a6e4a8 [file] [log] [blame]
Deepak Kodihalli4de4d002019-11-11 02:41:43 -06001#pragma once
2
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +09303#include "libpldm/instance-id.h"
4
5#include <phosphor-logging/lg2.hpp>
6
7#include <cerrno>
Andrew Jefferyda4b13c2023-04-28 12:56:20 +09308#include <cstdint>
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +09309#include <exception>
10#include <string>
11#include <system_error>
12
13PHOSPHOR_LOG2_USING;
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060014
15namespace pldm
16{
17
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060018/** @class InstanceId
19 * @brief Implementation of PLDM instance id as per DSP0240 v1.0.0
20 */
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093021class InstanceIdDb
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060022{
23 public:
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093024 InstanceIdDb()
25 {
26 int rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
27 if (rc)
28 {
29 throw std::system_category().default_error_condition(rc);
30 }
31 }
32
33 /** @brief Constructor
34 *
35 * @param[in] path - instance ID database path
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060036 */
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093037 InstanceIdDb(const std::string& path)
38 {
39 int rc = pldm_instance_db_init(&pldmInstanceIdDb, path.c_str());
40 if (rc)
41 {
42 throw std::system_category().default_error_condition(rc);
43 }
44 }
45
46 ~InstanceIdDb()
47 {
48 int rc = pldm_instance_db_destroy(pldmInstanceIdDb);
49 if (rc)
50 {
51 error("pldm_instance_db_destroy failed, rc= {RC}", "RC", rc);
52 }
53 }
54
55 /** @brief Allocate an instance ID for the given terminus
56 * @param[in] tid - the terminus ID the instance ID is associated with
57 * @return - PLDM instance id or -EAGAIN if there are no available instance
58 * IDs
59 */
60 uint8_t next(uint8_t tid)
61 {
62 uint8_t id;
63 int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);
64
65 if (rc == -EAGAIN)
66 {
67 throw std::runtime_error("No free instance ids");
68 }
69
70 if (rc)
71 {
72 throw std::system_category().default_error_condition(rc);
73 }
74
75 return id;
76 }
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060077
78 /** @brief Mark an instance id as unused
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093079 * @param[in] tid - the terminus ID the instance ID is associated with
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060080 * @param[in] instanceId - PLDM instance id to be freed
81 */
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093082 void free(uint8_t tid, uint8_t instanceId)
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060083 {
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093084 int rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceId);
85 if (rc == -EINVAL)
86 {
Rashmica Guptaf4117422023-05-16 09:46:58 +100087 throw std::runtime_error(
88 "Instance ID " + std::to_string(instanceId) + " for TID " +
89 std::to_string(tid) + " was not previously allocated");
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093090 }
91 if (rc)
92 {
93 throw std::system_category().default_error_condition(rc);
94 }
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060095 }
96
97 private:
Rashmica Guptaf4117422023-05-16 09:46:58 +100098 pldm_instance_db* pldmInstanceIdDb = nullptr;
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060099};
100
101} // namespace pldm