xref: /openbmc/pldm/common/instance_id.hpp (revision 4668f5c8)
12abbce76SAndrew Jeffery #pragma once
22abbce76SAndrew Jeffery 
3*4668f5c8SAndrew Jeffery #include <libpldm/instance-id.h>
42abbce76SAndrew Jeffery 
52abbce76SAndrew Jeffery #include <cerrno>
62abbce76SAndrew Jeffery #include <cstdint>
72abbce76SAndrew Jeffery #include <exception>
82abbce76SAndrew Jeffery #include <string>
92abbce76SAndrew Jeffery #include <system_error>
102abbce76SAndrew Jeffery 
112abbce76SAndrew Jeffery namespace pldm
122abbce76SAndrew Jeffery {
132abbce76SAndrew Jeffery 
142abbce76SAndrew Jeffery /** @class InstanceId
152abbce76SAndrew Jeffery  *  @brief Implementation of PLDM instance id as per DSP0240 v1.0.0
162abbce76SAndrew Jeffery  */
172abbce76SAndrew Jeffery class InstanceIdDb
182abbce76SAndrew Jeffery {
192abbce76SAndrew Jeffery   public:
InstanceIdDb()202abbce76SAndrew Jeffery     InstanceIdDb()
212abbce76SAndrew Jeffery     {
222abbce76SAndrew Jeffery         int rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
232abbce76SAndrew Jeffery         if (rc)
242abbce76SAndrew Jeffery         {
252abbce76SAndrew Jeffery             throw std::system_category().default_error_condition(rc);
262abbce76SAndrew Jeffery         }
272abbce76SAndrew Jeffery     }
282abbce76SAndrew Jeffery 
292abbce76SAndrew Jeffery     /** @brief Constructor
302abbce76SAndrew Jeffery      *
312abbce76SAndrew Jeffery      *  @param[in] path - instance ID database path
322abbce76SAndrew Jeffery      */
InstanceIdDb(const std::string & path)332abbce76SAndrew Jeffery     InstanceIdDb(const std::string& path)
342abbce76SAndrew Jeffery     {
352abbce76SAndrew Jeffery         int rc = pldm_instance_db_init(&pldmInstanceIdDb, path.c_str());
362abbce76SAndrew Jeffery         if (rc)
372abbce76SAndrew Jeffery         {
382abbce76SAndrew Jeffery             throw std::system_category().default_error_condition(rc);
392abbce76SAndrew Jeffery         }
402abbce76SAndrew Jeffery     }
412abbce76SAndrew Jeffery 
~InstanceIdDb()422abbce76SAndrew Jeffery     ~InstanceIdDb()
432abbce76SAndrew Jeffery     {
442abbce76SAndrew Jeffery         /*
452abbce76SAndrew Jeffery          * Abandon error-reporting. We shouldn't throw an exception from the
462abbce76SAndrew Jeffery          * destructor, and the class has multiple consumers using incompatible
472abbce76SAndrew Jeffery          * logging strategies.
482abbce76SAndrew Jeffery          *
492abbce76SAndrew Jeffery          * Broadly, it should be possible to use strace to investigate.
502abbce76SAndrew Jeffery          */
512abbce76SAndrew Jeffery         pldm_instance_db_destroy(pldmInstanceIdDb);
522abbce76SAndrew Jeffery     }
532abbce76SAndrew Jeffery 
542abbce76SAndrew Jeffery     /** @brief Allocate an instance ID for the given terminus
552abbce76SAndrew Jeffery      *  @param[in] tid - the terminus ID the instance ID is associated with
562abbce76SAndrew Jeffery      *  @return - PLDM instance id or -EAGAIN if there are no available instance
572abbce76SAndrew Jeffery      *            IDs
582abbce76SAndrew Jeffery      */
next(uint8_t tid)592abbce76SAndrew Jeffery     uint8_t next(uint8_t tid)
602abbce76SAndrew Jeffery     {
612abbce76SAndrew Jeffery         uint8_t id;
622abbce76SAndrew Jeffery         int rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &id);
632abbce76SAndrew Jeffery 
642abbce76SAndrew Jeffery         if (rc == -EAGAIN)
652abbce76SAndrew Jeffery         {
662abbce76SAndrew Jeffery             throw std::runtime_error("No free instance ids");
672abbce76SAndrew Jeffery         }
682abbce76SAndrew Jeffery 
692abbce76SAndrew Jeffery         if (rc)
702abbce76SAndrew Jeffery         {
712abbce76SAndrew Jeffery             throw std::system_category().default_error_condition(rc);
722abbce76SAndrew Jeffery         }
732abbce76SAndrew Jeffery 
742abbce76SAndrew Jeffery         return id;
752abbce76SAndrew Jeffery     }
762abbce76SAndrew Jeffery 
772abbce76SAndrew Jeffery     /** @brief Mark an instance id as unused
782abbce76SAndrew Jeffery      *  @param[in] tid - the terminus ID the instance ID is associated with
792abbce76SAndrew Jeffery      *  @param[in] instanceId - PLDM instance id to be freed
802abbce76SAndrew Jeffery      */
free(uint8_t tid,uint8_t instanceId)812abbce76SAndrew Jeffery     void free(uint8_t tid, uint8_t instanceId)
822abbce76SAndrew Jeffery     {
832abbce76SAndrew Jeffery         int rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceId);
842abbce76SAndrew Jeffery         if (rc == -EINVAL)
852abbce76SAndrew Jeffery         {
862abbce76SAndrew Jeffery             throw std::runtime_error(
872abbce76SAndrew Jeffery                 "Instance ID " + std::to_string(instanceId) + " for TID " +
882abbce76SAndrew Jeffery                 std::to_string(tid) + " was not previously allocated");
892abbce76SAndrew Jeffery         }
902abbce76SAndrew Jeffery         if (rc)
912abbce76SAndrew Jeffery         {
922abbce76SAndrew Jeffery             throw std::system_category().default_error_condition(rc);
932abbce76SAndrew Jeffery         }
942abbce76SAndrew Jeffery     }
952abbce76SAndrew Jeffery 
962abbce76SAndrew Jeffery   private:
972abbce76SAndrew Jeffery     pldm_instance_db* pldmInstanceIdDb = nullptr;
982abbce76SAndrew Jeffery };
992abbce76SAndrew Jeffery 
1002abbce76SAndrew Jeffery } // namespace pldm
101