mirror of
https://github.com/Quad4-Software/Reticulum-Go
synced 2026-08-29 23:48:44 -04:00
136 lines
3.4 KiB
C++
136 lines
3.4 KiB
C++
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright (c) 2024-2026 Quad4.io
|
|
|
|
#ifndef RNS_NODE_HPP
|
|
#define RNS_NODE_HPP
|
|
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "rns/detail/c_api.hpp"
|
|
#include "rns/error.hpp"
|
|
#include "rns/event.hpp"
|
|
#include "rns/identity.hpp"
|
|
#include "rns/span.hpp"
|
|
#include "rns/types.hpp"
|
|
#include "rns/util.hpp"
|
|
|
|
namespace rns {
|
|
|
|
class Node {
|
|
public:
|
|
Node() noexcept : handle_(0) {}
|
|
|
|
Node(Node &&other) noexcept
|
|
: handle_(other.handle_), callback_(std::move(other.callback_)) {
|
|
other.handle_ = 0;
|
|
}
|
|
|
|
Node &operator=(Node &&other) noexcept {
|
|
if (this != &other) {
|
|
reset();
|
|
handle_ = other.handle_;
|
|
callback_ = std::move(other.callback_);
|
|
other.handle_ = 0;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
Node(const Node &) = delete;
|
|
Node &operator=(const Node &) = delete;
|
|
|
|
~Node() { reset(); }
|
|
|
|
static Result<Node> create(std::string_view config_path = {}) {
|
|
char path_buf[4096];
|
|
const char *path_z = "";
|
|
if (!config_path.empty()) {
|
|
Error cerr =
|
|
util::require_cstring(config_path, path_buf, sizeof(path_buf), &path_z);
|
|
if (cerr != Error::Ok) {
|
|
return Result<Node>(cerr);
|
|
}
|
|
}
|
|
std::uint64_t h = rns_node_create(path_z);
|
|
if (h == 0) {
|
|
return Result<Node>(Error::Internal);
|
|
}
|
|
return Result<Node>(Node(h));
|
|
}
|
|
|
|
Error start() { return map_code(rns_node_start(handle_)); }
|
|
|
|
Error stop() { return map_code(rns_node_stop(handle_)); }
|
|
|
|
Error pause() { return map_code(rns_node_pause(handle_)); }
|
|
|
|
Error resume() { return map_code(rns_node_resume(handle_)); }
|
|
|
|
Error set_identity(Identity &identity) {
|
|
return map_code(rns_node_set_identity(handle_, identity.handle()));
|
|
}
|
|
|
|
Error refresh_paths() { return map_code(rns_node_refresh_paths(handle_, nullptr, 0)); }
|
|
|
|
Error refresh_paths(span<const Hash> dest_hashes) {
|
|
if (dest_hashes.empty()) {
|
|
return refresh_paths();
|
|
}
|
|
std::vector<std::uint8_t> flat(dest_hashes.size() * hash_len);
|
|
for (std::size_t i = 0; i < dest_hashes.size(); ++i) {
|
|
std::memcpy(flat.data() + i * hash_len, dest_hashes[i].data(), hash_len);
|
|
}
|
|
return map_code(rns_node_refresh_paths(handle_, flat.data(), dest_hashes.size()));
|
|
}
|
|
|
|
Result<Event> poll(int timeout_ms, span<std::uint8_t> app_data_buf = {}) {
|
|
rns_event ev;
|
|
std::memset(&ev, 0, sizeof(ev));
|
|
if (!app_data_buf.empty()) {
|
|
ev.app_data = app_data_buf.data();
|
|
ev.app_data_cap = app_data_buf.size();
|
|
}
|
|
Error err = map_code(rns_event_poll(handle_, &ev, timeout_ms));
|
|
if (err != Error::Ok) {
|
|
return Result<Event>(err);
|
|
}
|
|
return Result<Event>(Event::from_c(ev));
|
|
}
|
|
|
|
Error set_event_callback(EventCallback callback) {
|
|
if (!callback) {
|
|
Error err = map_code(rns_set_event_callback(handle_, nullptr, nullptr));
|
|
callback_.reset();
|
|
return err;
|
|
}
|
|
callback_ = std::make_unique<EventCallback>(std::move(callback));
|
|
return map_code(
|
|
rns_set_event_callback(handle_, event_callback_c_fn(), callback_.get()));
|
|
}
|
|
|
|
std::uint64_t handle() const noexcept { return handle_; }
|
|
explicit operator bool() const noexcept { return handle_ != 0; }
|
|
|
|
void reset() noexcept {
|
|
if (handle_ != 0) {
|
|
rns_set_event_callback(handle_, nullptr, nullptr);
|
|
rns_node_destroy(handle_);
|
|
handle_ = 0;
|
|
}
|
|
callback_.reset();
|
|
}
|
|
|
|
private:
|
|
explicit Node(std::uint64_t handle) noexcept : handle_(handle) {}
|
|
|
|
std::uint64_t handle_;
|
|
std::unique_ptr<EventCallback> callback_;
|
|
};
|
|
|
|
} // namespace rns
|
|
|
|
#endif
|