10#ifndef NROS_CPP_SERVICE_HPP
11#define NROS_CPP_SERVICE_HPP
18#include "nros/size_bound.hpp"
20#include "nros_cpp_ffi.h"
29 uint8_t* resp,
size_t resp_cap,
30 size_t* resp_len,
void* ctx);
33 const char* service_name,
const char* type_name,
36 void* context, uint8_t sched_context,
37 size_t* out_handle_id);
81 return try_recv_request_sized<::nros::rx_buffer_capacity<RequestType>::value>(req, seq_id);
96 nros_cpp_service_server_take_request_raw(storage_, buf,
sizeof(buf), &len, &seq);
97 if (ret != 0)
return Result(ret);
110 [[deprecated(
"Service::try_recv_request is deprecated; use Service::take_request")]]
Result
122 uint8_t buf[::nros::detail::buffer_bounds<ResponseType>::tx];
124 if (ResponseType::ffi_serialize(&resp, buf,
sizeof(buf), &len) != 0) {
127 return Result(nros_cpp_service_server_send_response_raw(storage_, seq_id, buf, len));
135 [[deprecated(
"Service::send_reply() is deprecated; use Service::send_response()")]]
Result
150 if (initialized_ && !callback_mode_) {
151 nros_cpp_service_server_destroy(storage_);
153 initialized_ =
false;
162 : initialized_(other.initialized_), user_fn_(other.user_fn_),
163 user_fn_ctx_(other.user_fn_ctx_), user_ctx_(other.user_ctx_),
164 handle_id_(other.handle_id_), callback_mode_(other.callback_mode_) {
165 if (other.initialized_ && !other.callback_mode_) {
166 nros_cpp_service_server_relocate(other.storage_, storage_);
168 other.initialized_ =
false;
172 if (
this != &other) {
173 if (initialized_ && !callback_mode_) {
174 nros_cpp_service_server_destroy(storage_);
176 initialized_ = other.initialized_;
177 user_fn_ = other.user_fn_;
178 user_fn_ctx_ = other.user_fn_ctx_;
179 user_ctx_ = other.user_ctx_;
180 handle_id_ = other.handle_id_;
181 callback_mode_ = other.callback_mode_;
182 if (other.initialized_ && !other.callback_mode_) {
183 nros_cpp_service_server_relocate(other.storage_, storage_);
185 other.initialized_ =
false;
192 Service() : storage_(), initialized_(false) {}
208 static bool request_trampoline(
const uint8_t* req,
size_t req_len, uint8_t* resp,
209 size_t resp_cap,
size_t* resp_len,
void* ctx) {
210 auto* self =
static_cast<Service*
>(ctx);
211 if (self ==
nullptr)
return false;
213 if (RequestType::ffi_deserialize(req, req_len, &request) != 0)
return false;
215 if (self->user_fn_ !=
nullptr) {
216 self->user_fn_(request, response);
217 }
else if (self->user_fn_ctx_ !=
nullptr) {
218 self->user_fn_ctx_(request, response, self->user_ctx_);
223 if (ResponseType::ffi_serialize(&response, resp, resp_cap, &len) != 0)
return false;
228 alignas(8) uint8_t storage_[NROS_SERVICE_SERVER_SIZE];
233 void* user_ctx_ =
nullptr;
234 size_t handle_id_ =
static_cast<size_t>(-1);
235 bool callback_mode_ =
false;
250 &handle_, service_name, S::TYPE_NAME, S::Request::TYPE_HASH, ffi_qos, out.storage_);
252 out.initialized_ =
true;
260template <
typename S,
typename F,
typename>
262 const ServiceOptions& options) {
268 out.user_fn_ctx_ =
nullptr;
269 out.user_ctx_ =
nullptr;
271 uint8_t sched = (options.sched_context == SCHED_CONTEXT_UNSET)
273 :
static_cast<uint8_t
>(options.sched_context);
274 size_t handle =
static_cast<size_t>(-1);
276 &handle_, service_name, S::TYPE_NAME, S::Request::TYPE_HASH, ffi_qos,
278 &out, sched, &handle);
280 out.handle_id_ = handle;
281 out.callback_mode_ =
true;
282 out.initialized_ =
true;
Result create_service(Service< S > &out, const char *service_name, const QoS &qos=QoS::services())
Definition service.hpp:246
static constexpr Result success()
Named constructors.
Definition result.hpp:112
Definition service.hpp:60
void(*)(const RequestType &request, ResponseType &response, void *ctx) TypedServiceFnWithCtx
Definition service.hpp:70
Result try_recv_request_sized(RequestType &req, int64_t &seq_id)
Definition service.hpp:90
~Service()
Definition service.hpp:149
Result send_response(int64_t seq_id, const ResponseType &resp)
Definition service.hpp:120
Result try_recv_request(RequestType &req, int64_t &seq_id)
Definition service.hpp:111
typename S::Request RequestType
Definition service.hpp:62
Service(Service &&other)
Definition service.hpp:161
Service & operator=(Service &&other)
Definition service.hpp:171
Result send_reply(int64_t seq_id, const ResponseType &resp)
Definition service.hpp:136
typename S::Response ResponseType
Definition service.hpp:63
void(*)(const RequestType &request, ResponseType &response) TypedServiceFn
Definition service.hpp:68
size_t handle_id() const
Definition service.hpp:196
Result take_request(RequestType &req, int64_t &seq_id)
Definition service.hpp:80
Service()
Definition service.hpp:192
bool is_valid() const
Check if the service is initialized and valid.
Definition service.hpp:141
Inline storage-size macros for opaque entity buffers.
int nros_cpp_ret_t
Definition future.hpp:21
@ Error
Generic failure not covered by a more specific code.
@ TryAgain
Transient — no data ready yet (non-blocking take). Retry later.
nros::Node and global session helpers.
nros::Result, nros::ErrorCode, and the NROS_TRY macro.
bool(* nros_cpp_service_request_callback_t)(const uint8_t *req, size_t req_len, uint8_t *resp, size_t resp_cap, size_t *resp_len, void *ctx)
Definition service.hpp:28
nros_cpp_ret_t nros_cpp_service_server_register(const nros_cpp_node_t *node, const char *service_name, const char *type_name, const char *type_hash, nros_cpp_qos_t qos, nros_cpp_service_request_callback_t callback, void *context, uint8_t sched_context, size_t *out_handle_id)