Initial commit: Livox SDK2 source (excluding build artifacts)
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user