Files
salmanoff/senseApis/livoxGen1/livoxGen1.cpp
T
hayodea 6eb6fa1eb0 Livox: Add new loadable libs for Protocolv1 and gen1 lidars
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.
2025-09-06 22:46:03 -04:00

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