/* * voicecat.cpp — C ABI implementation (M0 skeleton). * * Lifecycle (create/destroy) and trivial accessors are real. Everything that needs a * subsystem (net/crypto/codec/protocol/session/audio) returns VC_ERR_NOT_IMPLEMENTED for * now and is the work of M1+ (see AGENTS.md / docs/roadmap.md). */ #include "voicecat.h" #include #include "core/client.h" #define VC_STR2(x) #x #define VC_STR(x) VC_STR2(x) extern "C" { const char* vc_version_string(void) { static const char* kVersion = VC_STR(VOICECAT_VERSION_MAJOR) "." VC_STR( VOICECAT_VERSION_MINOR) "." VC_STR(VOICECAT_VERSION_PATCH); return kVersion; } const char* vc_result_string(vc_result code) { switch (code) { case VC_OK: return "ok"; case VC_ERR_NOT_IMPLEMENTED: return "not implemented"; case VC_ERR_INVALID_ARG: return "invalid argument"; case VC_ERR_NOT_CONNECTED: return "not connected"; case VC_ERR_ALREADY: return "already in requested state"; case VC_ERR_AUTH_FAILED: return "authentication failed"; case VC_ERR_PERMISSION_DENIED: return "permission denied"; case VC_ERR_TIMEOUT: return "timeout"; case VC_ERR_IO: return "i/o error"; case VC_ERR_PROTOCOL: return "protocol error"; case VC_ERR_CRYPTO: return "crypto error"; case VC_ERR_AUDIO: return "audio error"; case VC_ERR_INTERNAL: return "internal error"; } return "unknown"; } vc_client* vc_client_create(const vc_config* cfg, vc_callbacks cb) { if (cfg == nullptr) return nullptr; return new (std::nothrow) vc_client(*cfg, cb); } void vc_client_destroy(vc_client* c) { delete c; } /* ── Everything below delegates to the (stub) client. ─────────────────────── */ vc_result vc_connect(vc_client* c, const char* host, uint16_t port) { if (c == nullptr || host == nullptr) return VC_ERR_INVALID_ARG; return c->connect(host, port); } vc_result vc_disconnect(vc_client* c) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->disconnect(); } vc_result vc_authenticate_guest(vc_client* c, const char* nickname) { if (c == nullptr || nickname == nullptr) return VC_ERR_INVALID_ARG; return c->authenticate_guest(nickname); } vc_result vc_authenticate_user(vc_client* c, const char* username, const char* password) { if (c == nullptr || username == nullptr || password == nullptr) return VC_ERR_INVALID_ARG; return c->authenticate_user(username, password); } vc_result vc_join_channel(vc_client* c, uint32_t channel_id, const char* password) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->join_channel(channel_id, password); } vc_result vc_leave_channel(vc_client* c) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->leave_channel(); } vc_result vc_stream_start(vc_client* c, const vc_stream_desc* desc, uint32_t* out_stream_id) { if (c == nullptr || desc == nullptr) return VC_ERR_INVALID_ARG; return c->stream_start(*desc, out_stream_id); } vc_result vc_stream_stop(vc_client* c, uint32_t stream_id) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->stream_stop(stream_id); } vc_result vc_set_input_device(vc_client* c, uint32_t stream_id, const char* device_id) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->set_input_device(stream_id, device_id); } vc_result vc_set_input_mode(vc_client* c, vc_input_mode mode) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->set_input_mode(mode); } vc_result vc_set_push_to_talk(vc_client* c, int active) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->set_push_to_talk(active != 0); } vc_result vc_set_self_mute(vc_client* c, int mic_muted, int deafened) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->set_self_mute(mic_muted != 0, deafened != 0); } vc_result vc_set_remote_stream(vc_client* c, uint32_t user_id, uint32_t stream_id, float gain, int muted, int noise_reduction) { if (c == nullptr) return VC_ERR_INVALID_ARG; return c->set_remote_stream(user_id, stream_id, gain, muted != 0, noise_reduction != 0); } vc_result vc_send_text(vc_client* c, vc_text_scope scope, uint32_t target_id, const char* utf8) { if (c == nullptr || utf8 == nullptr) return VC_ERR_INVALID_ARG; return c->send_text(scope, target_id, utf8); } vc_result vc_list_devices(vc_client* c, vc_device_kind kind, vc_device_list* out) { if (c == nullptr || out == nullptr) return VC_ERR_INVALID_ARG; return c->list_devices(kind, out); } void vc_free_device_list(vc_device_list* list) { if (list == nullptr) return; /* Stub: no allocation yet. Real impl frees list->items here. */ list->items = nullptr; list->count = 0; } } // extern "C"