Files
salmanoff/hcore/include/senseApis/senseApiLib.h
T
hayodea 53583e5735 SenseApiLib, SenseApiDesc improvements, new Sense API Mgmt Lib Ops role
SenseApiDesc:
* Use a number count for num exported implexor APIs instead of
  NULL-terminated list.
* Add sanity checker functions for structs.

SenseApiLib:
* Invoke the new sanity checkers on new Lib objects.
* SenseApiDesc is now a member object instead of being
  pointed to.

SenseApiManager:
* loadSenseApiLib now calls the SenseApiDesc getter function.
* loadSenseApiLib now fills out the SenseApiLib class object.

New Sense API Mgmt Sub-API:

This sub-api (metalanguage, some might call it) is used to initialize
the lib's connection to the provider. After this call, the lib should
be ready to attach new devices to its provider on behalf of Hk.
2025-01-09 06:03:43 -04:00

120 lines
3.6 KiB
C++

#ifndef SENSE_API_PROVIDER_DESC_H
#define SENSE_API_PROVIDER_DESC_H
#include <string>
#include <memory>
#include <vector>
#include <dlfcn.h>
#include <functional>
#include <user/senseApiDesc.h>
namespace hk {
namespace sense_api {
/* C++ version of the C struct above, which Harikoff uses to manage the
* lib and connect implexors to it.
*/
class SenseApiDesc
{
public:
class ExportedImplexorApiDesc
{
public:
ExportedImplexorApiDesc(const CExportedImplexorApiDesc& cDesc)
// The caller should sanity check before calling this constructor.
: name(cDesc.name)
{}
const std::string name;
};
public:
SenseApiDesc() = default;
SenseApiDesc(const CSenseApiDesc& cDesc)
// The caller should sanity check before calling this constructor.
: name(cDesc.name)
{
for (uint32_t i = 0; i < cDesc.numExportedImplexorApis; ++i)
{
if (!CExportedImplexorApiDesc_sanityCheck(
&cDesc.exportedImplexorApis[i]))
{
throw std::runtime_error(
"Sanity check failed for exported implexor API descriptor");
}
exportedImplexorApis.push_back(
ExportedImplexorApiDesc(cDesc.exportedImplexorApis[i]));
}
}
std::string name;
// These are the implexors whose APIs this lib exports.
std::vector<ExportedImplexorApiDesc> exportedImplexorApis;
};
class SenseApiLib
{
public:
SenseApiLib(
const std::string& path, void *_dlopen_handle, getSenseApiDescFn *descFn)
: libraryPath(path),
dlopen_handle(
_dlopen_handle, reinterpret_cast<void(*)(void*)>(&dlclose)),
HK_GET_SENSE_API_DESC_FN_NAME(descFn)
{}
void setSenseApiDesc(const CSenseApiDesc* desc)
{
if (!CSenseApiDesc_sanityCheck(desc) ||
!Csal_libMgmtOps_sanityCheck(desc->sal_libMgmtOps))
{
throw std::runtime_error(
std::string(__func__) + ": Sanity check failed for sense API "
"descriptor in library '" + libraryPath + "'");
}
for (uint32_t i = 0; i < desc->numExportedImplexorApis; ++i)
{
if (!CExportedImplexorApiDesc_sanityCheck(
&desc->exportedImplexorApis[i]))
{
throw std::runtime_error(
std::string(__func__) + ": Sanity check failed for "
"exported implexor API descriptor in library '"
+ libraryPath + "'");
}
}
new (&senseApiDesc) SenseApiDesc(*desc); // Placement new
}
public:
std::string libraryPath;
std::unique_ptr<void, void(*)(void*)> dlopen_handle;
/* UNIMPLEMENTED: API-specific cmdline options. These affect this specific
* sense api lib's behaviour globally.
*/
std::vector<std::string> options;
/**
* @brief Every sense API lib is required to provide a function that returns
* a CSenseApiDesc struct. This struct states which API the lib uses to
* connect Harikoff to the sense provider it supports.
*
* This getter function should be visible to dlsym() so that Harikoff can
* find it in the lib after loading it, and call it.
*/
std::function<getSenseApiDescFn> HK_GET_SENSE_API_DESC_FN_NAME;
/**
* @brief Harikoff will call the `HK_GET_SENSE_API_DESC_FN_NAME` getter
* function and use the data it provides in order to fill out this
* descriptor.
*/
SenseApiDesc senseApiDesc;
};
} // namespace sense_api
} // namespace hk
#endif // SENSE_API_PROVIDER_DESC_H