6eb6fa1eb0
We've added two new libs: * commonLibs/livoxProto1 * senseApis/livoxGen1 They currently get to the point of detecting my Livox Avia on the network over UDP. This was really easy to get done in one night using boost::asio and Cursor, honestly.
160 lines
4.0 KiB
C++
160 lines
4.0 KiB
C++
#include <iostream>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <map>
|
|
#include <functional>
|
|
#include <dlfcn.h>
|
|
#include <user/senseApiDesc.h>
|
|
#include <user/deviceAttachmentSpec.h>
|
|
#include <livoxProto1/livoxProto1.h>
|
|
|
|
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<void, void(*)(void*)> 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<smo::device::DeviceAttachmentSpec>& desc);
|
|
extern "C" int livoxGen1_detachDeviceReq(
|
|
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& 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<livoxProto1_mainFn *>(
|
|
dlsym(livoxProto1.dlopenHandle.get(), "livoxProto1_main"));
|
|
livoxProto1.livoxProto1_exit = reinterpret_cast<livoxProto1_exitFn *>(
|
|
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<smo::device::DeviceAttachmentSpec>& desc
|
|
)
|
|
{
|
|
// TODO: Implement device attachment logic
|
|
(void)desc; // Suppress unused parameter warning
|
|
return 0; // Success
|
|
}
|
|
|
|
extern "C" int livoxGen1_detachDeviceReq(
|
|
const std::shared_ptr<smo::device::DeviceAttachmentSpec>& 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
|