mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-03-27 22:53:07 +00:00
208 lines
7.2 KiB
C
208 lines
7.2 KiB
C
#ifndef CLIENT_FFI_H
|
|
#define CLIENT_FFI_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Opaque handle returned by client_create.
|
|
* ------------------------------------------------------------------ */
|
|
|
|
typedef struct ClientHandle ClientHandle_t;
|
|
|
|
/* ------------------------------------------------------------------
|
|
* C delivery callback.
|
|
*
|
|
* Called for each outbound envelope. `addr_ptr/addr_len` is the
|
|
* delivery address (UTF-8, not NUL-terminated). `data_ptr/data_len`
|
|
* is the encrypted payload. `userdata` is the pointer supplied to
|
|
* client_create. Return 0 on success, negative on error.
|
|
* ------------------------------------------------------------------ */
|
|
|
|
typedef int32_t (*DeliverFn_t)(
|
|
const uint8_t *addr_ptr, size_t addr_len,
|
|
const uint8_t *data_ptr, size_t data_len,
|
|
void *userdata);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Error codes (match crates/client-ffi/src/api.rs ErrorCode)
|
|
* ------------------------------------------------------------------ */
|
|
|
|
#define CLIENT_FFI_OK 0
|
|
#define CLIENT_FFI_ERR_BAD_UTF8 (-1)
|
|
#define CLIENT_FFI_ERR_BAD_INTRO (-2)
|
|
#define CLIENT_FFI_ERR_DELIVERY (-3)
|
|
#define CLIENT_FFI_ERR_UNKNOWN (-4)
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Result structs — all heap-allocated fields are owned by the caller
|
|
* and must be freed via the matching destroy_* function.
|
|
* ------------------------------------------------------------------ */
|
|
|
|
typedef struct {
|
|
int32_t error_code;
|
|
uint8_t *intro_bytes_ptr;
|
|
size_t intro_bytes_len;
|
|
} CreateIntroResult_t;
|
|
|
|
typedef struct {
|
|
int32_t error_code;
|
|
/* UTF-8, NOT NUL-terminated */
|
|
uint8_t *convo_id_ptr;
|
|
size_t convo_id_len;
|
|
} CreateConvoResult_t;
|
|
|
|
typedef struct {
|
|
int32_t error_code;
|
|
bool has_content;
|
|
bool is_new_convo;
|
|
/* UTF-8, NOT NUL-terminated. NULL when has_content is false. */
|
|
uint8_t *convo_id_ptr;
|
|
size_t convo_id_len;
|
|
/* NULL when has_content is false. */
|
|
uint8_t *content_ptr;
|
|
size_t content_len;
|
|
} PushInboundResult_t;
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Lifecycle
|
|
* ------------------------------------------------------------------ */
|
|
|
|
/**
|
|
* Create an ephemeral in-memory client.
|
|
*
|
|
* @param name_ptr UTF-8 installation name (need not be NUL-terminated).
|
|
* @param name_len Byte length of name_ptr.
|
|
* @param callback Non-null delivery callback.
|
|
* @param userdata Opaque pointer forwarded to each callback invocation.
|
|
* @return Opaque handle, or NULL on error. Free with client_destroy.
|
|
*/
|
|
ClientHandle_t *client_create(
|
|
const uint8_t *name_ptr, size_t name_len,
|
|
DeliverFn_t callback,
|
|
void *userdata);
|
|
|
|
/**
|
|
* Destroy a client handle. Must not be used after this call.
|
|
*/
|
|
void client_destroy(ClientHandle_t *handle);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Identity
|
|
* ------------------------------------------------------------------ */
|
|
|
|
/**
|
|
* Return a pointer to the installation name bytes (UTF-8, not NUL-terminated).
|
|
* The pointer is valid until the next mutating call or client_destroy.
|
|
* The caller must NOT free it.
|
|
*
|
|
* @param out_len Receives the byte length of the returned string.
|
|
*/
|
|
const uint8_t *client_installation_name(const ClientHandle_t *handle, size_t *out_len);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Intro bundle
|
|
* ------------------------------------------------------------------ */
|
|
|
|
/**
|
|
* Generate a serialised introduction bundle for out-of-band sharing.
|
|
* Always call destroy_create_intro_result when done.
|
|
*/
|
|
void client_create_intro_bundle(ClientHandle_t *handle, CreateIntroResult_t *out);
|
|
|
|
/** Free the result from client_create_intro_bundle. */
|
|
void destroy_create_intro_result(CreateIntroResult_t *result);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Create conversation
|
|
* ------------------------------------------------------------------ */
|
|
|
|
/**
|
|
* Parse an intro bundle and initiate a private conversation.
|
|
* Outbound envelopes are dispatched through the delivery callback.
|
|
* Always call destroy_create_convo_result when done.
|
|
*/
|
|
void client_create_conversation(
|
|
ClientHandle_t *handle,
|
|
const uint8_t *bundle_ptr, size_t bundle_len,
|
|
const uint8_t *content_ptr, size_t content_len,
|
|
CreateConvoResult_t *out);
|
|
|
|
/** Free the result from client_create_conversation. */
|
|
void destroy_create_convo_result(CreateConvoResult_t *result);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Send message
|
|
* ------------------------------------------------------------------ */
|
|
|
|
/**
|
|
* Encrypt content and dispatch outbound envelopes.
|
|
*
|
|
* @param convo_id_ptr UTF-8 conversation ID (not NUL-terminated).
|
|
* @return CLIENT_FFI_OK on success, error code otherwise.
|
|
*/
|
|
int32_t client_send_message(
|
|
ClientHandle_t *handle,
|
|
const uint8_t *convo_id_ptr, size_t convo_id_len,
|
|
const uint8_t *content_ptr, size_t content_len);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* Push inbound
|
|
* ------------------------------------------------------------------ */
|
|
|
|
/**
|
|
* Decrypt an inbound payload. has_content is false for protocol frames.
|
|
* Always call destroy_push_inbound_result when error_code == CLIENT_FFI_OK.
|
|
*/
|
|
void client_push_inbound(
|
|
ClientHandle_t *handle,
|
|
const uint8_t *payload_ptr, size_t payload_len,
|
|
PushInboundResult_t *out);
|
|
|
|
/** Free the result from client_push_inbound. */
|
|
void destroy_push_inbound_result(PushInboundResult_t *result);
|
|
|
|
/* ------------------------------------------------------------------
|
|
* ClientOps — vtable used by c-test so C can call the Rust client-ffi
|
|
* functions indirectly via function pointers supplied by the Rust harness.
|
|
*
|
|
* This avoids the linker-ordering problem that arises when C archives
|
|
* are searched before Rust rlibs: the C code has no direct undefined
|
|
* references to Rust symbols; it only uses the pointers it receives.
|
|
* ------------------------------------------------------------------ */
|
|
|
|
typedef struct {
|
|
ClientHandle_t *(*create)(
|
|
const uint8_t *name_ptr, size_t name_len,
|
|
DeliverFn_t callback, void *userdata);
|
|
void (*destroy)(ClientHandle_t *handle);
|
|
void (*create_intro_bundle)(ClientHandle_t *handle, CreateIntroResult_t *out);
|
|
void (*destroy_intro_result)(CreateIntroResult_t *result);
|
|
void (*create_conversation)(
|
|
ClientHandle_t *handle,
|
|
const uint8_t *bundle_ptr, size_t bundle_len,
|
|
const uint8_t *content_ptr, size_t content_len,
|
|
CreateConvoResult_t *out);
|
|
void (*destroy_convo_result)(CreateConvoResult_t *result);
|
|
int32_t (*send_message)(
|
|
ClientHandle_t *handle,
|
|
const uint8_t *convo_id_ptr, size_t convo_id_len,
|
|
const uint8_t *content_ptr, size_t content_len);
|
|
void (*push_inbound)(
|
|
ClientHandle_t *handle,
|
|
const uint8_t *payload_ptr, size_t payload_len,
|
|
PushInboundResult_t *out);
|
|
void (*destroy_inbound_result)(PushInboundResult_t *result);
|
|
} ClientOps;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* CLIENT_FFI_H */
|