VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
c_api.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file c_api.h
26 * @brief Pure C API for the VLink communication middleware.
27 *
28 * @details
29 * Provides a stable, language-agnostic C binding over the VLink C++ core.
30 * Each of the three VLink communication models is exposed through a handle-based
31 * interface that wraps the corresponding C++ template class:
32 *
33 * | Model | C++ class | C handle types |
34 * | ------- | --------------------------------- | -------------------------------------------------- |
35 * | Event | Publisher / Subscriber | vlink_publisher_handle_t / vlink_subscriber_handle_t |
36 * | Method | Server / Client | vlink_server_handle_t / vlink_client_handle_t |
37 * | Field | Setter / Getter | vlink_setter_handle_t / vlink_getter_handle_t |
38 *
39 * All handles are opaque structs that contain a @c native_handle pointer to the
40 * underlying C++ object and a @c reserved array used for internal state
41 * (e.g., the @c std::mutex and response buffer used by @c vlink_server_handle_t).
42 *
43 * @par Return value conventions
44 * Every function returns a @c vlink_ret_t integer:
45 *
46 * | Code | Meaning |
47 * | ----------------------------- | ------------------------------------------------ |
48 * | VLINK_RET_NO_ERROR (0) | Success |
49 * | VLINK_RET_UNEXPECTED_ERROR | Condition not met (e.g., no subscribers yet) |
50 * | VLINK_RET_INVALID_ERROR | Null pointer or invalid handle |
51 * | VLINK_RET_MEMORY_ERROR | Output buffer too small |
52 * | VLINK_RET_RUNTIME_ERROR | Exception thrown during C++ construction |
53 * | VLINK_RET_TRANSFER_ERROR | Publish / listen / invoke operation failed |
54 * | VLINK_RET_UNKNOWN_ERROR (-1) | Unclassified error |
55 *
56 * @par Server reply protocol
57 * The @c vlink_server_handle_t::reserved array is used to coordinate the
58 * synchronous request-reply flow:
59 * @code
60 * static void on_request(const uint8_t* data, size_t size, void* user_data) {
61 * vlink_server_handle_t* handle = (vlink_server_handle_t*) user_data;
62 * vlink_reply(handle, resp_data, resp_size);
63 * }
64 *
65 * vlink_schema_info_t schema = {"demo.raw.Text", VLINK_SCHEMA_RAW};
66 * vlink_create_server(url, &schema, &handle, on_request, &handle);
67 * @endcode
68 * If @c vlink_reply() is not called, the request completes with an empty
69 * response payload. Calling @c vlink_reply() after the callback returns is
70 * undefined behaviour; the internal mutex lock will no longer be held.
71 *
72 * @par Usage -- publisher / subscriber
73 * @code
74 * vlink_publisher_handle_t pub;
75 * vlink_schema_info_t schema = {"demo.proto.PointCloud", VLINK_SCHEMA_PROTOBUF};
76 * vlink_create_publisher("dds://my/topic", &schema, &pub);
77 * vlink_wait_for_subscribers(pub, 1000);
78 * vlink_publish(pub, data_buf, data_size);
79 * vlink_destroy_publisher(&pub);
80 *
81 * static void on_message(const uint8_t* data, size_t size, void* user_data) {
82 * (void) data;
83 * (void) size;
84 * (void) user_data;
85 * }
86 *
87 * vlink_subscriber_handle_t sub;
88 * vlink_create_subscriber("dds://my/topic", &schema, &sub, on_message, user_data);
89 * @endcode
90 *
91 * @par Usage -- getter (polling)
92 * @code
93 * vlink_getter_handle_t getter;
94 * vlink_schema_info_t schema = {"demo.proto.State", VLINK_SCHEMA_PROTOBUF};
95 * vlink_create_getter("dds://state/topic", &schema, &getter, NULL, NULL);
96 *
97 * uint8_t buf[4096];
98 * size_t sz = sizeof(buf);
99 * if (vlink_get(getter, buf, &sz) == VLINK_RET_NO_ERROR) {
100 * // buf[0..sz-1] contains the latest value
101 * }
102 * @endcode
103 *
104 * @note
105 * - The C API uses @c vlink::Publisher<vlink::Bytes> and similar internally.
106 * Pass @c vlink_schema_info_t to configure @c ser + @c schema atomically.
107 * - All create/destroy pairs must be balanced. Handles are not thread-safe
108 * across concurrent create/destroy calls.
109 * - @c vlink_get() copies the latest value into the caller-supplied buffer.
110 * Returns @c VLINK_RET_MEMORY_ERROR if @c *size is smaller than the payload.
111 * - @c vlink_publish_by_force() publishes even when no subscribers are
112 * matched, useful for transient-local-durability scenarios.
113 */
114
115// NOLINTBEGIN
116
117#pragma once
118
119#undef VLINK_C_API_EXPORT
120#ifdef VLINK_C_API_LIBRARY_STATIC
121#define VLINK_C_API_EXPORT
122#elif defined(_WIN32) || defined(__CYGWIN__)
123#ifdef VLINK_C_API_LIBRARY
124#define VLINK_C_API_EXPORT __declspec(dllexport)
125#else
126#define VLINK_C_API_EXPORT __declspec(dllimport)
127#endif
128#else
129#define VLINK_C_API_EXPORT __attribute__((visibility("default")))
130#endif
131
132#include <stdbool.h>
133#include <stddef.h>
134#include <stdint.h>
135
136#ifdef __cplusplus
137extern "C" {
138#endif
139
140/**
141 * @brief Return code for all VLink C API functions.
142 *
143 * @details
144 * A non-negative value indicates success or an expected condition.
145 * Negative values indicate hard errors. Check the return of every API call.
146 */
147typedef enum {
148 VLINK_RET_UNKNOWN_ERROR = -1, /**< Unclassified or unexpected internal error. */
149 VLINK_RET_NO_ERROR = 0, /**< Operation succeeded. */
150 VLINK_RET_UNEXPECTED_ERROR = 1, /**< Condition not yet met (e.g., no subscribers). */
151 VLINK_RET_INVALID_ERROR = 2, /**< Null pointer argument or invalid handle. */
152 VLINK_RET_MEMORY_ERROR = 3, /**< Caller-provided buffer is too small. */
153 VLINK_RET_RUNTIME_ERROR = 4, /**< C++ exception thrown during node construction. */
154 VLINK_RET_TRANSFER_ERROR = 5, /**< Publish, listen, or invoke operation failed. */
156
157/**
158 * @brief Coarse runtime schema family used for raw C API nodes.
159 *
160 * @details
161 * Numerical values are intentionally kept in sync with the C++
162 * @c vlink::SchemaType enum (see @c include/vlink/impl/types.h). This
163 * allows the C API implementation to cast between the two enums safely.
164 * Clients should always reference the symbolic names rather than the raw
165 * integer values so the mapping remains opaque at the source level.
166 */
167typedef enum {
168 VLINK_SCHEMA_UNKNOWN = 0, /**< Schema family is not specified. */
169 VLINK_SCHEMA_RAW = 1, /**< Opaque/raw payload. */
170 VLINK_SCHEMA_ZEROCOPY = 2, /**< VLink zero-copy payload. */
171 VLINK_SCHEMA_PROTOBUF = 3, /**< Protocol Buffers payload. */
172 VLINK_SCHEMA_FLATBUFFERS = 4, /**< FlatBuffers payload. */
174
175/**
176 * @brief Bundled runtime schema metadata for C API node creation.
177 *
178 * @details
179 * This mirrors the C++ pair of @c ser_type + @c schema_type so callers can
180 * configure both pieces atomically before the underlying node is initialised.
181 * Callers must either provide both fields together or leave both unset
182 * (@c ser == NULL / empty and @c schema == VLINK_SCHEMA_UNKNOWN).
183 */
184typedef struct {
185 const char* ser; /**< Concrete type name / serialization identifier, or @c NULL. */
186 vlink_schema_t schema; /**< Coarse schema family. */
188
189/**
190 * @brief Opaque handle for a @c Publisher node.
191 *
192 * @details
193 * Created by @c vlink_create_publisher() and destroyed by
194 * @c vlink_destroy_publisher(). @c native_handle points to a heap-allocated
195 * @c vlink::Publisher<vlink::Bytes> object.
196 */
197typedef struct {
198 void* native_handle; /**< Internal C++ Publisher object pointer. */
199 void* reserved[4]; /**< Reserved for internal use; do not modify. */
201
202/**
203 * @brief Opaque handle for a @c Subscriber node.
204 *
205 * @details
206 * Created by @c vlink_create_subscriber() and destroyed by
207 * @c vlink_destroy_subscriber(). @c native_handle points to a heap-allocated
208 * @c vlink::Subscriber<vlink::Bytes> object.
209 */
210typedef struct {
211 void* native_handle; /**< Internal C++ Subscriber object pointer. */
212 void* reserved[4]; /**< Reserved for internal use; do not modify. */
214
215/**
216 * @brief Opaque handle for a @c Server node.
217 *
218 * @details
219 * Created by @c vlink_create_server() and destroyed by
220 * @c vlink_destroy_server(). @c native_handle points to a heap-allocated
221 * @c vlink::Server<vlink::Bytes, vlink::Bytes> object.
222 * The @c reserved array is used internally to coordinate the synchronous
223 * request-reply flow:
224 * - @c reserved[0]: pointer to a @c std::mutex (lock held during callback).
225 * - @c reserved[1]: pointer to the response byte buffer.
226 * - @c reserved[2]: response byte count (stored as a pointer-sized integer).
227 * - @c reserved[3]: non-null while a request is being processed (cleared by
228 * @c vlink_reply()).
229 */
230typedef struct {
231 void* native_handle; /**< Internal C++ Server object pointer. */
232 void* reserved[4]; /**< Internal coordination fields; do not modify. */
234
235/**
236 * @brief Opaque handle for a @c Client node.
237 *
238 * @details
239 * Created by @c vlink_create_client() and destroyed by
240 * @c vlink_destroy_client(). @c native_handle points to a heap-allocated
241 * @c vlink::Client<vlink::Bytes, vlink::Bytes> object.
242 */
243typedef struct {
244 void* native_handle; /**< Internal C++ Client object pointer. */
245 void* reserved[4]; /**< Reserved for internal use; do not modify. */
247
248/**
249 * @brief Opaque handle for a @c Setter node.
250 *
251 * @details
252 * Created by @c vlink_create_setter() and destroyed by
253 * @c vlink_destroy_setter(). @c native_handle points to a heap-allocated
254 * @c vlink::Setter<vlink::Bytes> object.
255 */
256typedef struct {
257 void* native_handle; /**< Internal C++ Setter object pointer. */
258 void* reserved[4]; /**< Reserved for internal use; do not modify. */
260
261/**
262 * @brief Opaque handle for a @c Getter node.
263 *
264 * @details
265 * Created by @c vlink_create_getter() and destroyed by
266 * @c vlink_destroy_getter(). @c native_handle points to a heap-allocated
267 * @c vlink::Getter<vlink::Bytes> object.
268 */
269typedef struct {
270 void* native_handle; /**< Internal C++ Getter object pointer. */
271 void* reserved[4]; /**< Reserved for internal use; do not modify. */
273
274/**
275 * @brief Callback invoked when the connection state of a Publisher or Client changes.
276 *
277 * @param is_connected @c true when at least one peer has matched, @c false otherwise.
278 * @param user_data Opaque pointer supplied at registration time.
279 */
280typedef void (*vlink_connect_callback_t)(const bool is_connected, void* user_data);
281
282/**
283 * @brief Callback invoked when a Subscriber or Getter receives a message.
284 *
285 * @param data Pointer to the received payload bytes.
286 * @param size Number of bytes in @p data.
287 * @param user_data Opaque pointer supplied at creation time.
288 */
289typedef void (*vlink_msg_callback_t)(const uint8_t* data, const size_t size, void* user_data);
290
291/**
292 * @brief Callback invoked when a Server receives an RPC request.
293 *
294 * @details
295 * Called synchronously on the Server's dispatch thread while an internal mutex
296 * is held. Call @c vlink_reply() from within this callback if you want to
297 * provide a non-empty response before returning. If it is not called, the
298 * request completes with an empty payload. Calling it after the callback
299 * returns is undefined behaviour.
300 *
301 * @param data Pointer to the request payload bytes.
302 * @param size Number of bytes in @p data.
303 * @param user_data Opaque pointer supplied at creation time.
304 */
305typedef void (*vlink_req_callback_t)(const uint8_t* data, const size_t size, void* user_data);
306
307/**
308 * @brief Callback invoked when a Client receives an RPC response.
309 *
310 * @param data Pointer to the response payload bytes. May be null if the
311 * server did not provide a response.
312 * @param size Number of bytes in @p data.
313 * @param user_data Opaque pointer supplied at invocation time.
314 */
315typedef void (*vlink_resp_callback_t)(const uint8_t* data, const size_t size, void* user_data);
316
317////////////////////////////////////////////////////////////////
318/// Publisher
319////////////////////////////////////////////////////////////////
320
321/**
322 * @brief Creates a Publisher node and initialises it on the given URL.
323 *
324 * @details
325 * Allocates a @c vlink::Publisher<vlink::Bytes> on the heap and stores the
326 * pointer in @p handle. Pass @p schema_info to set @c ser + @c schema before
327 * the underlying node is initialised. Pass @c NULL to leave both unset.
328 *
329 * @param url VLink topic URL (e.g., @c "dds://my/topic"). Must not be @c NULL.
330 * @param schema_info Optional bundled @c ser + @c schema metadata.
331 * @param handle Output handle to fill. Must not be @c NULL.
332 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
333 * @p url or @p handle is @c NULL, if @p schema_info is only
334 * partially filled, if @p schema_info->schema is invalid, or
335 * @c VLINK_RET_RUNTIME_ERROR if construction throws.
336 */
337VLINK_C_API_EXPORT int vlink_create_publisher(const char* url, const vlink_schema_info_t* schema_info,
339
340/**
341 * @brief Destroys a Publisher node and releases all associated resources.
342 *
343 * @param handle Publisher handle to destroy. Must not be @c NULL.
344 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
345 * @p handle or its @c native_handle is @c NULL.
346 */
348
349/**
350 * @brief Checks whether at least one Subscriber has matched this Publisher.
351 *
352 * @param handle Publisher handle.
353 * @return @c VLINK_RET_NO_ERROR if subscribers are present,
354 * @c VLINK_RET_UNEXPECTED_ERROR if none are matched yet, or
355 * @c VLINK_RET_INVALID_ERROR on bad handle.
356 */
358
359/**
360 * @brief Blocks until at least one Subscriber matches or the timeout elapses.
361 *
362 * @param handle Publisher handle.
363 * @param timeout_ms Maximum wait time in milliseconds.
364 * @return @c VLINK_RET_NO_ERROR if a subscriber matched,
365 * @c VLINK_RET_UNEXPECTED_ERROR if the timeout expired, or
366 * @c VLINK_RET_INVALID_ERROR on bad handle.
367 */
369
370/**
371 * @brief Registers a callback fired whenever the Subscriber connection state changes.
372 *
373 * @details
374 * The callback is invoked from the Publisher's internal event thread.
375 *
376 * @param handle Publisher handle.
377 * @param connect_callback Callback to invoke on connection change.
378 * @param user_data Opaque pointer forwarded to @p connect_callback.
379 * @return @c VLINK_RET_NO_ERROR on success, or
380 * @c VLINK_RET_INVALID_ERROR on bad handle or
381 * @c NULL @p connect_callback.
382 */
384 const vlink_connect_callback_t connect_callback, void* user_data);
385
386/**
387 * @brief Publishes a message to all matched Subscribers.
388 *
389 * @details
390 * Internally wraps @p data in a shallow-copy @c vlink::Bytes (zero-copy when
391 * the underlying transport supports it). Returns @c VLINK_RET_TRANSFER_ERROR
392 * if no subscribers are matched and the publisher does not allow forced delivery.
393 *
394 * @param handle Publisher handle.
395 * @param data Payload to publish. Must remain valid until the call returns.
396 * @param size Number of bytes in @p data.
397 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_TRANSFER_ERROR
398 * if publishing failed, or @c VLINK_RET_INVALID_ERROR on bad handle.
399 */
400VLINK_C_API_EXPORT int vlink_publish(const vlink_publisher_handle_t handle, const uint8_t* data, const size_t size);
401
402/**
403 * @brief Publishes a message even when no Subscribers are currently matched.
404 *
405 * @details
406 * Identical to @c vlink_publish() but passes @c force=true to the underlying
407 * publisher, bypassing the subscriber-presence check. Useful for
408 * transient-local-durability or late-joining subscriber scenarios.
409 *
410 * @param handle Publisher handle.
411 * @param data Payload to publish.
412 * @param size Number of bytes in @p data.
413 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_TRANSFER_ERROR
414 * on failure, or @c VLINK_RET_INVALID_ERROR on bad handle.
415 */
417 const size_t size);
418
419////////////////////////////////////////////////////////////////
420/// Subscriber
421////////////////////////////////////////////////////////////////
422
423/**
424 * @brief Creates a Subscriber node, initialises it, and registers the message callback.
425 *
426 * @details
427 * Allocates a @c vlink::Subscriber<vlink::Bytes> and immediately calls @c listen()
428 * with the provided @p msg_callback. The callback is invoked on the Subscriber's
429 * internal receive thread.
430 *
431 * @param url VLink topic URL. Must not be @c NULL.
432 * @param schema_info Optional bundled @c ser + @c schema metadata.
433 * @param handle Output handle. Must not be @c NULL.
434 * @param msg_callback Callback invoked on each received message. Must not be @c NULL.
435 * @param user_data Opaque pointer forwarded to @p msg_callback.
436 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
437 * any required argument is @c NULL, if @p schema_info is only
438 * partially filled, if @p schema_info->schema is invalid,
439 * @c VLINK_RET_TRANSFER_ERROR if @c listen() fails, or
440 * @c VLINK_RET_RUNTIME_ERROR on construction exception.
441 */
442VLINK_C_API_EXPORT int vlink_create_subscriber(const char* url, const vlink_schema_info_t* schema_info,
444 const vlink_msg_callback_t msg_callback, void* user_data);
445
446/**
447 * @brief Destroys a Subscriber node and releases all associated resources.
448 *
449 * @param handle Subscriber handle to destroy. Must not be @c NULL.
450 * @return @c VLINK_RET_NO_ERROR on success, or @c VLINK_RET_INVALID_ERROR
451 * on bad handle.
452 */
454
455////////////////////////////////////////////////////////////////
456/// Server
457////////////////////////////////////////////////////////////////
458
459/**
460 * @brief Creates a Server node, initialises it, and registers the request callback.
461 *
462 * @details
463 * Allocates a @c vlink::Server<vlink::Bytes, vlink::Bytes> and calls @c listen()
464 * with an internal handler that wraps @p req_callback.
465 *
466 * The internal handler holds a @c std::mutex (stored in @c handle->reserved[0])
467 * during each invocation. Call @c vlink_reply() from within @p req_callback
468 * to set a non-empty response before the callback returns.
469 *
470 * @param url VLink service URL. Must not be @c NULL.
471 * @param schema_info Optional bundled @c ser + @c schema metadata.
472 * @param handle Output handle. Must not be @c NULL.
473 * @param req_callback Request handler. Must not be @c NULL. Call
474 * @c vlink_reply() before returning if a non-empty
475 * response is required.
476 * @param user_data Opaque pointer forwarded to @p req_callback.
477 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
478 * @p url or @p handle is @c NULL, if @p req_callback is
479 * @c NULL, if @p schema_info is only partially filled, if
480 * @p schema_info->schema is invalid, @c VLINK_RET_TRANSFER_ERROR
481 * if @c listen() fails, or @c VLINK_RET_RUNTIME_ERROR on
482 * construction exception.
483 */
484VLINK_C_API_EXPORT int vlink_create_server(const char* url, const vlink_schema_info_t* schema_info,
485 vlink_server_handle_t* handle, const vlink_req_callback_t req_callback,
486 void* user_data);
487
488/**
489 * @brief Destroys a Server node and frees all internal resources including the
490 * internal mutex and any pending response buffer.
491 *
492 * @param handle Server handle to destroy. Must not be @c NULL.
493 * @return @c VLINK_RET_NO_ERROR on success, or @c VLINK_RET_INVALID_ERROR
494 * on bad handle.
495 */
497
498/**
499 * @brief Provides the response data for the current in-progress RPC request.
500 *
501 * @details
502 * Must be called from within the @c vlink_req_callback_t while the internal
503 * mutex lock is still held. Copies @p data into a heap buffer stored in
504 * @c handle->reserved[1] and sets @c handle->reserved[2] to the size.
505 * Sets @c handle->reserved[3] to @c NULL to signal that a reply is ready.
506 *
507 * @param handle Server handle. Must not be @c NULL.
508 * @param data Response payload bytes.
509 * @param size Number of bytes in @p data.
510 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR
511 * on bad handle, or @c VLINK_RET_RUNTIME_ERROR if no pending
512 * request is in progress.
513 */
514VLINK_C_API_EXPORT int vlink_reply(vlink_server_handle_t* handle, const uint8_t* data, const size_t size);
515
516////////////////////////////////////////////////////////////////
517/// Client
518////////////////////////////////////////////////////////////////
519
520/**
521 * @brief Creates a Client node and initialises it on the given URL.
522 *
523 * @param url VLink service URL. Must not be @c NULL.
524 * @param schema_info Optional bundled @c ser + @c schema metadata.
525 * @param handle Output handle. Must not be @c NULL.
526 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
527 * @p url or @p handle is @c NULL, if @p schema_info is only
528 * partially filled, if @p schema_info->schema is invalid, or
529 * @c VLINK_RET_RUNTIME_ERROR on construction exception.
530 */
531VLINK_C_API_EXPORT int vlink_create_client(const char* url, const vlink_schema_info_t* schema_info,
532 vlink_client_handle_t* handle);
533
534/**
535 * @brief Destroys a Client node and releases all associated resources.
536 *
537 * @param handle Client handle to destroy. Must not be @c NULL.
538 * @return @c VLINK_RET_NO_ERROR on success, or @c VLINK_RET_INVALID_ERROR
539 * on bad handle.
540 */
542
543/**
544 * @brief Checks whether the Client is connected to a Server.
545 *
546 * @param handle Client handle.
547 * @return @c VLINK_RET_NO_ERROR if connected, @c VLINK_RET_UNEXPECTED_ERROR
548 * if not yet connected, or @c VLINK_RET_INVALID_ERROR on bad handle.
549 */
551
552/**
553 * @brief Blocks until a Server is available or the timeout elapses.
554 *
555 * @param handle Client handle.
556 * @param timeout_ms Maximum wait time in milliseconds.
557 * @return @c VLINK_RET_NO_ERROR if connected, @c VLINK_RET_UNEXPECTED_ERROR
558 * on timeout, or @c VLINK_RET_INVALID_ERROR on bad handle.
559 */
560VLINK_C_API_EXPORT int vlink_wait_for_server(const vlink_client_handle_t handle, const int timeout_ms);
561
562/**
563 * @brief Registers a callback fired whenever the Server connection state changes.
564 *
565 * @param handle Client handle.
566 * @param connect_callback Callback to invoke on connection change.
567 * @param user_data Opaque pointer forwarded to @p connect_callback.
568 * @return @c VLINK_RET_NO_ERROR on success, or
569 * @c VLINK_RET_INVALID_ERROR on bad handle or
570 * @c NULL @p connect_callback.
571 */
573 const vlink_connect_callback_t connect_callback, void* user_data);
574
575/**
576 * @brief Sends an RPC request and registers a callback to receive the response.
577 *
578 * @details
579 * Internally calls @c vlink::Client::invoke() using a shallow-copy @c Bytes
580 * wrapping @p data. The @p resp_callback is invoked asynchronously on the
581 * underlying @c vlink::Client callback context when the Server's response
582 * arrives.
583 * Pass @c NULL for @p resp_callback if the response is not needed.
584 *
585 * @param handle Client handle.
586 * @param data Request payload. Must remain valid until the call returns.
587 * @param size Number of bytes in @p data.
588 * @param resp_callback Callback invoked with the response, or @c NULL.
589 * @param user_data Opaque pointer forwarded to @p resp_callback.
590 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_TRANSFER_ERROR
591 * if the invoke failed, or @c VLINK_RET_INVALID_ERROR on bad handle.
592 */
593VLINK_C_API_EXPORT int vlink_invoke(const vlink_client_handle_t handle, const uint8_t* data, const size_t size,
594 const vlink_resp_callback_t resp_callback, void* user_data);
595
596////////////////////////////////////////////////////////////////
597/// Setter
598////////////////////////////////////////////////////////////////
599
600/**
601 * @brief Creates a Setter node and initialises it on the given URL.
602 *
603 * @param url VLink field URL. Must not be @c NULL.
604 * @param schema_info Optional bundled @c ser + @c schema metadata.
605 * @param handle Output handle. Must not be @c NULL.
606 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
607 * @p url or @p handle is @c NULL, if @p schema_info is only
608 * partially filled, if @p schema_info->schema is invalid, or
609 * @c VLINK_RET_RUNTIME_ERROR on construction exception.
610 */
611VLINK_C_API_EXPORT int vlink_create_setter(const char* url, const vlink_schema_info_t* schema_info,
612 vlink_setter_handle_t* handle);
613
614/**
615 * @brief Destroys a Setter node and releases all associated resources.
616 *
617 * @param handle Setter handle to destroy. Must not be @c NULL.
618 * @return @c VLINK_RET_NO_ERROR on success, or @c VLINK_RET_INVALID_ERROR
619 * on bad handle.
620 */
622
623/**
624 * @brief Publishes the latest field value.
625 *
626 * @details
627 * The new value overwrites the previous value held by all matched Getters.
628 * Internally wraps @p data in a shallow-copy @c vlink::Bytes (zero-copy).
629 *
630 * @warning
631 * The Setter caches the latest value internally so that late-joining Getters
632 * can sync. Because @p data is wrapped without copying, the buffer it points
633 * to **must remain valid until either** (a) the next @c vlink_set() call on
634 * the same handle (which overrides the cached value), or (b)
635 * @c vlink_destroy_setter() is called. Releasing @p data sooner causes a
636 * use-after-free when a late Getter tries to read the cache. Static
637 * storage (string literals, file-scope buffers) or a pinned allocation that
638 * lives for the Setter's lifetime is the typical pattern; if that is
639 * inconvenient, copy the value into a long-lived buffer before calling
640 * @c vlink_set().
641 *
642 * @param handle Setter handle.
643 * @param data New field value bytes. Must remain valid until the next
644 * @c vlink_set() or @c vlink_destroy_setter().
645 * @param size Number of bytes in @p data.
646 * @return @c VLINK_RET_NO_ERROR on success, or @c VLINK_RET_INVALID_ERROR
647 * on bad handle.
648 */
649VLINK_C_API_EXPORT int vlink_set(const vlink_setter_handle_t handle, const uint8_t* data, const size_t size);
650
651////////////////////////////////////////////////////////////////
652/// Getter
653////////////////////////////////////////////////////////////////
654
655/**
656 * @brief Creates a Getter node, initialises it, and optionally registers a change callback.
657 *
658 * @details
659 * Allocates a @c vlink::Getter<vlink::Bytes>. If @p msg_callback is non-null,
660 * @c listen() is called and the callback is invoked on every value update.
661 * If @p msg_callback is @c NULL the Getter operates in polling mode -- use
662 * @c vlink_get() to retrieve the latest value.
663 *
664 * @param url VLink field URL. Must not be @c NULL.
665 * @param schema_info Optional bundled @c ser + @c schema metadata.
666 * @param handle Output handle. Must not be @c NULL.
667 * @param msg_callback Callback for push-mode updates, or @c NULL for poll mode.
668 * @param user_data Opaque pointer forwarded to @p msg_callback.
669 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_INVALID_ERROR if
670 * @p url or @p handle is @c NULL, if @p schema_info is only
671 * partially filled, if @p schema_info->schema is invalid, or
672 * @c VLINK_RET_RUNTIME_ERROR on construction exception.
673 */
674VLINK_C_API_EXPORT int vlink_create_getter(const char* url, const vlink_schema_info_t* schema_info,
675 vlink_getter_handle_t* handle, const vlink_msg_callback_t msg_callback,
676 void* user_data);
677
678/**
679 * @brief Destroys a Getter node and releases all associated resources.
680 *
681 * @param handle Getter handle to destroy. Must not be @c NULL.
682 * @return @c VLINK_RET_NO_ERROR on success, or @c VLINK_RET_INVALID_ERROR
683 * on bad handle.
684 */
686
687/**
688 * @brief Retrieves the latest field value into a caller-provided buffer.
689 *
690 * @details
691 * Copies the current cached value into @p data. On entry @c *size must hold
692 * the capacity of @p data; on success @c *size is updated to the actual byte
693 * count. When the buffer is too small returns @c VLINK_RET_MEMORY_ERROR and
694 * sets @c *size to the required byte count so the caller can allocate and
695 * retry. @p data is left unmodified in the error case.
696 *
697 * @param handle Getter handle.
698 * @param data Output buffer. Must not be @c NULL.
699 * @param size In/out: buffer capacity on entry, actual size on exit (or required
700 * size when the buffer is too small). Must not be @c NULL.
701 * @return @c VLINK_RET_NO_ERROR on success, @c VLINK_RET_TRANSFER_ERROR if no
702 * value is available yet, @c VLINK_RET_MEMORY_ERROR if @c *size is too
703 * small (the required size is written back into @c *size), or
704 * @c VLINK_RET_INVALID_ERROR on bad arguments.
705 */
706VLINK_C_API_EXPORT int vlink_get(const vlink_getter_handle_t handle, uint8_t* data, size_t* size);
707
708#ifdef __cplusplus
709}
710#endif
711
712// NOLINTEND
void(* vlink_connect_callback_t)(const bool is_connected, void *user_data)
Callback invoked when the connection state of a Publisher or Client changes.
Definition c_api.h:280
VLINK_C_API_EXPORT int vlink_invoke(const vlink_client_handle_t handle, const uint8_t *data, const size_t size, const vlink_resp_callback_t resp_callback, void *user_data)
Sends an RPC request and registers a callback to receive the response.
VLINK_C_API_EXPORT int vlink_publish(const vlink_publisher_handle_t handle, const uint8_t *data, const size_t size)
Publishes a message to all matched Subscribers.
vlink_ret_t
Return code for all VLink C API functions.
Definition c_api.h:147
@ VLINK_RET_UNKNOWN_ERROR
Definition c_api.h:148
@ VLINK_RET_NO_ERROR
Definition c_api.h:149
@ VLINK_RET_RUNTIME_ERROR
Definition c_api.h:153
@ VLINK_RET_INVALID_ERROR
Definition c_api.h:151
@ VLINK_RET_MEMORY_ERROR
Definition c_api.h:152
@ VLINK_RET_TRANSFER_ERROR
Definition c_api.h:154
@ VLINK_RET_UNEXPECTED_ERROR
Definition c_api.h:150
VLINK_C_API_EXPORT int vlink_create_setter(const char *url, const vlink_schema_info_t *schema_info, vlink_setter_handle_t *handle)
Setter.
vlink_schema_t
Coarse runtime schema family used for raw C API nodes.
Definition c_api.h:167
@ VLINK_SCHEMA_ZEROCOPY
Definition c_api.h:170
@ VLINK_SCHEMA_RAW
Definition c_api.h:169
@ VLINK_SCHEMA_FLATBUFFERS
Definition c_api.h:172
@ VLINK_SCHEMA_PROTOBUF
Definition c_api.h:171
@ VLINK_SCHEMA_UNKNOWN
Definition c_api.h:168
VLINK_C_API_EXPORT int vlink_has_server(const vlink_client_handle_t handle)
Checks whether the Client is connected to a Server.
void(* vlink_req_callback_t)(const uint8_t *data, const size_t size, void *user_data)
Callback invoked when a Server receives an RPC request.
Definition c_api.h:305
VLINK_C_API_EXPORT int vlink_publish_by_force(const vlink_publisher_handle_t handle, const uint8_t *data, const size_t size)
Publishes a message even when no Subscribers are currently matched.
#define VLINK_C_API_EXPORT
Definition c_api.h:129
VLINK_C_API_EXPORT int vlink_create_publisher(const char *url, const vlink_schema_info_t *schema_info, vlink_publisher_handle_t *handle)
Publisher.
VLINK_C_API_EXPORT int vlink_create_getter(const char *url, const vlink_schema_info_t *schema_info, vlink_getter_handle_t *handle, const vlink_msg_callback_t msg_callback, void *user_data)
Getter.
VLINK_C_API_EXPORT int vlink_detect_subscribers(const vlink_publisher_handle_t handle, const vlink_connect_callback_t connect_callback, void *user_data)
Registers a callback fired whenever the Subscriber connection state changes.
VLINK_C_API_EXPORT int vlink_detect_server(const vlink_client_handle_t handle, const vlink_connect_callback_t connect_callback, void *user_data)
Registers a callback fired whenever the Server connection state changes.
VLINK_C_API_EXPORT int vlink_create_subscriber(const char *url, const vlink_schema_info_t *schema_info, vlink_subscriber_handle_t *handle, const vlink_msg_callback_t msg_callback, void *user_data)
Subscriber.
VLINK_C_API_EXPORT int vlink_destroy_publisher(vlink_publisher_handle_t *handle)
Destroys a Publisher node and releases all associated resources.
void(* vlink_resp_callback_t)(const uint8_t *data, const size_t size, void *user_data)
Callback invoked when a Client receives an RPC response.
Definition c_api.h:315
VLINK_C_API_EXPORT int vlink_wait_for_subscribers(const vlink_publisher_handle_t handle, const int timeout_ms)
Blocks until at least one Subscriber matches or the timeout elapses.
VLINK_C_API_EXPORT int vlink_wait_for_server(const vlink_client_handle_t handle, const int timeout_ms)
Blocks until a Server is available or the timeout elapses.
VLINK_C_API_EXPORT int vlink_reply(vlink_server_handle_t *handle, const uint8_t *data, const size_t size)
Provides the response data for the current in-progress RPC request.
VLINK_C_API_EXPORT int vlink_get(const vlink_getter_handle_t handle, uint8_t *data, size_t *size)
Retrieves the latest field value into a caller-provided buffer.
void(* vlink_msg_callback_t)(const uint8_t *data, const size_t size, void *user_data)
Callback invoked when a Subscriber or Getter receives a message.
Definition c_api.h:289
VLINK_C_API_EXPORT int vlink_destroy_server(vlink_server_handle_t *handle)
Destroys a Server node and frees all internal resources including the internal mutex and any pending ...
VLINK_C_API_EXPORT int vlink_destroy_client(vlink_client_handle_t *handle)
Destroys a Client node and releases all associated resources.
VLINK_C_API_EXPORT int vlink_create_client(const char *url, const vlink_schema_info_t *schema_info, vlink_client_handle_t *handle)
Client.
VLINK_C_API_EXPORT int vlink_create_server(const char *url, const vlink_schema_info_t *schema_info, vlink_server_handle_t *handle, const vlink_req_callback_t req_callback, void *user_data)
Server.
VLINK_C_API_EXPORT int vlink_has_subscribers(const vlink_publisher_handle_t handle)
Checks whether at least one Subscriber has matched this Publisher.
VLINK_C_API_EXPORT int vlink_destroy_subscriber(vlink_subscriber_handle_t *handle)
Destroys a Subscriber node and releases all associated resources.
VLINK_C_API_EXPORT int vlink_destroy_setter(vlink_setter_handle_t *handle)
Destroys a Setter node and releases all associated resources.
VLINK_C_API_EXPORT int vlink_destroy_getter(vlink_getter_handle_t *handle)
Destroys a Getter node and releases all associated resources.
VLINK_C_API_EXPORT int vlink_set(const vlink_setter_handle_t handle, const uint8_t *data, const size_t size)
Publishes the latest field value.