blob: 5de0963a2e444865c687b97e932ea11710cb18ce [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
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +09305#include <cerrno>
Andrew Jefferyda4b13c2023-04-28 12:56:20 +09306#include <cstdint>
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +09307#include <exception>
8#include <string>
9#include <system_error>
10
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060011namespace pldm
12{
13
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060014/** @class InstanceId
15 * @brief Implementation of PLDM instance id as per DSP0240 v1.0.0
16 */
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093017class InstanceIdDb
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060018{
19 public:
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093020 InstanceIdDb()
21 {
22 int rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
23 if (rc)
24 {
25 throw std::system_category().default_error_condition(rc);
26 }
27 }
28
29 /** @brief Constructor
30 *
31 * @param[in] path - instance ID database path
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060032 */
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093033 InstanceIdDb(const std::string& path)
34 {
35 int rc = pldm_instance_db_init(&pldmInstanceIdDb, path.c_str());
36 if (rc)
37 {
38 throw std::system_category().default_error_condition(rc);
39 }
40 }
41
42 ~InstanceIdDb()
43 {
Andrew Jeffery68a525e2023-10-18 10:09:33 +103044 /*
45 * Abandon error-reporting. We shouldn't throw an exception from the
46 * destructor, and the class has multiple consumers using incompatible
47 * logging strategies.
48 *
49 * Broadly, it should be possible to use strace to investigate.
50 */
51 pldm_instance_db_destroy(pldmInstanceIdDb);
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093052 }
53
54 /** @brief Allocate an instance ID for the given terminus
55 * @param[in] tid - the terminus ID the instance ID is associated with
56 * @return - PLDM instance id or -EAGAIN if there are no available instance
57 * IDs
58 */
59 uint8_t next(uint8_t tid)
60 {
61 uint8_t id;
62 int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);
63
64 if (rc == -EAGAIN)
65 {
66 throw std::runtime_error("No free instance ids");
67 }
68
69 if (rc)
70 {
71 throw std::system_category().default_error_condition(rc);
72 }
73
74 return id;
75 }
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060076
77 /** @brief Mark an instance id as unused
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093078 * @param[in] tid - the terminus ID the instance ID is associated with
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060079 * @param[in] instanceId - PLDM instance id to be freed
80 */
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093081 void free(uint8_t tid, uint8_t instanceId)
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060082 {
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093083 int rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceId);
84 if (rc == -EINVAL)
85 {
Rashmica Guptaf4117422023-05-16 09:46:58 +100086 throw std::runtime_error(
87 "Instance ID " + std::to_string(instanceId) + " for TID " +
88 std::to_string(tid) + " was not previously allocated");
Andrew Jeffery7c1dc7e2023-04-28 14:52:16 +093089 }
90 if (rc)
91 {
92 throw std::system_category().default_error_condition(rc);
93 }
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060094 }
95
96 private:
Rashmica Guptaf4117422023-05-16 09:46:58 +100097 pldm_instance_db* pldmInstanceIdDb = nullptr;
Deepak Kodihalli4de4d002019-11-11 02:41:43 -060098};
99
100} // namespace pldm