#ifndef __USER_SENSE_API_LIB_H__ #define __USER_SENSE_API_LIB_H__ #include #include #include namespace hk { namespace sense_api { /* Exported by all sense API Libraries to tell Harikoff what API the lib uses * to connect to providers; and also to state which implexor APIs it exports. */ typedef int (sal_mho_initializeRdyFn)(void); typedef int (sal_mho_finalizeRdyFn)(void); typedef int (sal_mho_attachDeviceAckFn)(const device::SenseDeviceSpec *const desc); typedef int (sal_mho_detachDeviceAckFn)(const device::SenseDeviceSpec *const desc); struct Sal_Mgmt_HkOps { // Lib calls this function to notify Harikoff that it's done initializing. sal_mho_initializeRdyFn *initializeRdy; // Lib calls this function to notify Harikoff that it's done finalizing. sal_mho_finalizeRdyFn *finalizeRdy; // Lib calls this to notify Harikoff that it's done attaching a device. sal_mho_attachDeviceAckFn *attachDeviceAck; // Lib calls this to notify Harikoff that it's done detaching a device. sal_mho_detachDeviceAckFn *detachDeviceAck; }; typedef int (sal_mlo_initializeIndFn)(void); typedef int (sal_mlo_finalizeIndFn)(void); typedef int (sal_mlo_attachDeviceReqFn)(const device::SenseDeviceSpec *const desc); typedef int (sal_mlo_detachDeviceReqFn)(const device::SenseDeviceSpec *const desc); struct Sal_Mgmt_LibOps { /* When Harikoff loads a sense API lib, it calls this function to initialize * the lib. When this returns, the lib should be ready to attach devices. */ sal_mlo_initializeIndFn *initializeInd; /* Harikoff calls this to finalize the lib and free its internal * resources. When this returns, the lib should be ready to be unloaded. */ sal_mlo_finalizeIndFn *finalizeInd; /* Harikoff calls this to attach a device to the lib. When it returns, the * device should be attached and ready to be implexed. */ sal_mlo_attachDeviceReqFn *attachDeviceReq; // When this returns, the device should be detached. sal_mlo_detachDeviceReqFn *detachDeviceReq; static bool sanityCheck(const Sal_Mgmt_LibOps &ops) { if (!ops.initializeInd || !ops.finalizeInd || !ops.attachDeviceReq || !ops.detachDeviceReq) { return false; } return true; } }; /* 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 std::string name) // The caller should sanity check before calling this constructor. : name(name) {} static bool sanityCheck(const ExportedImplexorApiDesc &desc) { if (desc.name.empty()) { return false; } return true; } public: std::string name; }; public: SenseApiDesc() = default; std::string stringify() const { std::string result = "Name: " + name + "\n"; result += "Exported Implexor APIs:\n"; for (const auto& api : exportedImplexorApis) { result += " - " + api.name + "\n"; } return result; } static bool sanityCheck(const SenseApiDesc &desc) { if (desc.name.empty() || desc.exportedImplexorApis.empty()) { return false; } for (const auto& api : desc.exportedImplexorApis) { if (!ExportedImplexorApiDesc::sanityCheck(api)) { return false; } } return Sal_Mgmt_LibOps::sanityCheck(desc.sal_mgmt_libOps); } std::string name; // These are the implexors whose APIs this lib exports. std::vector exportedImplexorApis; Sal_Mgmt_LibOps sal_mgmt_libOps; }; #define HK_GET_SENSE_API_DESC_FN_NAME getSenseApiDesc #define HK_GET_SENSE_API_DESC_FN_NAME_STR \ HK_QUOTE(HK_GET_SENSE_API_DESC_FN_NAME) typedef const SenseApiDesc &(getSenseApiDescFn)(void); } // namespace sense_api } // namespace hk #endif // __USER_SENSE_API_LIB_H__