Initial commit: Livox SDK2 source (excluding build artifacts)

This commit is contained in:
gardentech
2026-08-26 01:38:14 +09:00
commit 34a9a52cd4
221 changed files with 54102 additions and 0 deletions
+249
View File
@@ -0,0 +1,249 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_COMMAND_CALLBACK_H
#define LIVOX_COMMAND_CALLBACK_H
#include <functional>
#include <memory>
#include "livox_lidar_api.h"
namespace livox {
namespace lidar {
class CommandCallback {
public:
virtual ~CommandCallback() {}
virtual void operator()(livox_status status,uint32_t handle, void *data) = 0;
};
template <class T, class ResponseType>
class MemberFunctionCallback : public CommandCallback {
public:
typedef void (T::*MemFn)(livox_status status, uint32_t handle, ResponseType *data);
MemberFunctionCallback(T *cls, MemFn func) : this_(cls), func_(func) {}
void operator()(livox_status status, uint32_t handle, void *data) {
if (this_) {
(this_->*func_)(status, handle, static_cast<ResponseType *>(data));
}
}
private:
T *this_;
MemFn func_;
};
template <class T>
class MemberFunctionCallback<T, uint8_t> : public CommandCallback {
public:
typedef void (T::*MemFn)(livox_status status, uint32_t handle, uint8_t response);
MemberFunctionCallback(T *cls, MemFn func) : this_(cls), func_(func) {}
void operator()(livox_status status, uint32_t handle, void *data) {
if (this_) {
if (data == NULL) {
(this_->*func_)(status, handle, 0);
} else {
(this_->*func_)(status, handle, static_cast<uint8_t>(reinterpret_cast<uintptr_t>(data)));
}
}
}
private:
T *this_;
MemFn func_;
};
template <class T, class ResponseType>
std::shared_ptr<CommandCallback> MakeCommandCallback(T *cls,
typename MemberFunctionCallback<T, ResponseType>::MemFn func) {
std::shared_ptr<CommandCallback> cb(new MemberFunctionCallback<T, ResponseType>(cls, func));
return cb;
}
template <class T>
class FunctionStatusCallback : public CommandCallback {
public:
typedef void (*Fn)(livox_status status, uint32_t handle, T *data, void *client_data);
public:
FunctionStatusCallback(Fn func, void *client_data) : func_(func), client_data_(client_data) {}
void operator()(livox_status status, uint32_t handle, void *data) {
if (func_) {
(*func_)(status, handle, static_cast<T *>(data), client_data_);
}
}
private:
Fn func_;
void *client_data_;
};
template <>
class FunctionStatusCallback<uint8_t> : public CommandCallback {
public:
typedef void (*Fn)(livox_status status, uint32_t handle, uint8_t data, void *client_data);
public:
FunctionStatusCallback(Fn func, void *client_data) : func_(func), client_data_(client_data) {}
void operator()(livox_status status, uint32_t handle, void *data) {
if (func_) {
if (data == NULL) {
(*func_)(status, handle, 0, client_data_);
} else {
(*func_)(status, handle, *(uint8_t *)data, client_data_);
}
}
}
private:
Fn func_;
void *client_data_;
};
template <class T>
std::shared_ptr<CommandCallback> MakeCommandCallback(typename FunctionStatusCallback<T>::Fn func, void *client_data) {
std::shared_ptr<CommandCallback> cb(new FunctionStatusCallback<T>(func, client_data));
return cb;
}
template <class T>
class MessageCallback : public CommandCallback {
public:
typedef void (*Fn)(livox_status status, uint32_t handle, T *data);
public:
MessageCallback(const Fn &func) : func_(func) {}
void operator()(livox_status status, uint32_t handle, void *data) {
if (func_) {
(*func_)(status, handle, static_cast<T *>(data));
}
}
private:
Fn func_;
};
template <class ResponseType>
class BoostFunctionMessageCallback : public CommandCallback {
public:
typedef std::function<void(livox_status, uint8_t, ResponseType *)> Fn;
public:
BoostFunctionMessageCallback(const Fn &func) : func_(func) {}
void operator()(livox_status status, uint32_t handle, void *data) {
if (func_) {
func_(status, handle, static_cast<ResponseType *>(data));
}
}
private:
Fn func_;
};
template <class T>
std::shared_ptr<CommandCallback> MakeMessageCallback(typename MessageCallback<T>::Fn func) {
std::shared_ptr<CommandCallback> cb(new MessageCallback<T>(func));
return cb;
}
template <class T>
std::shared_ptr<CommandCallback> MakeMessageCallback(typename BoostFunctionMessageCallback<T>::Fn func) {
std::shared_ptr<CommandCallback> cb(new BoostFunctionMessageCallback<T>(func));
return cb;
}
template <class T, class ResponseType>
class MemberMessageCallback : public CommandCallback {
public:
typedef void (T::*MemFn)(livox_status status, uint32_t handle, ResponseType *data);
MemberMessageCallback(T *cls, MemFn func) : this_(cls), func_(func) {}
void operator()(livox_status status,uint32_t handle, void *data) {
if (this_) {
(this_->*func_)(status, handle, (ResponseType *)data);
}
}
private:
T *this_;
MemFn func_;
};
template <class T, class ResponseType>
std::shared_ptr<CommandCallback> MakeMemberMessageCallback(
T *_this,
typename MemberMessageCallback<T, ResponseType>::MemFn func) {
std::shared_ptr<CommandCallback> cb(new MemberMessageCallback<T, ResponseType>(_this, func));
return cb;
}
template <class ResponseType>
class BoostFunctionCallback : public CommandCallback {
public:
typedef std::function<void(uint8_t, uint8_t, ResponseType *)> Fn;
BoostFunctionCallback(const Fn &func) : func_(func) {}
void operator()(livox_status status,uint32_t handle, void *data) {
if (func_) {
if (data == NULL) {
func_(status, handle, NULL);
} else {
func_(status, handle, (ResponseType *)data);
}
}
}
private:
Fn func_;
};
template <>
class BoostFunctionCallback<uint8_t> : public CommandCallback {
public:
typedef std::function<void(uint8_t, uint8_t, uint8_t)> Fn;
BoostFunctionCallback(const Fn &func) : func_(func) {}
void operator()(livox_status status,uint32_t handle, void *data) {
if (func_) {
if (data == NULL) {
func_(status, handle, 0);
} else {
func_(status, handle, static_cast<uint8_t>(reinterpret_cast<uintptr_t>(data)));
}
}
}
private:
Fn func_;
};
template <class ResponseType>
std::shared_ptr<CommandCallback> MakeCommandCallback(const typename BoostFunctionCallback<ResponseType>::Fn &func) {
std::shared_ptr<CommandCallback> cb(new BoostFunctionCallback<ResponseType>(func));
return cb;
}
} // namespace lidar
} // namespace livox
#endif // LIVOX_COMMAND_CALLBACK_H
+131
View File
@@ -0,0 +1,131 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "io_loop.h"
#include <functional>
#include <mutex>
#include <iostream>
#include <algorithm>
#include "logging.h"
using std::lock_guard;
using std::mutex;
using std::vector;
using std::chrono::steady_clock;
namespace livox {
namespace lidar {
bool IOLoop::Init() {
auto multiple_io = MultipleIOFactory::CreateMultipleIO();
if (!multiple_io) {
LOG_ERROR("Creat Multiple IO Failed!");
return false;
}
multiple_io_base_ = std::move(multiple_io);
if (!multiple_io_base_->PollCreate(OPEN_MAX_POLL)) {
LOG_ERROR("Poll Create Failed!");
return false;
}
return true;
}
void IOLoop::Uninit() {
multiple_io_base_->PollDestroy();
}
void IOLoop::AddDelegate(socket_t sock, IOLoop::IOLoopDelegate *delegate, void *data) {
PostTask(std::bind(&IOLoop::AddDelegateAsync, this, sock, delegate, data));
}
void IOLoop::RemoveDelegate(socket_t sock, IOLoopDelegate *) {
PostTask(std::bind(&IOLoop::RemoveDelegateAsync, this, sock));
}
void IOLoop::Loop() {
multiple_io_base_->Poll(POLL_TIMEOUT);
vector<IOLoopTask> tasks;
{
lock_guard<mutex> lock(mutex_);
tasks.swap(pending_tasks_);
}
for (auto &task : tasks) {
task();
}
}
bool IOLoop::Wakeup() {
if (multiple_io_base_) {
multiple_io_base_->PollWakeUp();
}
return true;
}
void IOLoop::PostTask(const IOLoopTask &task) {
{
lock_guard<mutex> lock(mutex_);
pending_tasks_.push_back(task);
}
Wakeup();
}
void IOLoop::AddDelegateAsync(socket_t sock, IOLoop::IOLoopDelegate *delegate, void *data) {
PollFd pollfd = {};
pollfd.fd = sock;
pollfd.event = READBLE_EVENT;
pollfd.event_callback = [=](FdEvent event) {
if (event & READBLE_EVENT) {
if (delegate) {
delegate->OnData(sock, data);
}
}
};
if (enable_timer_) {
pollfd.timer_callback = [=](TimePoint t) {
if (delegate) {
delegate->OnTimer(t);
}
};
}
if (enable_wake_) {
pollfd.wake_callback = [=]() {
if (delegate) {
delegate->OnWake();
}
};
}
multiple_io_base_->PollSetAdd(pollfd);
}
void IOLoop::RemoveDelegateAsync(socket_t sock) {
PollFd pollfd = {};
pollfd.fd = sock;
pollfd.event = READBLE_EVENT;
multiple_io_base_->PollSetRemove(pollfd);
}
} // namespace lidar
} // namespace livox
+92
View File
@@ -0,0 +1,92 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_IO_LOOP_H_
#define LIVOX_IO_LOOP_H_
#include <functional>
#include <mutex>
#include <unordered_map>
#include <utility>
#include <vector>
#include <algorithm>
#include "command_callback.h"
#include "noncopyable.h"
#include "thread_base.h"
#include "multiple_io/multiple_io_base.h"
#include "multiple_io/multiple_io_factory.h"
namespace livox {
namespace lidar {
#define OPEN_MAX_POLL 48
#define POLL_TIMEOUT 50 //ms
typedef int socket_t;
class IOLoop : public noncopyable {
public:
typedef std::function<void(void)> IOLoopTask;
class IOLoopDelegate {
public:
virtual void OnData(socket_t, void *) {}
virtual void OnTimer(std::chrono::steady_clock::time_point) {}
virtual void OnWake() {}
};
public:
explicit IOLoop(bool enable_timer = true, bool enable_wake = true)
: enable_timer_(enable_timer), enable_wake_(enable_wake){};
bool Init();
void Uninit();
void AddDelegate(socket_t sock, IOLoopDelegate *delegate, void *data = NULL);
void RemoveDelegate(socket_t sock, IOLoopDelegate *delegate);
void Loop();
bool Wakeup();
void PostTask(const IOLoopTask &task);
private:
void AddDelegateAsync(socket_t sock, IOLoopDelegate *delegate, void *data);
void RemoveDelegateAsync(socket_t sock);
private:
std::mutex mutex_;
bool enable_timer_;
bool enable_wake_;
std::vector<IOLoopTask> pending_tasks_;
std::unique_ptr<MultipleIOBase> multiple_io_base_;
};
} // namespace lidar
} // namespace livox
#endif // LIVOX_IO_LOOP_H_
+56
View File
@@ -0,0 +1,56 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "io_thread.h"
namespace livox {
namespace lidar {
IOThread::~IOThread() {
Join();
Uninit();
}
void IOThread::ThreadFunc() {
if (!loop_) {
return;
}
while (!IsQuit()) {
loop_->Loop();
}
}
bool IOThread::Init(bool enable_timer, bool enable_wake) {
loop_ = std::make_shared<IOLoop>(enable_timer, enable_wake);
return loop_->Init();
}
void IOThread::Uninit() {
if (loop_) {
loop_->Uninit();
}
}
} // namespace lidar
} // namespace livox
+49
View File
@@ -0,0 +1,49 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_IO_THREAD_H_
#define LIVOX_IO_THREAD_H_
#include <memory>
#include "io_loop.h"
#include "thread_base.h"
namespace livox {
namespace lidar {
class IOThread : public ThreadBase {
public:
IOThread() : loop_(nullptr) {}
virtual ~IOThread();
bool Init(bool enable_timer = true, bool enable_wake = true);
std::weak_ptr<IOLoop> GetLoop() { return loop_; }
void ThreadFunc();
private:
void Uninit();
std::shared_ptr<IOLoop> loop_;
};
} // namespace lidar
} // namespace livox
#endif // LIVOX_IO_THREAD_H_
+59
View File
@@ -0,0 +1,59 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "logging.h"
std::shared_ptr<spdlog::logger> logger = NULL;
bool is_save_log_file = false;
bool is_console_log_enable = true;
void InitLogger() {
if (spdlog::get("console") != nullptr) {
logger = spdlog::get("console");
return;
}
std::vector<spdlog::sink_ptr> sinkList;
if (is_console_log_enable) {
auto consoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
consoleSink->set_level(spdlog::level::debug);
sinkList.push_back(consoleSink);
}
if (is_save_log_file) {
auto rotateSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("livox_log.txt", 1024 * 1024 * 5, 2);
rotateSink->set_level(spdlog::level::debug);
sinkList.push_back(rotateSink);
}
logger = std::make_shared<spdlog::logger>("console", begin(sinkList), end(sinkList));
spdlog::register_logger(logger);
logger->set_level(spdlog::level::debug);
logger->flush_on(spdlog::level::debug);
}
void UninitLogger() {
spdlog::drop_all();
}
+66
View File
@@ -0,0 +1,66 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_LOGGING_H_
#define LIVOX_LOGGING_H_
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"
#ifdef _WIN32
#define __FILENAME__ (strrchr(__FILE__, '\\') ? (strrchr(__FILE__, '\\') + 1):__FILE__)
#else
#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1):__FILE__)
#endif
#ifndef suffix
#define suffix(msg) std::string(msg).append(" [")\
.append(__FILENAME__).append("] [").append(__func__)\
.append("] [").append(std::to_string(__LINE__))\
.append("]").c_str()
#endif
#ifndef SPDLOG_TRACE_ON
#define SPDLOG_TRACE_ON
#endif
#ifndef SPDLOG_DEBUG_ON
#define SPDLOG_DEBUG_ON
#endif
extern std::shared_ptr<spdlog::logger> logger;
extern bool is_save_log_file;
extern bool is_console_log_enable;
void InitLogger();
void UninitLogger();
#define LOG_TRACE(msg, ...) logger->trace(suffix(msg), ##__VA_ARGS__)
#define LOG_DEBUG(msg, ...) logger->debug(suffix(msg), ##__VA_ARGS__)
#define LOG_INFO(msg, ...) logger->info(suffix(msg), ##__VA_ARGS__)
#define LOG_WARN(msg, ...) logger->warn(suffix(msg), ##__VA_ARGS__)
#define LOG_ERROR(msg, ...) logger->error(suffix(msg), ##__VA_ARGS__)
#define LOG_FATAL(msg, ...) logger->critical(suffix(msg), ##__VA_ARGS__)
#endif // LIVOX_LOGGING_H_
@@ -0,0 +1,86 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "multiple_io_base.h"
namespace livox {
namespace lidar {
void MultipleIOBase::CheckTimer() {
TimePoint t = std::chrono::steady_clock::now();
if (t - last_timeout_ > std::chrono::milliseconds(50)) {
last_timeout_ = t;
for (auto & descriptor : descriptors_) {
PollFd pollfd = descriptor.second;
if (pollfd.timer_callback) {
pollfd.timer_callback(t);
}
}
}
}
void MultipleIOBase::WakeUpInit() {
//Initialize wake up pipe
wake_up_pipe_.reset(new WakeUpPipe());
wake_up_pipe_->PipeCreate();
//register wake_fd to multiple io
PollFd wake_fd = {};
wake_fd.fd = wake_up_pipe_->GetPipeOut();
wake_fd.event = READBLE_EVENT;
wake_fd.event_callback = [this](FdEvent event) {
if (event & READBLE_EVENT) {
if (wake_up_pipe_) {
wake_up_pipe_->Drain();
}
for (auto & descriptor : descriptors_) {
PollFd pollfd = descriptor.second;
if (pollfd.wake_callback) {
pollfd.wake_callback();
}
}
}
};
PollSetAdd(wake_fd);
}
void MultipleIOBase::WakeUpUninit() {
PollFd wake_fd = {};
wake_fd.fd = wake_up_pipe_->GetPipeOut();
wake_fd.event = READBLE_EVENT | WRITABLE_EVENT;
PollSetRemove(wake_fd);
if (wake_up_pipe_) {
wake_up_pipe_->PipeDestroy();
wake_up_pipe_ = nullptr;
}
}
void MultipleIOBase::PollWakeUp() {
if (wake_up_pipe_) {
wake_up_pipe_->WakeUp();
}
return;
}
} // namespace lidar
} // namespace livox
@@ -0,0 +1,75 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef MULTIPLE_IO_BASE_H_
#define MULTIPLE_IO_BASE_H_
#include <map>
#include <functional>
#include <chrono>
#include <memory>
#include "base/wake_up/wake_up_pipe.h"
namespace livox {
namespace lidar {
#define NONE_EVENT 0 /* No events registered. */
#define READBLE_EVENT 1 /* when descriptor is readable. */
#define WRITABLE_EVENT 2 /* when descriptor is writeable. */
typedef std::chrono::steady_clock::time_point TimePoint;
typedef int FdEvent;
typedef struct {
int fd; /* File descriptor. */
FdEvent event; /* Read | Write Event to listen. */
std::function<void(FdEvent)> event_callback; /* Read or Write Event Callback. */
std::function<void(TimePoint)> timer_callback; /* Timer Event Callback. */
std::function<void()> wake_callback; /* WakeUp Event Callback. */
} PollFd;
class MultipleIOBase {
public:
MultipleIOBase() = default;
virtual ~MultipleIOBase() = default;
virtual bool PollCreate(int size) = 0;
virtual void PollDestroy() = 0;
virtual bool PollSetAdd(PollFd poll_fd) = 0;
virtual bool PollSetRemove(PollFd poll_fd) = 0;
virtual void Poll(int timeout) = 0;
virtual void PollWakeUp();
protected:
virtual void CheckTimer();
std::map<int, PollFd> descriptors_;
TimePoint last_timeout_ = TimePoint();
virtual void WakeUpInit();
virtual void WakeUpUninit();
std::unique_ptr<WakeUpPipe> wake_up_pipe_;
};
} // namespace lidar
} // namespace livox
#endif // MULTIPLE_IO_BASE_H_
@@ -0,0 +1,109 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "multiple_io_epoll.h"
#ifdef HAVE_EPOLL
namespace livox {
namespace lidar {
int GetEvent (FdEvent event) {
FdEvent rv = 0;
if (event & READBLE_EVENT)
rv |= EPOLLIN;
if (event & WRITABLE_EVENT)
rv |= EPOLLOUT;
return rv;
}
bool MultipleIOEpoll::PollCreate(int size) {
max_poll_size_ = size + 1;
epoll_fd_ = epoll_create(max_poll_size_);
if (epoll_fd_ < 0) {
return false;
}
pollset_.reset(new struct epoll_event[size]);
WakeUpInit();
return true;
}
void MultipleIOEpoll::PollDestroy() {
WakeUpUninit();
if (epoll_fd_ > 0) {
close(epoll_fd_);
epoll_fd_ = -1;
}
}
bool MultipleIOEpoll::PollSetAdd(PollFd poll_fd) {
if (max_poll_size_ <= (int)descriptors_.size()) {
return false;
}
struct epoll_event ee = {0};
ee.events = GetEvent(poll_fd.event);
ee.data.fd = poll_fd.fd;
if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, poll_fd.fd, &ee) == -1) {
return false;
}
int fd = poll_fd.fd;
descriptors_[fd] = poll_fd;
return true;
}
bool MultipleIOEpoll::PollSetRemove(PollFd poll_fd) {
int fd = poll_fd.fd;
struct epoll_event ee = {0};
epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee);
if (descriptors_.find(fd) != descriptors_.end()) {
descriptors_.erase(fd);
}
return true;
}
void MultipleIOEpoll::Poll(int time_out) {
int ret = epoll_wait(epoll_fd_, pollset_.get(), (int)descriptors_.size(),
time_out);
if (ret > 0) {
for (int i =0; i< ret; i++) {
FdEvent fd_event = NONE_EVENT;
if (pollset_[i].events & EPOLLIN) {
fd_event |= READBLE_EVENT;
}
if (pollset_[i].events & EPOLLOUT) {
fd_event |= WRITABLE_EVENT;
}
int fd = pollset_[i].data.fd;
if (descriptors_.find(fd) != descriptors_.end()) {
PollFd pollfd = descriptors_[fd];
pollfd.event_callback(fd_event);
}
}
}
CheckTimer();
}
} // namespace lidar
} // namespace livox
#endif // HAVE_EPOLL
@@ -0,0 +1,54 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef MULTIPLE_IO_EPOLL_H_
#define MULTIPLE_IO_EPOLL_H_
#include "multiple_io_base.h"
#include "livox_lidar_cfg.h"
#include <memory>
#ifdef HAVE_EPOLL
namespace livox {
namespace lidar {
class MultipleIOEpoll : public MultipleIOBase {
public:
bool PollCreate(int size);
bool PollSetAdd(PollFd poll_fd);
bool PollSetRemove(PollFd poll_fd);
void Poll(int timeout);
void PollDestroy();
private:
int epoll_fd_ = -1;
std::unique_ptr<struct epoll_event[]> pollset_;
int max_poll_size_ = 0;
};
} // namespace lidar
} // namespace livox
#endif // HAVE_EPOLL
#endif // MULTIPLE_IO_EPOLL_H_
@@ -0,0 +1,58 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef MULTIPLE_IO_FACTORY_H_
#define MULTIPLE_IO_FACTORY_H_
#include "multiple_io_base.h"
#include "multiple_io_epoll.h"
#include "multiple_io_kqueue.h"
#include "multiple_io_select.h"
#include "multiple_io_poll.h"
#include <memory>
namespace livox {
namespace lidar {
class MultipleIOFactory {
public:
static std::unique_ptr<MultipleIOBase> CreateMultipleIO() {
#if defined(HAVE_EPOLL)
return std::unique_ptr<MultipleIOBase>(new MultipleIOEpoll());
#elif defined(HAVE_KQUEUE)
return std::unique_ptr<MultipleIOBase>(new MultipleIOKqueue());
#elif defined(HAVE_SELECT)
return std::unique_ptr<MultipleIOBase>(new MultipleIOSelect());
#elif defined(HAVE_POLL)
return std::unique_ptr<MultipleIOBase>(new MultipleIOPoll());
#else
return nullptr;
#endif
}
};
} // namespace lidar
} // namespace livox
#endif // MULTIPLE_IO_FACTORY_H_
@@ -0,0 +1,142 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "multiple_io_kqueue.h"
#ifdef HAVE_KQUEUE
namespace livox {
namespace lidar {
bool MultipleIOKqueue::PollCreate(int size) {
kqueue_fd_ = kqueue();
if (kqueue_fd_ == -1) {
return false;
}
int flags = 0;
if ((flags = fcntl(kqueue_fd_, F_GETFD)) == -1) {
close(kqueue_fd_);
return false;
}
flags |= FD_CLOEXEC;
if (fcntl(kqueue_fd_, F_SETFD, flags) == -1) {
close(kqueue_fd_);
return false;
}
max_poll_size_ = size + 1;
set_size_ = 2 * max_poll_size_;
kevent_set_.reset(new struct kevent[set_size_]);
WakeUpInit();
return true;
}
void MultipleIOKqueue::PollDestroy() {
WakeUpUninit();
if (kqueue_fd_ > 0) {
close(kqueue_fd_);
kqueue_fd_ = -1;
}
}
bool MultipleIOKqueue::PollSetAdd(PollFd poll_fd) {
if (max_poll_size_ <= (int)descriptors_.size()) {
return false;
}
int fd = poll_fd.fd;
descriptors_[fd] = poll_fd;
if (poll_fd.event & READBLE_EVENT) {
EV_SET(&kevent_, fd, EVFILT_READ, EV_ADD, 0, 0, &descriptors_[fd].fd);
if (kevent(kqueue_fd_, &kevent_, 1, nullptr, 0, nullptr) == -1) {
descriptors_.erase(fd);
return false;
}
}
if (poll_fd.event & WRITABLE_EVENT) {
EV_SET(&kevent_, fd, EVFILT_WRITE, EV_ADD, 0, 0, &descriptors_[fd].fd);
if (kevent(kqueue_fd_, &kevent_, 1, nullptr, 0, nullptr) == -1) {
descriptors_.erase(fd);
return false;
}
}
return true;
}
bool MultipleIOKqueue::PollSetRemove(PollFd poll_fd) {
int fd = poll_fd.fd;
bool result = true;
if (descriptors_.find(fd) != descriptors_.end()) {
do {
if (descriptors_[fd].event & READBLE_EVENT) {
EV_SET(&kevent_, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
if (kevent(kqueue_fd_, &kevent_, 1, nullptr, 0, nullptr) == -1) {
result = false;
break;
}
}
if (descriptors_[fd].event & WRITABLE_EVENT) {
EV_SET(&kevent_, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
if (kevent(kqueue_fd_, &kevent_, 1, nullptr, 0, nullptr) == -1) {
result = false;
break;
}
}
} while(0);
descriptors_.erase(fd);
}
return result;
}
void MultipleIOKqueue::Poll(int time_out) {
struct timespec tv, *tvptr;
if (time_out < 0) {
tvptr = NULL;
} else {
tv.tv_sec = (long) time_out / 1000;
tv.tv_nsec = (long) (time_out % 1000) * 1000000;
tvptr = &tv;
}
int rv = kevent(kqueue_fd_, NULL, 0, kevent_set_.get(), set_size_, tvptr);
if (rv > 0) {
for (int i = 0; i < rv; i++) {
int fd = *(int *)(kevent_set_[i].udata);
if (descriptors_.find(fd) != descriptors_.end()) {
PollFd pollfd = descriptors_[fd];
if (kevent_set_[i].filter == EVFILT_READ) {
pollfd.event_callback(READBLE_EVENT);
}
if (kevent_set_[i].filter == EVFILT_WRITE) {
pollfd.event_callback(WRITABLE_EVENT);
}
}
}
}
CheckTimer();
}
} // namespace lidar
} // namespace livox
#endif // HAVE_KQUEUE
@@ -0,0 +1,54 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef MULTIPLE_IO_KQUEUE_H_
#define MULTIPLE_IO_KQUEUE_H_
#include "multiple_io_base.h"
#include "livox_lidar_cfg.h"
#ifdef HAVE_KQUEUE
namespace livox {
namespace lidar {
class MultipleIOKqueue : public MultipleIOBase {
public:
bool PollCreate(int size);
bool PollSetAdd(PollFd poll_fd);
bool PollSetRemove(PollFd poll_fd);
void Poll(int timeout);
void PollDestroy();
private:
int kqueue_fd_ = -1;
struct kevent kevent_ = {};
std::unique_ptr<struct kevent[]> kevent_set_;
int max_poll_size_ = 0;
int set_size_ = 0;
};
} // namespace lidar
} // namespace livox
#endif // HAVE_KQUEUE
#endif // MULTIPLE_IO_KQUEUE_H_
@@ -0,0 +1,116 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "multiple_io_poll.h"
#ifdef HAVE_POLL
namespace livox {
namespace lidar {
int GetEvent (FdEvent event) {
int rv = 0;
if (event & READBLE_EVENT)
rv |= POLLIN;
if (event & WRITABLE_EVENT)
rv |= POLLOUT;
return rv;
}
bool MultipleIOPoll:: PollCreate(int size) {
max_poll_size_ = size + 1;
pollset_.reset(new struct pollfd[max_poll_size_]);
WakeUpInit();
return true;
}
bool MultipleIOPoll:: PollSetAdd(PollFd poll_fd) {
if (max_poll_size_ <= (int)descriptors_.size()) {
return false;
}
int fd = poll_fd.fd;
descriptors_[fd] = poll_fd;
struct pollfd fds;
fds.fd = fd;
fds.events = GetEvent(poll_fd.event);
pollset_[pollset_num_] = fds;
pollset_num_++;
return true;
}
void MultipleIOPoll::PollDestroy() {
WakeUpUninit();
return;
}
bool MultipleIOPoll:: PollSetRemove(PollFd poll_fd) {
int fd = poll_fd.fd;
if (descriptors_.find(fd) != descriptors_.end()) {
descriptors_.erase(fd);
}
for (int i = 0; i< pollset_num_; i++) {
if (pollset_[i].fd == fd) {
int dst = i;
for (i++; i < pollset_num_ - 1; i++) {
if (pollset_[i].fd == fd) {
pollset_num_--;
} else {
pollset_[dst] = pollset_[i];
dst++;
}
}
}
}
return true;
}
void MultipleIOPoll:: Poll(int time_out) {
int rv = poll(pollset_.get(), pollset_num_, time_out);
if (rv > 0) {
for (int i = 0; i < pollset_num_; i++) {
FdEvent fd_event = NONE_EVENT;
if (pollset_[i].revents & POLLIN) {
fd_event |= READBLE_EVENT;
}
if (pollset_[i].revents & POLLOUT) {
fd_event |= WRITABLE_EVENT;
}
int fd = pollset_[i].fd;
if (descriptors_.find(fd) != descriptors_.end()) {
PollFd pollfd = descriptors_[fd];
pollfd.event_callback(fd_event);
}
pollset_[i].revents = NONE_EVENT;
}
}
CheckTimer();
}
} // namespace lidar
} // namespace livox
#endif // HAVE_POLL
@@ -0,0 +1,55 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef MULTIPLE_IO_POLL_H_
#define MULTIPLE_IO_POLL_H_
#include "multiple_io_base.h"
#include "livox_lidar_cfg.h"
#include <memory>
#ifdef HAVE_POLL
namespace livox {
namespace lidar {
class MultipleIOPoll : public MultipleIOBase {
public:
bool PollCreate(int size);
bool PollSetAdd(PollFd poll_fd);
bool PollSetRemove(PollFd poll_fd);
void Poll(int timeout);
void PollDestroy();
private:
std::unique_ptr<struct pollfd[]> pollset_;
int pollset_num_ = 0;
int max_poll_size_ = 0;
};
} // namespace lidar
} // namespace livox
#endif // HAVE_POLL
#endif // MULTIPLE_IO_POLL_H_
@@ -0,0 +1,123 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "multiple_io_select.h"
#include <thread>
#ifdef HAVE_SELECT
namespace livox {
namespace lidar {
bool MultipleIOSelect:: PollCreate(int size) {
FD_ZERO(&rfds_);
FD_ZERO(&wfds_);
//wake up fd + 1
max_poll_size_ = size + 1;
WakeUpInit();
return true;
}
void MultipleIOSelect::PollDestroy() {
WakeUpUninit();
FD_ZERO(&rfds_);
FD_ZERO(&wfds_);
}
bool MultipleIOSelect:: PollSetAdd(PollFd poll_fd) {
if (max_poll_size_ <= (int)descriptors_.size()) {
return false;
}
int fd = poll_fd.fd;
descriptors_[fd] = poll_fd;
if (max_fd_ < fd) {
max_fd_ = fd;
}
if (poll_fd.event & READBLE_EVENT) {
FD_SET(fd, &rfds_);
}
if (poll_fd.event & WRITABLE_EVENT) {
FD_SET(fd, &wfds_);
}
return true;
}
bool MultipleIOSelect:: PollSetRemove(PollFd poll_fd) {
int fd = poll_fd.fd;
if (descriptors_.find(fd) != descriptors_.end()) {
descriptors_.erase(fd);
}
FD_CLR(fd, &rfds_);
FD_CLR(fd, &wfds_);
if (max_fd_ <= fd) {
max_fd_--;
}
return true;
}
void MultipleIOSelect:: Poll(int time_out) {
fd_set readset, writeset;
struct timeval tv, *tvptr;
if (descriptors_.size() == 0) {
if (time_out > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(time_out));
return;
}
return ;
}
if (time_out < 0) {
tvptr = nullptr;
} else {
tv.tv_sec = (long)time_out / 1000;
tv.tv_usec = (long)time_out % 1000;
tvptr = &tv;
}
memcpy(&readset, &rfds_, sizeof(fd_set));
memcpy(&writeset, &wfds_, sizeof(fd_set));
int rv = select(max_fd_ + 1, &readset, &writeset, nullptr, tvptr);
if (rv > 0) {
for (auto& descriptor : descriptors_) {
int fd = descriptor.first;
FdEvent fd_event = NONE_EVENT;
if (FD_ISSET(fd, &readset)) {
fd_event |= READBLE_EVENT;
}
if (FD_ISSET(fd, &writeset)) {
fd_event |= WRITABLE_EVENT;
}
if (fd_event != NONE_EVENT) {
PollFd pollfd = descriptor.second;
pollfd.event_callback(fd_event);
}
}
}
CheckTimer();
}
} // namespace lidar
} // namespace livox
#endif // HAVE_SELECT
@@ -0,0 +1,54 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef MULTIPLE_IO_SELECT_H_
#define MULTIPLE_IO_SELECT_H_
#include "multiple_io_base.h"
#include "livox_lidar_cfg.h"
#ifdef HAVE_SELECT
namespace livox {
namespace lidar {
class MultipleIOSelect : public MultipleIOBase {
public:
bool PollCreate(int size);
bool PollSetAdd(PollFd poll_fd);
bool PollSetRemove(PollFd poll_fd);
void Poll(int timeout);
void PollDestroy();
private:
int max_fd_ = -1;
fd_set rfds_;
fd_set wfds_;
int max_poll_size_ = 0;
};
} // namespace lidar
} // namespace livox
#endif // HAVE_SELECT
#endif // MULTIPLE_IO_SELECT_H_
+62
View File
@@ -0,0 +1,62 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_NETWORK_UTIL_H_
#define LIVOX_NETWORK_UTIL_H_
#include <stdint.h>
#ifdef WIN32
#include <winsock2.h>
#include <Ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif // WIN32
#include <stdio.h>
#include <stdio.h>
#include <fcntl.h>
#include <string>
namespace livox {
namespace lidar {
namespace util {
typedef int socket_t;
socket_t CreateSocket(uint16_t port, bool nonblock = true, bool reuse_port = true, bool is_broadcast = false, const std::string netif = "", const std::string multicast_ip = "");
//socket_t CreateSocket(uint16_t port, bool nonblock = true, bool reuse_port = true, bool is_broadcast = false);
void CloseSock(socket_t sock);
bool FindLocalIp(const struct sockaddr_in &client_addr, uint32_t &local_ip);
size_t RecvFrom(socket_t &sock, void *buff, size_t buf_size, int flag, struct sockaddr *addr, int* addrlen);
} // namespace util
} // namespace lidar
} // namespace livox
#endif // LIVOX_NETWORK_UTIL_H_
+218
View File
@@ -0,0 +1,218 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef WIN32
#include "base/network/network_util.h"
#include <ifaddrs.h>
#include <string>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netdb.h>
namespace livox {
namespace lidar {
namespace util {
socket_t CreateSocket(uint16_t port, bool nonblock, bool reuse_port, bool is_broadcast, const std::string netif, const std::string multicast_ip) {
int status = -1;
int on = -1;
int sock = -1;
int recv_buff_size = 1024 * 1024 * 200;
struct sockaddr_in servaddr;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("create failed\n");
return -1;
}
if (nonblock) {
status = ioctl(sock, FIONBIO, (char*)&on);
if (status != 0) {
printf("noblock failed\n");
close(sock);
return -1;
}
}
if (reuse_port) {
status = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *) &on, sizeof (on));
if (status != 0) {
printf("reuse port failed\n");
close(sock);
return -1;
}
}
status = setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *)&recv_buff_size, sizeof(recv_buff_size));
if (status != 0) {
close(sock);
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
if (netif.empty()) {
servaddr.sin_addr.s_addr = INADDR_ANY;
} else {
if(!multicast_ip.empty()){
servaddr.sin_addr.s_addr = inet_addr(multicast_ip.c_str());
} else {
servaddr.sin_addr.s_addr = inet_addr(netif.c_str());
}
}
servaddr.sin_port = htons(port);
status = bind(sock, (const struct sockaddr *)&servaddr, sizeof(servaddr));
if (status != 0) {
printf("bind failed\n");
close(sock);
return -1;
}
if (is_broadcast) {
status = setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
(char *)&on, sizeof(on));
if (status != 0) {
close(sock);
printf("broad cast failed\n");
return -1;
}
}
if (!multicast_ip.empty()) {
struct ip_mreq mreq;
bzero(&mreq, sizeof(struct ip_mreq));
mreq.imr_interface.s_addr = inet_addr(netif.c_str());
mreq.imr_multiaddr.s_addr = inet_addr(multicast_ip.c_str());
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq)) == -1) {
printf("setsockopt failed\n");
}
}
return sock;
}
// socket_t CreateSocket(uint16_t port, bool nonblock, bool reuse_port, bool is_broadcast) {
// int status = -1;
// int on = -1;
// int sock = -1;
// struct sockaddr_in servaddr;
// sock = socket(AF_INET, SOCK_DGRAM, 0);
// if (sock < 0) {
// return -1;
// }
// if (nonblock) {
// status = ioctl(sock, FIONBIO, (char*)&on);
// if (status != 0) {
// close(sock);
// return -1;
// }
// }
// if (reuse_port) {
// status = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
// (char *) &on, sizeof (on));
// if (status != 0) {
// close(sock);
// return -1;
// }
// }
// if (is_broadcast) {
// status = setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
// (char *)&on, sizeof(on));
// if (status != 0) {
// close(sock);
// return -1;
// }
// }
// memset(&servaddr, 0, sizeof(servaddr));
// // Filling server information
// servaddr.sin_family = AF_INET; // IPv4
// servaddr.sin_addr.s_addr = INADDR_ANY;
// servaddr.sin_port = htons(port);
// status = bind(sock, (const struct sockaddr *)&servaddr, sizeof(servaddr));
// if (status != 0) {
// close(sock);
// return -1;
// }
// return sock;
// }
void CloseSock(int sock) {
if (sock > 0) {
close(sock);
}
}
bool FindLocalIp(const struct sockaddr_in &client_addr, uint32_t &local_ip) {
struct ifaddrs *if_addrs = NULL, *addrs = NULL;
if (getifaddrs(&if_addrs) == -1) {
return false;
}
addrs = if_addrs;
bool found = false;
while (if_addrs != NULL) {
if ((if_addrs->ifa_addr != NULL) && (if_addrs->ifa_addr->sa_family == AF_INET)) // check it is IP4
{
// is a connected IP4 Address
struct sockaddr_in *ifu_localaddr = (struct sockaddr_in *)if_addrs->ifa_addr;
struct sockaddr_in *ifu_netmask = (struct sockaddr_in *)if_addrs->ifa_netmask;
if (ifu_localaddr->sin_addr.s_addr != htonl(INADDR_ANY)) {
if ((ifu_localaddr->sin_addr.s_addr & ifu_netmask->sin_addr.s_addr) ==
(client_addr.sin_addr.s_addr & ifu_netmask->sin_addr.s_addr)) {
local_ip = ifu_localaddr->sin_addr.s_addr;
found = true;
break;
}
}
}
if_addrs = if_addrs->ifa_next;
}
if (addrs) {
freeifaddrs(addrs);
}
return found;
}
size_t RecvFrom(socket_t &sock, void *buff, size_t buf_size, int flag, struct sockaddr *addr, int *addrlen) {
return recvfrom(sock, buff, buf_size, 0, addr, (socklen_t *)addrlen);
}
} // namespace util
} // namespace lidar
} // namespace livox
#endif // WIN32
+177
View File
@@ -0,0 +1,177 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifdef WIN32
#include "base/network/network_util.h"
#include <memory>
#include <iphlpapi.h>
#include <string>
#pragma comment(lib,"iphlpapi.lib")
#pragma comment(lib,"ws2_32.lib")
namespace livox {
namespace lidar {
namespace util {
void CloseSock(socket_t sock) {
closesocket(sock);
}
socket_t CreateSocket(uint16_t port, bool nonblock, bool reuse_port, bool is_broadcast, std::string netif, const std::string multicast_ip) {
int status = -1;
int on = -1;
int sock = -1;
int recv_buff_size = 1024 * 1024 * 200;
struct sockaddr_in servaddr;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
return -1;
}
if (nonblock) {
status = ioctlsocket(sock, FIONBIO, (u_long *)&on);
if (status != NO_ERROR) {
closesocket(sock);
return -1;
}
}
if (reuse_port) {
status = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *) &on, sizeof (on));
if (status != 0) {
closesocket(sock);
return -1;
}
}
if (is_broadcast) {
status = setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
(char *)&on, sizeof(on));
if (status != 0) {
closesocket(sock);
return -1;
}
}
status = setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *)&recv_buff_size, sizeof(recv_buff_size));
if (status != 0) {
closesocket(sock);
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
if (netif.empty()) {
servaddr.sin_addr.s_addr = INADDR_ANY;
} else {
servaddr.sin_addr.s_addr = inet_addr(netif.c_str());
}
servaddr.sin_port = htons(port);
status = bind(sock, (const struct sockaddr *)&servaddr, sizeof(servaddr));
if (status != 0) {
closesocket(sock);
return -1;
}
if (is_broadcast) {
status = setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
(char *)&on, sizeof(on));
if (status != 0) {
closesocket(sock);
printf("broad cast failed\n");
return -1;
}
}
if (!multicast_ip.empty()) {
struct ip_mreq mreq;
memset(&mreq, 0, sizeof(struct ip_mreq));
mreq.imr_interface.s_addr = inet_addr(netif.c_str());
mreq.imr_multiaddr.s_addr = inet_addr(multicast_ip.c_str());
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<char*>(&mreq), sizeof(struct ip_mreq)) == -1) {
printf("setsockopt failed\n");
}
}
return sock;
}
bool GetAdapterState(const IP_ADAPTER_INFO *pAdapter) {
if(pAdapter == NULL) {
return false;
}
MIB_IFROW info;
memset(&info ,0 ,sizeof(MIB_IFROW));
info.dwIndex = pAdapter->Index;
if (GetIfEntry(&info) != NOERROR) {
return false;
}
if (info.dwOperStatus == IF_OPER_STATUS_NON_OPERATIONAL
|| info.dwOperStatus == IF_OPER_STATUS_UNREACHABLE
|| info.dwOperStatus == IF_OPER_STATUS_DISCONNECTED
|| info.dwOperStatus == IF_OPER_STATUS_CONNECTING)
return false;
return true;
}
bool FindLocalIp(const struct sockaddr_in &client_addr, uint32_t &local_ip) {
bool found = false;
ULONG ulOutbufLen = sizeof(IP_ADAPTER_INFO);
std::unique_ptr<uint8_t[]> pAdapterInfo(new uint8_t[ulOutbufLen]);
DWORD dlRetVal = GetAdaptersInfo(reinterpret_cast<IP_ADAPTER_INFO *>(pAdapterInfo.get()), &ulOutbufLen);
if (dlRetVal == ERROR_BUFFER_OVERFLOW) {
pAdapterInfo.reset(new uint8_t[ulOutbufLen]);
dlRetVal = GetAdaptersInfo(reinterpret_cast<IP_ADAPTER_INFO *>(pAdapterInfo.get()), &ulOutbufLen);
}
IP_ADAPTER_INFO *pAdapter = reinterpret_cast<IP_ADAPTER_INFO *>(pAdapterInfo.get());
if (NO_ERROR == dlRetVal && pAdapter != NULL) {
while (pAdapter != NULL) {
if (GetAdapterState(pAdapter)) {
std::string str_ip = pAdapter->IpAddressList.IpAddress.String;
std::string str_mask = pAdapter->IpAddressList.IpMask.String;
ULONG host_ip = inet_addr(const_cast<char *>(str_ip.c_str()));
ULONG host_mask = inet_addr(const_cast<char *>(str_mask.c_str()));
if ((host_ip & host_mask) ==
(client_addr.sin_addr.S_un.S_addr & host_mask)) {
local_ip = host_ip;
found = true;
break;
}
}
pAdapter = pAdapter->Next;
}
}
return found;
}
size_t RecvFrom(socket_t &sock, void *buff, size_t buf_size, int flag, struct sockaddr *addr, int* addrlen) {
return recvfrom(sock, (char *)buff, buf_size, 0, addr, addrlen);
}
} // namespace util
} // namespace lidar
} // namespace livox
#endif // WIN32
+43
View File
@@ -0,0 +1,43 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_NONCOPYABLE_H_
#define LIVOX_NONCOPYABLE_H_
namespace livox {
namespace lidar {
class noncopyable {
protected:
noncopyable() {}
~noncopyable() {}
private:
noncopyable(const noncopyable &);
noncopyable &operator=(const noncopyable &);
};
} // namespace lidar
} // namespace livox
#endif // LIVOX_NONCOPYABLE_H_
+61
View File
@@ -0,0 +1,61 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "thread_base.h"
#include <thread>
#include <iostream>
#include <memory>
namespace livox {
namespace lidar {
ThreadBase::ThreadBase() : quit_(false) {}
bool ThreadBase::Start() {
quit_ = false;
thread_ = std::make_shared<std::thread>(&ThreadBase::ThreadFunc, this);
return true;
}
ThreadBase::~ThreadBase() {
if (thread_) {
Join();
}
}
void ThreadBase::Join() {
quit_ = true;
if (thread_ && thread_->joinable()) {
thread_->join();
thread_ = nullptr;
} else {
std::cout << "failed to join thread, joinable: "
<< thread_->joinable() << std::endl;
thread_ = nullptr;
}
}
} // namespace lidar
} // namespace livox
+54
View File
@@ -0,0 +1,54 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef LIVOX_THREAD_BASE_H_
#define LIVOX_THREAD_BASE_H_
#include <atomic>
#include <thread>
#include <memory>
#include "noncopyable.h"
namespace livox {
namespace lidar {
class ThreadBase : public noncopyable {
public:
ThreadBase();
virtual ~ThreadBase();
virtual void ThreadFunc() = 0;
bool Start();
bool IsQuit() { return quit_; }
protected:
void Join();
private:
std::atomic_bool quit_;
std::shared_ptr<std::thread> thread_;
};
} //namespace lidar
} // namespace livox
#endif // LIVOX_THREAD_BASE_H_
+119
View File
@@ -0,0 +1,119 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef WIN32
#include "base/wake_up/wake_up_pipe.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
namespace livox {
namespace lidar {
WakeUpPipe::~WakeUpPipe() {
PipeDestroy();
}
bool WakeUpPipe::WakeUp() {
char ch = '1';
ssize_t nbytes = sizeof(ch);
if (pipe_in_ > 0) {
if (nbytes != write(pipe_in_, &ch, nbytes)) {
return false;
}
}
return true;
}
bool WakeUpPipe::Drain() {
char ch[512];
size_t size = sizeof(ch);
if (pipe_out_ > 0) {
ssize_t ret = read(pipe_out_, ch, size);
if (ret < 0) {
return false;
}
}
return true;
}
bool WakeUpPipe::PipeDestroy() {
if (pipe_in_ > 0) {
close(pipe_in_);
}
if (pipe_out_ > 0) {
close(pipe_out_);
}
return true;
}
bool WakeUpPipe::PipeCreate() {
bool status = false;
//in filedes[0]
//out filedes[1]
int filedes[2]= {};
if (pipe(filedes) == -1) {
return false;
}
do {
int flags = 0;
if ((flags = fcntl(filedes[0], F_GETFD)) == -1) {
break;
}
flags |= FD_CLOEXEC;
if (fcntl(filedes[0], F_SETFD, flags) == -1) {
break;
}
flags = 0;
if ((flags = fcntl(filedes[1], F_GETFD)) == -1) {
break;
}
flags |= FD_CLOEXEC;
if (fcntl(filedes[1], F_SETFD, flags) == -1) {
break;
}
status = true;
} while(0);
if (!status) {
if (filedes[0] > 0) {
close(filedes[0]);
}
if (filedes[1] > 0) {
close(filedes[1]);
}
return false;
}
pipe_out_ = filedes[0];
pipe_in_ = filedes[1];
return true;
}
} // namespace lidar
} // namespace livox
#endif // WIN32
+48
View File
@@ -0,0 +1,48 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifndef WAKE_UP_PIPE_H_
#define WAKE_UP_PIPE_H_
namespace livox {
namespace lidar {
class WakeUpPipe {
public:
WakeUpPipe(): pipe_in_(0), pipe_out_(0) {}
virtual ~WakeUpPipe();
bool PipeCreate();
bool PipeDestroy();
bool WakeUp();
bool Drain();
int GetPipeOut() { return pipe_out_; }
protected:
int pipe_in_;
int pipe_out_;
};
} // namespace lidar
} // namespace livox
#endif // WAKE_UP_PIPE_H_
+134
View File
@@ -0,0 +1,134 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2022 Livox. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#ifdef WIN32
#include "base/wake_up/wake_up_pipe.h"
#include <fcntl.h>
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"iphlpapi.lib")
#pragma comment(lib,"ws2_32.lib")
namespace livox {
namespace lidar {
WakeUpPipe::~WakeUpPipe() {
PipeDestroy();
}
bool WakeUpPipe::WakeUp() {
char ch = '1';
size_t nbytes = sizeof(ch);
if (pipe_in_ > 0) {
if (nbytes != send(pipe_in_,&ch, nbytes, 0)) {
return false;
}
}
return true;
}
bool WakeUpPipe::Drain() {
char ch[512];
size_t size = sizeof(ch);
if (pipe_out_ > 0) {
recv(pipe_out_, ch, size, 0);
}
return true;
}
bool WakeUpPipe::PipeDestroy() {
if (pipe_in_ > 0) {
closesocket(pipe_in_);
}
if (pipe_out_ > 0) {
closesocket(pipe_out_);
}
return true;
}
bool WakeUpPipe::PipeCreate() {
int listen_sock = -1;
unsigned long on = 1;
bool status = false;
if ((listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
return false;
}
struct sockaddr_in servaddr;
int servaddr_len = sizeof(servaddr);
servaddr.sin_family = AF_INET;
servaddr.sin_port = 0;
servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
do {
if (bind(listen_sock, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == SOCKET_ERROR) {
break;
}
if (getsockname(listen_sock, (struct sockaddr *)&servaddr, &servaddr_len) == SOCKET_ERROR) {
break;
}
if (listen(listen_sock, 1) == SOCKET_ERROR) {
break;
}
if ((pipe_in_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
break;
}
if (connect(pipe_in_, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == SOCKET_ERROR) {
break;
}
if (ioctlsocket(listen_sock, FIONBIO, &on) == SOCKET_ERROR) {
break;
}
struct sockaddr_in clientaddr;
int clientaddr_len = sizeof(clientaddr);
fd_set poll_set;
FD_ZERO(&poll_set);
FD_SET(listen_sock, &poll_set);
// timeout 2s
struct timeval timeout = {2, 0};
int rv = select(0, &poll_set, nullptr, nullptr, &timeout);
if (rv <= 0) {
break;
}
if ((pipe_out_ = accept(listen_sock, (struct sockaddr *)&clientaddr, &clientaddr_len)) == INVALID_SOCKET) {
break;
}
status = true;
} while(0);
closesocket(listen_sock);
if (!status) {
if (pipe_in_ > 0) {
closesocket(pipe_in_);
}
return false;
}
return true;
}
} // namespace lidar
} // namespace livox
#endif // WIN32