#include #include #include #include #include #include #include #include #include #include namespace smo { namespace sense_api { // Salmanoff hooks, obtained from SMO_GET_SENSE_API_DESC_FN_NAME(). static const SmoCallbacks* smoHooksPtr = nullptr; static SmoThreadingModelDesc smoThreadingModelDesc; // LivoxProto1 library state struct LivoxProto1DllState { LivoxProto1DllState() : dlopenHandle(nullptr, DlCloser), livoxProto1_main(nullptr), livoxProto1_exit(nullptr) {} static void DlCloser(void* handle) { if (handle) { dlclose(handle); } } std::unique_ptr dlopenHandle; livoxProto1_mainFn *livoxProto1_main; livoxProto1_exitFn *livoxProto1_exit; }; static LivoxProto1DllState livoxProto1; // Callback function declarations extern "C" int livoxGen1_initializeInd(void); extern "C" int livoxGen1_finalizeInd(void); extern "C" int livoxGen1_attachDeviceReq( const std::shared_ptr& desc); extern "C" int livoxGen1_detachDeviceReq( const std::shared_ptr& desc); // Sense API descriptor static const SenseApiDesc livoxGen1ApiDesc = { .name = "livoxGen1", .exportedImplexorApis = { {.name = "pointCloudCoords"}, {.name = "pointCloudIntensity"}, {.name = "gyro"}, {.name = "accel"} }, .sal_mgmt_libOps = { .initializeInd = livoxGen1_initializeInd, .finalizeInd = livoxGen1_finalizeInd, .attachDeviceReq = livoxGen1_attachDeviceReq, .detachDeviceReq = livoxGen1_detachDeviceReq } }; // Callback function implementations extern "C" int livoxGen1_initializeInd(void) { if (!smoHooksPtr) { throw std::runtime_error(std::string(__func__) + ": SMO hooks " "pointers not filled in."); } // Load LivoxProto1 library auto libPath = smoHooksPtr->searchForLibInSmoSearchPaths( "liblivoxProto1.so"); livoxProto1.dlopenHandle.reset(dlopen( libPath.value_or("liblivoxProto1.so").c_str(), RTLD_LAZY)); if (!livoxProto1.dlopenHandle) { throw std::runtime_error( std::string(__func__) + ": Failed to load LivoxProto1 library: " + (dlerror() ? dlerror() : "unknown error")); } // Get LivoxProto1 library functions livoxProto1.livoxProto1_main = reinterpret_cast( dlsym(livoxProto1.dlopenHandle.get(), "livoxProto1_main")); livoxProto1.livoxProto1_exit = reinterpret_cast( dlsym(livoxProto1.dlopenHandle.get(), "livoxProto1_exit")); if (!livoxProto1.livoxProto1_main || !livoxProto1.livoxProto1_exit) { throw std::runtime_error( std::string(__func__) + ": Failed to get LivoxProto1 library functions"); } // Call LivoxProto1 library main function livoxProto1.livoxProto1_main(smoThreadingModelDesc.componentThread); return 0; // Success } extern "C" int livoxGen1_finalizeInd(void) { // TODO: Implement finalization logic if (livoxProto1.livoxProto1_exit) { livoxProto1.livoxProto1_exit(); } if (livoxProto1.dlopenHandle) { dlclose(livoxProto1.dlopenHandle.get()); livoxProto1.dlopenHandle.reset(); } livoxProto1 = LivoxProto1DllState(); return 0; // Success } extern "C" int livoxGen1_attachDeviceReq( const std::shared_ptr& desc ) { // TODO: Implement device attachment logic (void)desc; // Suppress unused parameter warning return 0; // Success } extern "C" int livoxGen1_detachDeviceReq( const std::shared_ptr& desc ) { // TODO: Implement device detachment logic (void)desc; // Suppress unused parameter warning return 0; // Success } // Exported function extern "C" smo::sense_api::SMO_GET_SENSE_API_DESC_FN_TYPEDEF SMO_GET_SENSE_API_DESC_FN_NAME; const smo::sense_api::SenseApiDesc& SMO_GET_SENSE_API_DESC_FN_NAME( const smo::sense_api::SmoCallbacks& callbacks, const smo::sense_api::SmoThreadingModelDesc& threadingModel) { smoHooksPtr = &callbacks; smoThreadingModelDesc = threadingModel; return livoxGen1ApiDesc; } } // namespace sense_api } // namespace smo