diff --git a/apps/android/native/rtc_bridge.cpp b/apps/android/native/rtc_bridge.cpp index fd133714..e34eb239 100644 --- a/apps/android/native/rtc_bridge.cpp +++ b/apps/android/native/rtc_bridge.cpp @@ -50,8 +50,8 @@ struct CallbackContext { Session* owner; bool controller; }; struct Session { jobject owner = nullptr; jmethodID event_method, audio_method, frame_method; - PeerPtr* identity = nullptr; - PeerPtr* controller = nullptr; + MiniRtcPeerPtr* identity = nullptr; + MiniRtcPeerPtr* controller = nullptr; CallbackContext identity_context{this, false}, controller_context{this, true}; std::string host, log_path, identity_login, controller_login, remote; int port; @@ -78,7 +78,7 @@ struct Session { android_controller::FileTransferSession files{ [this](const char* stream, const char* data, size_t size) { return controller && !stopping - ? SendReliableDataFrame(controller, data, size, stream) : -1; + ? MiniRtcSendReliableDataFrame(controller, data, size, stream) : -1; }, [this](const std::string& name, double progress, bool sending, const std::string& path) { Event(10, {{"name", name}, {"progress", progress}, {"sending", sending}, {"path", path}}); @@ -100,7 +100,7 @@ struct Session { } void Send(const char* stream, const std::string& data) { if (controller && !stopping && !data.empty()) - SendReliableDataFrame(controller, data.data(), data.size(), stream); + MiniRtcSendReliableDataFrame(controller, data.data(), data.size(), stream); } void Surface(JNIEnv* env, jobject surface) { std::lock_guard lock(render_mutex); @@ -131,25 +131,25 @@ struct Session { stopping = true; renderer.Stop(); if (controller) { - LeaveConnection(controller, remote.c_str()); - DestroyPeer(&controller); + MiniRtcLeaveConnection(controller, remote.c_str()); + MiniRtcDestroyPeer(&controller); } - if (identity) DestroyPeer(&identity); + if (identity) MiniRtcDestroyPeer(&identity); Environment scope; Surface(scope.env, nullptr); if (scope.env) scope.env->DeleteGlobalRef(owner); } }; -void Signal(SignalStatus status, const char*, size_t, void* user) { +void Signal(MiniRtcSignalStatus status, const char*, size_t, void* user) { auto* ctx = static_cast(user); - if (!ctx->controller && status == SignalStatus::SignalConnected && + if (!ctx->controller && status == MiniRtcSignalStatus::MiniRtcSignalConnected && !ctx->owner->stopping && ctx->owner->identity) { // Report after every identity login, including reconnects. The server // ignores client_info sent through the temporary C- controller peer. constexpr char info[] = R"({"type":"client_info","version":"android-native","platform":"android"})"; - SendSignalMessage(ctx->owner->identity, info, sizeof(info) - 1); + MiniRtcSendSignalMessage(ctx->owner->identity, info, sizeof(info) - 1); } if (!ctx->controller && ctx->owner->signal_status.exchange(status) != status) ++ctx->owner->signal_generation; @@ -169,14 +169,14 @@ void SignalMessage(const char* data, size_t size, void* user) { ctx->owner->Event(9, message); } } -void Connection(ConnectionStatus status, const char*, size_t, void* user) { +void Connection(MiniRtcConnectionStatus status, const char*, size_t, void* user) { auto* ctx = static_cast(user); if (ctx->controller) ctx->owner->Event(2, {{"status", status}}); } -void Network(const char* id, size_t size, TraversalMode mode, +void Network(const char* id, size_t size, MiniRtcTraversalMode mode, const MiniRtcNetTrafficStats* stats, const char*, size_t, void* user) { auto* ctx = static_cast(user); - if (!ctx->controller && mode == UnknownMode && id && size) { + if (!ctx->controller && mode == MiniRtcTraversalUnknown && id && size) { ctx->owner->Event(3, id, size); } else if (ctx->controller && stats) { ctx->owner->Event(7, android_controller::NetworkReport(*stats, mode)); @@ -250,7 +250,7 @@ void RenderVideo(Session* s, VideoPicture picture) { s->Event(5, {{"width", w}, {"height", h}}); } // Measure through display submission, using MiniRTC's calibrated capture clock. - const auto now = GetSystemTimeMicros(s->controller); + const auto now = MiniRtcGetSystemTimeMicros(s->controller); const double latency = android_controller::VideoLatencyMilliseconds( picture.captured_us, picture.received_us, now); Environment scope; @@ -259,8 +259,8 @@ void RenderVideo(Session* s, VideoPicture picture) { if (scope.env->ExceptionCheck()) scope.env->ExceptionClear(); } } -Params Parameters(Session* s, bool controller) { - Params p{}; +MiniRtcParams Parameters(Session* s, bool controller) { + MiniRtcParams p{}; std::snprintf(p.signal_server_ip, sizeof(p.signal_server_ip), "%s", s->host.c_str()); std::snprintf(p.log_path, sizeof(p.log_path), "%s", s->log_path.c_str()); p.signal_server_port = s->port; @@ -268,12 +268,12 @@ Params Parameters(Session* s, bool controller) { // MediaCodec returns retained Surface buffers; software fallback returns // pooled CPU NV12 with the same ownership contract. p.native_video_output = controller; - p.turn_mode = TurnAutoUdpTcp; + p.turn_mode = MiniRtcTurnAutoUdpTcp; p.enable_srtp = true; - p.video_content_type = VideoContentType::ScreenContent; - p.video_quality = QualityMedium; + p.video_content_type = MiniRtcVideoContentType::ScreenContent; + p.video_quality = MiniRtcVideoQualityMedium; p.video_frame_rate = 30; - p.video_degradation_preference = VideoDegradationPreference::Balanced; + p.video_degradation_preference = MiniRtcVideoDegradationPreference::Balanced; p.on_signal_status = Signal; p.on_connection_status = Connection; p.on_signal_message = SignalMessage; p.on_net_status_report = Network; p.on_receive_data_buffer = Data; @@ -344,8 +344,8 @@ extern "C" JNIEXPORT jlong JNICALL JNI_METHOD(nCreate)( if (MiniRtcConfigureLogging(MiniRtcLogOff, nullptr, nullptr) != 0) throw std::runtime_error("Unable to configure MiniRTC logging"); auto params = Parameters(s.get(), false); - s->identity = CreatePeer(¶ms); - if (!s->identity || Init(s->identity) != 0) return 0; + s->identity = MiniRtcCreatePeer(¶ms); + if (!s->identity || MiniRtcInit(s->identity) != 0) return 0; return reinterpret_cast(s.release()); } catch (const std::exception&) { return 0; } } @@ -356,15 +356,15 @@ extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nConnect)( s->controller_login = "C-" + String(env, identity); s->remote = String(env, remote); auto params = Parameters(s, true); - s->controller = CreatePeer(¶ms); + s->controller = MiniRtcCreatePeer(¶ms); if (!s->controller) return false; - AddAudioStream(s->controller, kAudioStream); - AddDataStream(s->controller, kDataStream, false); + MiniRtcAddAudioStream(s->controller, kAudioStream); + MiniRtcAddDataStream(s->controller, kDataStream, false); for (const char* name : {kMouseStream, kKeyboardStream, kControlStream, - kClipboardStream, kFileStream, kFileFeedbackStream}) AddDataStream(s->controller, name, true); - if (Init(s->controller) != 0) return false; + kClipboardStream, kFileStream, kFileFeedbackStream}) MiniRtcAddDataStream(s->controller, name, true); + if (MiniRtcInit(s->controller) != 0) return false; const auto join = s->remote + "@" + String(env, password); - return JoinConnection(s->controller, join.c_str()) == 0; + return MiniRtcJoinConnection(s->controller, join.c_str()) == 0; } extern "C" JNIEXPORT void JNICALL JNI_METHOD(nReady)(JNIEnv*, jclass, jlong handle) { auto* s = From(handle); if (!s || !s->controller) return; @@ -420,13 +420,13 @@ extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nVideoSettings)( if (!s || !s->controller || s->stopping || request_id < 0 || request_id > UINT32_MAX) return false; const auto data = android_controller::VideoSettingsMessage(quality, rate, preference, static_cast(request_id)); if (data.empty()) return false; - return SendReliableDataFrame(s->controller, data.data(), data.size(), kControlStream) == 0; + return MiniRtcSendReliableDataFrame(s->controller, data.data(), data.size(), kControlStream) == 0; } extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nSecureAttention)(JNIEnv*, jclass, jlong handle) { auto* s = From(handle); if (!s || !s->controller || s->stopping) return false; const auto data = android_controller::SecureAttentionMessage(); - return SendReliableDataFrame(s->controller, data.data(), data.size(), kControlStream) == 0; + return MiniRtcSendReliableDataFrame(s->controller, data.data(), data.size(), kControlStream) == 0; } extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nPrivacy)( JNIEnv*, jclass, jlong handle, jint flag, jboolean block_input) { @@ -434,7 +434,7 @@ extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nPrivacy)( if (!s || !s->controller || s->stopping) return false; const auto data = android_controller::PrivacyMessage(flag, block_input); return !data.empty() && - SendReliableDataFrame(s->controller, data.data(), data.size(), kControlStream) == 0; + MiniRtcSendReliableDataFrame(s->controller, data.data(), data.size(), kControlStream) == 0; } extern "C" JNIEXPORT void JNICALL JNI_METHOD(nFileDirectory)(JNIEnv* env, jclass, jlong handle, jstring directory) { auto* s = From(handle); if (s) s->files.SetDirectory(String(env, directory)); @@ -466,7 +466,7 @@ extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nAnnouncementRequest)( auto message = json::parse(bytes, nullptr, false); if (!message.is_object() || !message.contains("type") || !message["type"].is_string() || message["type"] != "announcements_list") return false; - return SendSignalMessage(s->identity, bytes.data(), bytes.size()) == 0; + return MiniRtcSendSignalMessage(s->identity, bytes.data(), bytes.size()) == 0; } extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nPresenceRequest)( JNIEnv* env, jclass, jlong handle, jbyteArray data) { @@ -483,7 +483,7 @@ extern "C" JNIEXPORT jboolean JNICALL JNI_METHOD(nPresenceRequest)( !message.contains("user_id") || !message["user_id"].is_string() || !message.contains("devices") || !message["devices"].is_array() || !message.contains("subscribe") || message["subscribe"] != true) return false; - return SendSignalMessage(s->identity, bytes.data(), bytes.size()) == 0; + return MiniRtcSendSignalMessage(s->identity, bytes.data(), bytes.size()) == 0; } extern "C" JNIEXPORT void JNICALL JNI_METHOD(nClipboard)( JNIEnv* env, jclass, jlong handle, jbyteArray data) { @@ -498,7 +498,7 @@ extern "C" JNIEXPORT void JNICALL JNI_METHOD(nSurface)(JNIEnv* env, jclass, jlon if (auto* s = From(handle)) { s->Surface(env, surface); if (surface && s->controller && !s->stopping) - RequestVideoKeyFrame(s->controller, MakeDisplayStreamId(s->display.load()).c_str()); + MiniRtcRequestVideoKeyFrame(s->controller, MakeDisplayStreamId(s->display.load()).c_str()); } } extern "C" JNIEXPORT void JNICALL JNI_METHOD(nDestroy)(JNIEnv*, jclass, jlong handle) { delete From(handle); } diff --git a/apps/android/test/native/controller_protocol_test.cpp b/apps/android/test/native/controller_protocol_test.cpp index 854d20e5..fd44f7b9 100644 --- a/apps/android/test/native/controller_protocol_test.cpp +++ b/apps/android/test/native/controller_protocol_test.cpp @@ -27,13 +27,13 @@ int main() { stats.data_inbound_stats.bitrate = 2000; stats.data_outbound_stats.bitrate = 3000; stats.total_inbound_stats.bitrate = UINT32_MAX; stats.total_outbound_stats.bitrate = 131'000; stats.total_inbound_stats.loss_rate = 1.2f; stats.rtt_ms = 40; stats.srtp_active = true; - auto json = android_controller::NetworkReport(stats, Relay); + auto json = android_controller::NetworkReport(stats, MiniRtcTraversalRelay); assert(json.at("mode") == 1 && json.at("srtp") == true && json.at("rtt") == 40); assert(json.at("video").at("inbound") == 8'000'000 && json.at("audio").at("outbound") == 128'000); assert(json.at("data").at("inbound") == 2000 && json.at("data").at("outbound") == 3000); assert(json.at("total").at("inbound").get() == UINT32_MAX); assert(std::abs(json.at("total").at("loss").get() - 1.2) < .001); stats.rtt_ms = -1; stats.srtp_active = false; - json = android_controller::NetworkReport(stats, UnknownMode); + json = android_controller::NetworkReport(stats, MiniRtcTraversalUnknown); assert(json.at("mode") == 2 && json.at("srtp") == false && json.at("rtt") == -1); } diff --git a/apps/cli/docs/automation-protocol.md b/apps/cli/docs/automation-protocol.md index 07a0d32f..dc9ebe0b 100644 --- a/apps/cli/docs/automation-protocol.md +++ b/apps/cli/docs/automation-protocol.md @@ -44,7 +44,7 @@ The output queue is bounded to 64 messages and 8 MiB; a blocked output pipe term `connect` returns immediately after initiating transport. Poll `status` until `state == "ready"`; this requires a frame from the current display generation. Status includes `transport_state`, `geometry_epoch`, `frame_age_ms`, `source_size`, `control_allowed`, `human_paused`, host platform, displays and transport diagnostics. -During initial `registering`, `SignalReconnecting` keeps the existing signaling peer and its backoff worker alive within the original 30-second connection deadline. Expiry in that phase reports `signaling_timeout`; expiry after submitting a device join reports `connection_timeout`. Certificate validation and login rejection terminate the attempt immediately. A signaling interruption after join submission also terminates the attempt. Explicit cancellation closes the peer and its retry worker. The MCP adapter forwards recognized status errors as an optional `error.reason` alongside its public error category. +During initial `registering`, `MiniRtcSignalReconnecting` keeps the existing signaling peer and its backoff worker alive within the original 30-second connection deadline. Expiry in that phase reports `signaling_timeout`; expiry after submitting a device join reports `connection_timeout`. Certificate validation and login rejection terminate the attempt immediately. A signaling interruption after join submission also terminates the attempt. Explicit cancellation closes the peer and its retry worker. The MCP adapter forwards recognized status errors as an optional `error.reason` alongside its public error category. ## Live video @@ -87,7 +87,7 @@ NV12 retains one latest picture in the I/O handoff and at most one unacknowledge `status.video_output` includes `transport`, `viewers`, I/O handoff `queued` / `queued_bytes`, aggregate `unacknowledged_bytes`, and `dropped` (handoff replacements plus per-viewer congestion skips). These diagnostics contain no video payload. The original receive-tap SPS/PPS and keyframe state remain available for H.264. -The MiniRTC `Params` structure appends `on_receive_encoded_video`, changing its ABI size. Rebuild consumers and MiniRTC together; zero-initialize `Params`. The callback borrows frame bytes on the receive/decode queue and must not retain the pointer. Returning nonzero requests a remote keyframe. No remote wire-protocol change is required. +The MiniRTC `MiniRtcParams` structure appends `on_receive_encoded_video`, changing its ABI size. Rebuild consumers and MiniRTC together; zero-initialize `MiniRtcParams`. The callback borrows frame bytes on the receive/decode queue and must not retain the pointer. Returning nonzero requests a remote keyframe. No remote wire-protocol change is required. ## Images and observations diff --git a/apps/cli/docs/source-provenance.md b/apps/cli/docs/source-provenance.md index 7fdce7d0..d1138341 100644 --- a/apps/cli/docs/source-provenance.md +++ b/apps/cli/docs/source-provenance.md @@ -7,7 +7,7 @@ CLI 从独立开发目录整合到 CrossDesk,入口、打包脚本、npm 启 - `ControllerSession` 的流名称、HostInformation 和输入参考 Android `rtc_bridge.cpp`;身份使用单 Peer 的 `cli` 临时注册协议;终端适配不依赖 JNI、Surface 或 GuiRuntime。 - 帧缓存遵守 `MiniRtcVideoFrame` 回调借用契约,直接复制到有界 CPU 存储,不跨回调保留 native 指针。 - PreviewSubscription 复用 wire 实现与对端 capability 字段,不新增被控端协议。 -- MCP 实时面板新增 MiniRTC 的 `on_receive_encoded_video` 回调,转发解码前的完整 H.264 Annex B 帧;回调及关键帧请求由当前子模块源码提供。`Params` 新增字段改变 ABI 大小,CLI 与 MiniRTC 必须一起重建;发布时同步记录包含该改动的子模块提交。 +- MCP 实时面板新增 MiniRTC 的 `on_receive_encoded_video` 回调,转发解码前的完整 H.264 Annex B 帧;回调及关键帧请求由当前子模块源码提供。`MiniRtcParams` 新增字段改变 ABI 大小,CLI 与 MiniRTC 必须一起重建;发布时同步记录包含该改动的子模块提交。 - 自动化图像编码复用 MiniRTC 已有的 libyuv 2025.8.14,并通过 Xmake 固定静态 libpng v1.6.59;libpng 的压缩依赖沿用平台 zlib。新增依赖的许可证和对应源码也应纳入正式发行的依赖材料。 MiniRTC 已在提交 `b9ee1fa7fe038fdf771f5dec1b1d561d78273f15` 中合入凭据日志脱敏:Join、排队 Join、取消 Join、Leave 四个日志点只记录 `@` 前的 ID,不记录密码。`apps/cli/scripts/prepare-deps.sh` 仅按主仓库记录初始化子模块,不再应用独立补丁;更新 MiniRTC 时只需更新子模块提交。共享子模块中的脱敏同样适用于桌面程序;该修改没有改变鉴权、TLS、TURN 或媒体协议。 diff --git a/apps/cli/docs/terminal-client.md b/apps/cli/docs/terminal-client.md index 20df14a9..9aae2cf6 100644 --- a/apps/cli/docs/terminal-client.md +++ b/apps/cli/docs/terminal-client.md @@ -35,9 +35,9 @@ crossdesk-cli 123456789 --server your-server.example --port 9099 需先部署支持 `cli` 注册的新版 crossdesk-server;旧服务端会登录失败,本客户端不会回退为普通设备身份。桥接 `status.client_id` 返回服务端分配的 ID。 -流程为创建主控 Peer、注册流 → 以 `cli` 注册 → SignalConnected 返回 `cli-xxxxxxxxx` → Join → Connected → 现有 HostInformation 握手 → 显示器选择、能力协商 → 视频。Init 返回 0 不是远端连接成功。连接总超时默认 30 秒;信令断开后结束本次会话,用户重新连接,不自动循环重试密码。 +流程为创建主控 Peer、注册流 → 以 `cli` 注册 → SignalConnected 返回 `cli-xxxxxxxxx` → Join → Connected → 现有 HostInformation 握手 → 显示器选择、能力协商 → 视频。MiniRtcInit 返回 0 不是远端连接成功。连接总超时默认 30 秒;信令断开后结束本次会话,用户重新连接,不自动循环重试密码。 -交互界面区分 `Connecting to server`(连接信令)、`Connecting to device`(连接设备)、`Connected, waiting for first frame`(已连接,等待首帧)和 `Displaying`(正在显示)。首帧前显示居中的等待提示及秒数;连接阶段从发起连接计时,首帧等待阶段从连接成功重新计时。首帧完整写入终端后才切换到 `Displaying` 并清除等待提示。已连接但暂时没有画面不会因此判为连接失败,也不代表中继未启用。状态栏右侧为接收视频码率,收到网络统计后显示 `P2P` 或 `RELAY`,码率按 bps、kbps、Mbps 显示;初始码率为零或很低时仍继续等待视频。 +交互界面区分 `MiniRtcConnectionConnecting to server`(连接信令)、`MiniRtcConnectionConnecting to device`(连接设备)、`MiniRtcConnectionConnected, waiting for first frame`(已连接,等待首帧)和 `Displaying`(正在显示)。首帧前显示居中的等待提示及秒数;连接阶段从发起连接计时,首帧等待阶段从连接成功重新计时。首帧完整写入终端后才切换到 `Displaying` 并清除等待提示。已连接但暂时没有画面不会因此判为连接失败,也不代表中继未启用。状态栏右侧为接收视频码率,收到网络统计后显示 `MiniRtcTraversalP2P` 或 `RELAY`,码率按 bps、kbps、Mbps 显示;初始码率为零或很低时仍继续等待视频。 保留 MiniRTC WSS 证书链与主机名验证、TURN 临时凭据下发及 SRTP 协商。未提供跳过证书检查的参数。SRTP 是否实际协商成功通过状态统计呈现;沿用现有 MiniRTC 对旧端的兼容性,不宣称所有旧端必然启用 SRTP。自建证书问题应修复证书/系统信任链。 diff --git a/apps/cli/main.cpp b/apps/cli/main.cpp index a6f28066..15ea38e1 100644 --- a/apps/cli/main.cpp +++ b/apps/cli/main.cpp @@ -617,8 +617,8 @@ int View(SessionOptions options, const std::string &device, const auto bps = st["network"]["video_bps"].get(); const auto traversal = st["network"]["traversal"].get(); bar.network = - std::string(traversal == P2P ? "P2P " - : traversal == Relay ? "RELAY " + std::string(traversal == MiniRtcTraversalP2P ? "P2P " + : traversal == MiniRtcTraversalRelay ? "RELAY " : "Video ") + (bps < 1000 ? std::to_string(bps) + " bps" : bps < 1000000 ? std::to_string(bps / 1000) + " kbps" diff --git a/apps/desktop/src/gui/application/gui_application.cpp b/apps/desktop/src/gui/application/gui_application.cpp index 41256f7b..b49f3b72 100644 --- a/apps/desktop/src/gui/application/gui_application.cpp +++ b/apps/desktop/src/gui/application/gui_application.cpp @@ -495,25 +495,25 @@ std::optional ParsePort(const slint::SharedString& text) { return port; } -std::string ConnectionStatusText(ConnectionStatus status, int language) { +std::string ConnectionStatusText(MiniRtcConnectionStatus status, int language) { switch (status) { - case ConnectionStatus::Connected: + case MiniRtcConnectionStatus::MiniRtcConnectionConnected: return localization::p2p_connected[language]; - case ConnectionStatus::Connecting: + case MiniRtcConnectionStatus::MiniRtcConnectionConnecting: return localization::p2p_connecting[language]; - case ConnectionStatus::Gathering: + case MiniRtcConnectionStatus::MiniRtcConnectionGathering: return localization::p2p_gathering[language]; - case ConnectionStatus::Disconnected: + case MiniRtcConnectionStatus::MiniRtcConnectionDisconnected: return localization::p2p_disconnected[language]; - case ConnectionStatus::NoSuchTransmissionId: + case MiniRtcConnectionStatus::MiniRtcConnectionNoSuchTransmissionId: return localization::no_such_id[language]; - case ConnectionStatus::IncorrectPassword: + case MiniRtcConnectionStatus::MiniRtcConnectionIncorrectPassword: return localization::reinput_password[language]; - case ConnectionStatus::Closed: + case MiniRtcConnectionStatus::MiniRtcConnectionClosed: return localization::p2p_closed[language]; - case ConnectionStatus::RemoteUnavailable: + case MiniRtcConnectionStatus::MiniRtcConnectionRemoteUnavailable: return localization::device_offline[language]; - case ConnectionStatus::Failed: + case MiniRtcConnectionStatus::MiniRtcConnectionFailed: default: return localization::p2p_failed[language]; } @@ -1913,7 +1913,7 @@ void GuiApplication::BindMainCallbacks(bool gallery_window) { main->on_recent_disconnect([this](slint::SharedString id) { const std::string remote_id(id); if (auto props = FindRemoteSession(remote_id); - props && props->connection_status_ == ConnectionStatus::Connected && + props && props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !props->closing_) { CloseStreamTab(props->remote_id_); SyncMainWindow(); @@ -2057,9 +2057,9 @@ void GuiApplication::BindMainCallbacks(bool gallery_window) { main->on_connection_acknowledge([this] { const auto props = FindRemoteSession(ui_->connection_dialog_remote_id); if (props) { - const ConnectionStatus status = props->connection_status_.load(); - if (status == ConnectionStatus::NoSuchTransmissionId || - status == ConnectionStatus::RemoteUnavailable) { + const MiniRtcConnectionStatus status = props->connection_status_.load(); + if (status == MiniRtcConnectionStatus::MiniRtcConnectionNoSuchTransmissionId || + status == MiniRtcConnectionStatus::MiniRtcConnectionRemoteUnavailable) { CloseStreamTab(props->remote_id_); re_enter_remote_id_ = true; } @@ -2216,13 +2216,13 @@ void GuiApplication::BindStreamCallbacks() { action.type = ControlType::display_id; action.d = index; const std::string message = action.to_json(); - SendReliableDataFrame(props->peer_, message.c_str(), message.size(), + MiniRtcSendReliableDataFrame(props->peer_, message.c_str(), message.size(), props->control_data_label_.c_str()); }); stream->on_send_shortcut([this](slint::SharedString shortcut) { auto props = SelectedSession(); if (!props || !props->peer_ || !props->control_mouse_ || - props->connection_status_.load() != ConnectionStatus::Connected) { + props->connection_status_.load() != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { return; } const std::string name(shortcut); @@ -2237,13 +2237,13 @@ void GuiApplication::BindStreamCallbacks() { ? ServiceCommandFlag::send_sas : ServiceCommandFlag::lock_workstation; const std::string message = action.to_json(); - SendReliableDataFrame(props->peer_, message.c_str(), message.size(), + MiniRtcSendReliableDataFrame(props->peer_, message.c_str(), message.size(), props->control_data_label_.c_str()); }); const auto send_privacy = [this](bool relock) { auto props = SelectedSession(); if (!props || !props->peer_ || (!relock && !props->control_mouse_) || - props->connection_status_.load() != ConnectionStatus::Connected) return; + props->connection_status_.load() != MiniRtcConnectionStatus::MiniRtcConnectionConnected) return; RemoteAction action{}; action.type = ControlType::privacy_command; { @@ -2265,7 +2265,7 @@ void GuiApplication::BindStreamCallbacks() { props->privacy_request_revision_ = status.revision; } const auto message = action.to_json(); - if (SendReliableDataFrame(props->peer_, message.data(), message.size(), + if (MiniRtcSendReliableDataFrame(props->peer_, message.data(), message.size(), props->control_data_label_.c_str()) != 0) { std::lock_guard lock(props->privacy_status_mutex_); props->privacy_command_pending_ = false; @@ -2295,7 +2295,7 @@ void GuiApplication::BindStreamCallbacks() { int preference) { auto props = SelectedSession(); if (!props || !props->peer_ || - props->connection_status_.load() != ConnectionStatus::Connected) + props->connection_status_.load() != MiniRtcConnectionStatus::MiniRtcConnectionConnected) return; RemoteAction action{}; action.type = ControlType::video_settings; @@ -2308,7 +2308,7 @@ void GuiApplication::BindStreamCallbacks() { if (!props->video_settings_supported_) return; action.vs.request_id = props->video_settings_.request_id + 1; const auto message = action.to_json(); - if (SendReliableDataFrame(props->peer_, message.data(), message.size(), + if (MiniRtcSendReliableDataFrame(props->peer_, message.data(), message.size(), props->control_data_label_.c_str()) != 0) return; props->video_settings_ = action.vs; @@ -2773,7 +2773,7 @@ void GuiApplication::ShareLocalCursorState() { std::shared_lock lock(connection_status_mutex_); connected_controllers.reserve(connection_status_.size()); for (const auto& [remote_id, status] : connection_status_) { - if (status == ConnectionStatus::Connected) { + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { connected_controllers.push_back(remote_id); } } @@ -2997,7 +2997,7 @@ bool GuiApplication::RequestPasswordChange(const std::string &password) { {"request_id", request_id}, {"new_password", password}}; const std::string message = request.dump(); - if (SendSignalMessage(peer_, message.data(), message.size()) != 0) { + if (MiniRtcSendSignalMessage(peer_, message.data(), message.size()) != 0) { { std::lock_guard lock(password_change_mutex_); password_change_pending_ = false; @@ -3128,7 +3128,7 @@ void GuiApplication::HandleCredentialRecovery() { } const auto message = nlohmann::json{{"type", "change_password"}, {"request_id", request_id}, {"new_password", password}}.dump(); - if (SendSignalMessage(peer_, message.data(), message.size()) != 0) { + if (MiniRtcSendSignalMessage(peer_, message.data(), message.size()) != 0) { std::lock_guard lock(password_change_mutex_); password_change_result_ready_ = true; password_change_result_uncertain_ = true; @@ -3204,7 +3204,7 @@ void GuiApplication::SyncAnnouncements() { const auto request = announcements_.TakePendingRequest(); if (!request.is_null()) { const auto payload = request.dump(); - if (!peer_ || SendSignalMessage(peer_, payload.data(), payload.size()) != 0) + if (!peer_ || MiniRtcSendSignalMessage(peer_, payload.data(), payload.size()) != 0) announcements_.Failed(request["request_id"]); } if (ui_->announcement_version == announcements_.Version()) return; @@ -3315,7 +3315,7 @@ void GuiApplication::SyncMainWindow() { main->set_signal_connected(signal_online); main->set_signal_reconnecting(signal_reconnecting); main->set_signal_tls_error(signal_status_ == - SignalStatus::SignalTlsCertError); + MiniRtcSignalStatus::MiniRtcSignalTlsCertError); main->set_update_available(update_available_); switch (update_checker_->status()) { case UpdateChecker::Status::Idle: @@ -3389,7 +3389,7 @@ void GuiApplication::SyncMainWindow() { } const auto is_connected = [this](const std::string& id) { const auto props = FindRemoteSession(id); - return props && props->connection_status_ == ConnectionStatus::Connected && + return props && props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !props->closing_; }; const auto preview_size = ui_->recent_preview_resolution.Update( @@ -3512,8 +3512,8 @@ void GuiApplication::SyncConnectionDialog() { ui_->connection_password_initialized = false; } ui_->connection_dialog_remote_id = props->remote_id_; - const ConnectionStatus status = props->connection_status_.load(); - if (status == ConnectionStatus::Connected && !ui_->gallery_auth_id.empty()) { + const MiniRtcConnectionStatus status = props->connection_status_.load(); + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !ui_->gallery_auth_id.empty()) { ui_->gallery_auth_id.clear(); show_connection_status_window_ = false; ui_->main->set_connection_dialog_open(false); @@ -3522,9 +3522,9 @@ void GuiApplication::SyncConnectionDialog() { } const auto auth = props->connection_auth_.Get(); const bool password_required = auth.password_required || - (status == ConnectionStatus::IncorrectPassword && auth.validating); + (status == MiniRtcConnectionStatus::MiniRtcConnectionIncorrectPassword && auth.validating); const bool pending = !password_required && - (status == ConnectionStatus::Connecting || status == ConnectionStatus::Gathering); + (status == MiniRtcConnectionStatus::MiniRtcConnectionConnecting || status == MiniRtcConnectionStatus::MiniRtcConnectionGathering); std::string text; if (password_required) { text = auth.validating @@ -3855,7 +3855,7 @@ void GuiApplication::SyncStreamWindow() { tab.title = UiText( props->remote_host_name_.empty() ? id : props->remote_host_name_); tab.connected = - props->connection_status_.load() == ConnectionStatus::Connected; + props->connection_status_.load() == MiniRtcConnectionStatus::MiniRtcConnectionConnected; tabs_by_id.emplace(id, std::move(tab)); } } @@ -3905,10 +3905,10 @@ void GuiApplication::SyncStreamWindow() { if (!props) { return; } - const ConnectionStatus status = props->connection_status_.load(); + const MiniRtcConnectionStatus status = props->connection_status_.load(); bool remote_update_available = false; HostPlatform remote_platform = HostPlatform::Unknown; - if (status == ConnectionStatus::Connected) { + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { std::lock_guard lock(props->remote_version_mutex_); remote_platform = props->remote_platform_; // Wait for host_info: a version still in transit is not a legacy peer. @@ -3925,14 +3925,14 @@ void GuiApplication::SyncStreamWindow() { SetStreamKeyboardFocus(false); } const bool waiting_for_frame = - status == ConnectionStatus::Connected && + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !(*ui_->stream)->get_has_frame(); // Once the peer is connected, the frame-waiting hint replaces the // connection status. Keeping these states mutually exclusive also avoids a // transient overlap when both properties are synchronized in one tick. (*ui_->stream) ->set_status_text(UiText( - status == ConnectionStatus::Connected + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected ? std::string{} : ConnectionStatusText(status, localization_language_index_))); (*ui_->stream) @@ -3949,7 +3949,7 @@ void GuiApplication::SyncStreamWindow() { status, props->privacy_status_received_, props->privacy_command_pending_, now - props->privacy_status_tick_, now - props->privacy_command_tick_); const bool connected = - props->connection_status_.load() == ConnectionStatus::Connected; + props->connection_status_.load() == MiniRtcConnectionStatus::MiniRtcConnectionConnected; (*ui_->stream)->set_privacy_unlock_visible(connected && props->privacy_unlock_notice_); (*ui_->stream)->set_privacy_can_lock(connected && props->privacy_desktop_available_ && props->privacy_status_received_ && status.supported && @@ -3977,7 +3977,7 @@ void GuiApplication::SyncStreamWindow() { { std::lock_guard lock(props->remote_cursor_state_mutex_); remote_cursor_active = - status == ConnectionStatus::Connected && props->control_mouse_ && + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && props->control_mouse_ && props->remote_cursor_state_received_; if (remote_cursor_active) { remote_cursor_shape = static_cast( @@ -3998,7 +3998,7 @@ void GuiApplication::SyncStreamWindow() { props->video_settings_.request_id = request_id; } (*ui_->stream) - ->set_video_settings_enabled(status == ConnectionStatus::Connected && + ->set_video_settings_enabled(status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && props->video_settings_supported_); (*ui_->stream) ->set_video_settings_feedback(UiText( @@ -4035,13 +4035,13 @@ void GuiApplication::SyncStreamWindow() { const auto net = props->net_traffic_stats_.Load(); const auto codecs = props->net_traffic_stats_.LoadVideoCodecs(); (*ui_->stream)->set_stats_encoder(UiText( - status == ConnectionStatus::Connected && !codecs.remote_encoder.empty() + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !codecs.remote_encoder.empty() ? codecs.remote_encoder : "—")); (*ui_->stream)->set_stats_decoder(UiText( - status == ConnectionStatus::Connected && !codecs.local_decoder.empty() + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !codecs.local_decoder.empty() ? codecs.local_decoder : "—")); (*ui_->stream)->set_stats_encryption_enabled( - status == ConnectionStatus::Connected && net.srtp_active); + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && net.srtp_active); std::vector stats_rows; stats_rows.reserve(4); const auto append_stats_row = [&](const std::string& label, @@ -4067,7 +4067,7 @@ void GuiApplication::SyncStreamWindow() { props->video_height_))); (*ui_->stream) ->set_stats_connection_mode( - UiText(props->traversal_mode_ == TraversalMode::P2P + UiText(props->traversal_mode_ == MiniRtcTraversalMode::MiniRtcTraversalP2P ? localization::connection_mode_direct [localization_language_index_] : localization::connection_mode_relay @@ -4095,7 +4095,7 @@ void GuiApplication::SyncStreamWindow() { } (*ui_->stream)->set_stats_fps(UiText(std::to_string(props->fps_))); if (!props->net_traffic_stats_button_pressed_ || - status != ConnectionStatus::Connected) { + status != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { props->video_latency_snapshot_.reset(); } else if (refresh_stats) { props->video_latency_snapshot_ = props->video_latency_->Get(fps_now); @@ -4109,7 +4109,7 @@ void GuiApplication::SyncStreamWindow() { : "—")); const auto display_rtt = props->net_traffic_stats_.SmoothedRttMs(fps_now); const bool rtt_available = props->net_traffic_stats_button_pressed_ && - status == ConnectionStatus::Connected && + status == MiniRtcConnectionStatus::MiniRtcConnectionConnected && display_rtt.has_value(); std::string connection_latency = "—"; if (rtt_available) { @@ -4119,7 +4119,7 @@ void GuiApplication::SyncStreamWindow() { : std::to_string(static_cast(std::lround(*display_rtt))) + " ms"; } (*ui_->stream)->set_stats_connection_latency(UiText(connection_latency)); - if (refresh_stats && status == ConnectionStatus::Connected) { + if (refresh_stats && status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { LOG_DEBUG("Latency stats: remote={} video_ms={} video_samples={} " "rtt_raw_ms={} rtt_display_ms={}", props->remote_id_, latency ? latency->average_ms : -1, @@ -4416,7 +4416,7 @@ void GuiApplication::SyncServerWindow() { has_connected_controller = std::any_of(connection_status_.begin(), connection_status_.end(), [](const auto& entry) { - return entry.second == ConnectionStatus::Connected; + return entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; }); } @@ -4478,7 +4478,7 @@ void GuiApplication::SyncServerWindow() { std::shared_lock lock(connection_status_mutex_); controllers.reserve(connection_status_.size()); for (const auto& [id, status] : connection_status_) { - if (status != ConnectionStatus::Connected) continue; + if (status != MiniRtcConnectionStatus::MiniRtcConnectionConnected) continue; const auto host = connection_host_names_.find(id); const std::string name = host != connection_host_names_.end() && !host->second.empty() @@ -5033,12 +5033,12 @@ void GuiApplication::ApplySettingsFromConfig(bool reconnect) { } else { const bool av1 = config_center_->GetVideoEncodeFormat() == ConfigCenter::VIDEO_ENCODE_FORMAT::AV1; - const auto turn = static_cast(config_center_->GetTurnMode()); + const auto turn = static_cast(config_center_->GetTurnMode()); if (av1 != params_.av1_encoding || turn != params_.turn_mode) { // Update the listening peer for incoming connections and the template // copied by ConnectTo for outgoing connections. Existing sessions retain // the codec/ICE snapshot with which they negotiated. - if (!peer_ || UpdateConnectionSettings(peer_, true, av1, turn) == 0) { + if (!peer_ || MiniRtcUpdateConnectionSettings(peer_, true, av1, turn) == 0) { params_.av1_encoding = av1; params_.turn_mode = turn; } else { @@ -5139,7 +5139,7 @@ void GuiApplication::SelectStreamTab(int index) { start_keyboard_capturer_ = selected_session && selected_session->control_mouse_ && selected_session->connection_status_.load() == - ConnectionStatus::Connected; + MiniRtcConnectionStatus::MiniRtcConnectionConnected; } if (clipboard_resumed) { // Flush a copy made in another local app before the next paste shortcut, @@ -5366,7 +5366,7 @@ void GuiApplication::SendKeyInput(const std::string& text, bool pressed, (void)meta; auto props = SelectedSession(); if (!props || !props->peer_ || !props->control_mouse_ || - props->connection_status_.load() != ConnectionStatus::Connected) { + props->connection_status_.load() != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { return; } @@ -5423,7 +5423,7 @@ void GuiApplication::SyncAudioPlayback() { std::shared_lock lock(remote_sessions_mutex_); for (const auto& [id, props] : remote_sessions_) { const bool allowed = !props->closing_ && - props->connection_status_ == ConnectionStatus::Connected && + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected && props->audio_capture_button_pressed_ && ((wall_visible && props->wall_managed_) || (stream_active && props->tab_opened_ && props->tab_selected_)); @@ -5898,7 +5898,7 @@ void GuiApplication::GalleryAction(const std::string& action, auto props = FindRemoteSession(value); if (value != ui_->gallery_focus || !props || !props->peer_ || props->closing_ || - props->connection_status_ != ConnectionStatus::Connected) + props->connection_status_ != MiniRtcConnectionStatus::MiniRtcConnectionConnected) return; { std::lock_guard lock(props->gallery_frame_mutex_); @@ -5955,7 +5955,7 @@ void GuiApplication::GalleryAction(const std::string& action, for (const auto& id : ids) { if (auto props = FindRemoteSession(id); props && !props->closing_ && - props->connection_status_ == ConnectionStatus::Connected) { + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { if (action == "mute") { MuteRemoteAudio(props); } else { @@ -6236,7 +6236,7 @@ void GuiApplication::SyncGallery() { // control. Followers can report different shapes without replacing it. auto controlled = FindRemoteSession(ui_->gallery_control_id); if (!visible || !controlled || controlled->closing_ || - controlled->connection_status_ != ConnectionStatus::Connected) { + controlled->connection_status_ != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { ReleaseControl(); } else { HostPlatform platform; @@ -6330,7 +6330,7 @@ void GuiApplication::SyncGallery() { std::shared_lock lock(remote_sessions_mutex_); for (const auto& [id, props] : remote_sessions_) if (props && !props->lan_session_ && !props->closing_ && - props->connection_status_ == ConnectionStatus::Connected) + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected) connected_ids.push_back(id); } std::sort(connected_ids.begin(), connected_ids.end()); @@ -6338,15 +6338,15 @@ void GuiApplication::SyncGallery() { for (const auto& id : connected_ids) { const auto props = FindRemoteSession(id); if (!props || props->closing_ || - props->connection_status_ != ConnectionStatus::Connected) + props->connection_status_ != MiniRtcConnectionStatus::MiniRtcConnectionConnected) continue; ui::GalleryNetworkDevice device{}; device.name = UiText(name(id)); device.id = UiText(FormatPeerId(id.c_str())); const auto mode = props->traversal_mode_.load(); - device.mode = UiText(mode == TraversalMode::P2P + device.mode = UiText(mode == MiniRtcTraversalMode::MiniRtcTraversalP2P ? tr("直连") - : mode == TraversalMode::UnknownMode + : mode == MiniRtcTraversalMode::MiniRtcTraversalUnknown ? tr("等待统计") : tr("中继")); device.inbound = device.outbound = device.loss = "—"; @@ -6374,7 +6374,7 @@ void GuiApplication::SyncGallery() { // Missing/stale reports cannot confirm either encrypted or plaintext. device.encryption_known = has_report; device.encryption_enabled = has_report && stats.srtp_active; - if (mode != TraversalMode::UnknownMode && has_report) { + if (mode != MiniRtcTraversalMode::MiniRtcTraversalUnknown && has_report) { device.inbound = UiText(FormatBitrate(stats.total_inbound_stats.bitrate)); device.outbound = UiText(FormatBitrate(stats.total_outbound_stats.bitrate)); // MiniRTC's total loss is a sum of media fractions, not an aggregate. @@ -6416,14 +6416,14 @@ void GuiApplication::SyncGallery() { MuteRemoteAudio(props); } const auto status = props ? props->connection_status_.load() - : ConnectionStatus::Closed; + : MiniRtcConnectionStatus::MiniRtcConnectionClosed; const bool usable = props && props->peer_ && !props->closing_; const bool connecting = usable && - (status == ConnectionStatus::Connecting || - status == ConnectionStatus::Gathering); + (status == MiniRtcConnectionStatus::MiniRtcConnectionConnecting || + status == MiniRtcConnectionStatus::MiniRtcConnectionGathering); if (!signal_connected_) operation.state = OperationState::Finished; - else if (!(usable && status == ConnectionStatus::Connected) && + else if (!(usable && status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) && (!connecting || operation.password)) { std::string password = operation.password.value_or(""); bool remember = operation.remember_password; @@ -6449,7 +6449,7 @@ void GuiApplication::SyncGallery() { operation.password.reset(); } } else if (!props || !props->peer_ || - props->connection_status_ != ConnectionStatus::Connected) { + props->connection_status_ != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { operation.state = OperationState::Finished; } else if (operation.action == "file") { if (!transfers_.ProcessSelectedFile(operation.file, props, @@ -6472,12 +6472,12 @@ void GuiApplication::SyncGallery() { else if (operation.action == "connect") { const auto status = props->connection_status_.load(); const auto auth = props->connection_auth_.Get(); - if (status == ConnectionStatus::Connected) + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) operation.state = OperationState::Finished; else if (auth.password_required && !auth.validating) operation.state = OperationState::AwaitingPassword; - else if (status != ConnectionStatus::Connecting && - status != ConnectionStatus::Gathering && !auth.validating) + else if (status != MiniRtcConnectionStatus::MiniRtcConnectionConnecting && + status != MiniRtcConnectionStatus::MiniRtcConnectionGathering && !auth.validating) operation.state = OperationState::Finished; else if (operation.state == OperationState::AwaitingPassword) { operation.state = OperationState::Running; @@ -6486,7 +6486,7 @@ void GuiApplication::SyncGallery() { operation.state = OperationState::Finished; CloseStreamTab(operation.id); } - } else if (props->connection_status_ != ConnectionStatus::Connected) + } else if (props->connection_status_ != MiniRtcConnectionStatus::MiniRtcConnectionConnected) operation.state = OperationState::Finished; else if (operation.action == "file") { std::lock_guard lock(props->file_transfer_.file_transfer_list_mutex_); @@ -6594,7 +6594,7 @@ void GuiApplication::SyncGallery() { tile.host_name = UiText(props->remote_host_name_); } tile.connected = props && - props->connection_status_ == ConnectionStatus::Connected && + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !props->closing_; const auto online = device_presence_cache_.GetOnline(id); tile.online = tile.connected || online.value_or(false); @@ -6648,7 +6648,7 @@ void GuiApplication::SyncGallery() { }; for (size_t i = 0; i < ids.size(); ++i) { const auto props = FindRemoteSession(ids[i]); - if (props && props->connection_status_ == ConnectionStatus::Connected && + if (props && props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected && !props->closing_) { ++connected; } @@ -6684,7 +6684,7 @@ void GuiApplication::SyncGallery() { device.name = UiText(name(id)); const auto props = FindRemoteSession(id); device.connected = props && !props->closing_ && - props->connection_status_ == ConnectionStatus::Connected; + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected; if (device.connected) { selected_audio_available = true; selected_audio_muted &= !props->audio_capture_button_pressed_; @@ -6738,7 +6738,7 @@ void GuiApplication::SyncGallery() { props->gallery_rgba_.reset(); } if (props->preview_subscription_supported_ && - props->connection_status_ == ConnectionStatus::Connected) { + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { if (wall_mode && !ui_->gallery_hidden_active_ids.count(id)) props->wall_managed_ = true; // Keep session quality and audio; wall bandwidth, resolution and @@ -6814,7 +6814,7 @@ void GuiApplication::SyncGallery() { demand.request_id = ++props->preview_request_; if (!demand.request_id) demand.request_id = ++props->preview_request_; const auto message = demand.ToJson().dump(); - if (SendReliableDataFrame(props->peer_, message.data(), message.size(), + if (MiniRtcSendReliableDataFrame(props->peer_, message.data(), message.size(), props->control_data_label_.c_str()) == 0) props->preview_requested_ = demand; props->preview_request_at_ = now; diff --git a/apps/desktop/src/gui/features/clipboard/clipboard_controller.cpp b/apps/desktop/src/gui/features/clipboard/clipboard_controller.cpp index cdfdd538..c0aee872 100644 --- a/apps/desktop/src/gui/features/clipboard/clipboard_controller.cpp +++ b/apps/desktop/src/gui/features/clipboard/clipboard_controller.cpp @@ -359,7 +359,7 @@ void ClipboardController::SendDeferredLocalText() { return; } - const int ret = SendReliableDataFrame( + const int ret = MiniRtcSendReliableDataFrame( session->peer_, last_text_.data(), last_text_.size(), session->clipboard_label_.c_str()); if (ret != 0) { @@ -388,7 +388,7 @@ int ClipboardController::SendToPeers(const std::string &text) { } const int ret = - SendReliableDataFrame(props->peer_, text.data(), text.size(), + MiniRtcSendReliableDataFrame(props->peer_, text.data(), text.size(), props->clipboard_label_.c_str()); if (ret != 0) { LOG_WARN("Failed to send clipboard data to peer [{}], ret={}", diff --git a/apps/desktop/src/gui/features/devices/session_device_manager.cpp b/apps/desktop/src/gui/features/devices/session_device_manager.cpp index 7040088c..0e2c4d0a 100644 --- a/apps/desktop/src/gui/features/devices/session_device_manager.cpp +++ b/apps/desktop/src/gui/features/devices/session_device_manager.cpp @@ -48,9 +48,9 @@ SessionDeviceManager::SessionDeviceManager(GuiRuntime &owner) frame.size = size; for (const auto& id : owner_.ConnectedControllers()) owner_.WithController( - id, [&](PeerPtr* peer, const std::string& wire) { - frame.captured_timestamp = GetSystemTimeMicros(peer); - return SendAudioFrameToPeer(peer, &frame, + id, [&](MiniRtcPeerPtr* peer, const std::string& wire) { + frame.captured_timestamp = MiniRtcGetSystemTimeMicros(peer); + return MiniRtcSendAudioFrameToPeer(peer, &frame, owner_.audio_label_.c_str(), wire.data(), wire.size()); }); @@ -239,11 +239,11 @@ int SessionDeviceManager::InitializeScreenCapturer() { if (!owner_.preview_subscriptions_.ShouldSend(remote_id, now_time, stream_id)) continue; if (owner_.WithController( - remote_id, [&](PeerPtr* peer, const std::string& wire) { + remote_id, [&](MiniRtcPeerPtr* peer, const std::string& wire) { if (resumed_after_gap || stream_changed) - RequestVideoKeyFrame(peer, stream_id.c_str()); - frame.captured_timestamp = GetSystemTimeMicros(peer); - return SendVideoFrameToPeer(peer, &frame, stream_id.c_str(), + MiniRtcRequestVideoKeyFrame(peer, stream_id.c_str()); + frame.captured_timestamp = MiniRtcGetSystemTimeMicros(peer); + return MiniRtcSendVideoFrameToPeer(peer, &frame, stream_id.c_str(), wire.data(), wire.size()); }) != 0) ++send_errors; @@ -285,7 +285,7 @@ bool SessionDeviceManager::ShouldCaptureCursor() const { std::shared_lock lock(owner_.connection_status_mutex_); return std::any_of(owner_.connection_status_.begin(), owner_.connection_status_.end(), [](const auto& entry) { - return entry.second == ConnectionStatus::Connected && + return entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnected && entry.first.find("web") != std::string::npos; }); } @@ -294,7 +294,7 @@ bool SessionDeviceManager::HasConnectedController() const { std::shared_lock lock(owner_.connection_status_mutex_); return std::any_of(owner_.connection_status_.begin(), owner_.connection_status_.end(), [](const auto& entry) { - return entry.second == ConnectionStatus::Connected; + return entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; }); } diff --git a/apps/desktop/src/gui/features/file_transfer/file_transfer_manager.cpp b/apps/desktop/src/gui/features/file_transfer/file_transfer_manager.cpp index b2c8159f..4c5f71e4 100644 --- a/apps/desktop/src/gui/features/file_transfer/file_transfer_manager.cpp +++ b/apps/desktop/src/gui/features/file_transfer/file_transfer_manager.cpp @@ -108,7 +108,7 @@ void FileTransferManager::ProcessQueue(std::shared_ptr props) { workers_.push_back(std::async(std::launch::async, [this, props, file] { auto& state = state_for(props); const auto id = file.file_id; - PeerPtr* peer; + MiniRtcPeerPtr* peer; std::shared_ptr events; { std::shared_lock lock(owner_.remote_sessions_mutex_); @@ -126,7 +126,7 @@ void FileTransferManager::ProcessQueue(std::shared_ptr props) { auto callback = events->EnterCallback(); if (!callback || !events->DataAllowed()) return -1; const auto wire_id = events->WireId(file.remote_id); - return SendReliableDataFrameToPeer( + return MiniRtcSendReliableDataFrameToPeer( peer, data, size, file.file_label.c_str(), wire_id.data(), wire_id.size()); }, file_transfer::Session::Progress{}); @@ -176,7 +176,7 @@ void FileTransferManager::ProcessQueue(std::shared_ptr props) { // Release that reservation even though no data chunk was ever sent. const auto packet = EncodeFileCancel(id, 0); const auto wire_id = events->WireId(file.remote_id); - SendReliableDataFrameToPeer(peer, packet.data(), packet.size(), + MiniRtcSendReliableDataFrameToPeer(peer, packet.data(), packet.size(), file.file_label.c_str(), wire_id.data(), wire_id.size()); } } @@ -347,7 +347,7 @@ void FileTransferManager::UpdateReceiveProgress( std::shared_ptr FileTransferManager::ReceiverFor( PeerEventHandler* handler, const std::string& remote) { const auto props = owner_.FindRemoteSession(remote); - PeerPtr* peer; + MiniRtcPeerPtr* peer; std::shared_ptr events; { std::shared_lock lock(owner_.remote_sessions_mutex_); @@ -382,7 +382,7 @@ std::shared_ptr FileTransferManager::ReceiverFor( if (!callback || !events->DataAllowed()) return -1; const auto bytes = EncodeFileTransferAck(ack); const auto wire_id = events->WireId(remote); - return SendReliableDataFrameToPeer( + return MiniRtcSendReliableDataFrameToPeer( peer, bytes.data(), bytes.size(), kFileFeedbackStream, wire_id.data(), wire_id.size()); }); @@ -529,11 +529,11 @@ bool FileTransferManager::SendBrowser(const std::string& remote, const FileBrows if (!events) return false; auto callback = events->EnterCallback(); if (!callback || !events->DataAllowed()) return false; - PeerPtr* peer = events->IsDirect() ? events->DirectPeer() : props ? props->peer_ : owner_.peer_; + MiniRtcPeerPtr* peer = events->IsDirect() ? events->DirectPeer() : props ? props->peer_ : owner_.peer_; const auto data = message.dump(-1, ' ', false, FileBrowser::Json::error_handler_t::replace); if (!peer || data.size() > 60000) return false; const auto wire_id = events->WireId(remote); - return SendReliableDataFrameToPeer(peer, data.data(), data.size(), + return MiniRtcSendReliableDataFrameToPeer(peer, data.data(), data.size(), owner_.control_data_label_.c_str(), wire_id.data(), wire_id.size()) == 0; } diff --git a/apps/desktop/src/gui/rendering/video_latency.h b/apps/desktop/src/gui/rendering/video_latency.h index b6d3de83..c4559356 100644 --- a/apps/desktop/src/gui/rendering/video_latency.h +++ b/apps/desktop/src/gui/rendering/video_latency.h @@ -22,7 +22,7 @@ namespace crossdesk { class VideoLatencyStats; // Travels with the exact queued pixels, including native frames. Its clock is -// translated once at the receive callback; rendering needs no live PeerPtr. +// translated once at the receive callback; rendering needs no live MiniRtcPeerPtr. struct VideoLatencyFrame { using Clock = std::chrono::steady_clock; std::shared_ptr stats; diff --git a/apps/desktop/src/gui/runtime/connection_runtime.cpp b/apps/desktop/src/gui/runtime/connection_runtime.cpp index 8d453576..7ce0530a 100644 --- a/apps/desktop/src/gui/runtime/connection_runtime.cpp +++ b/apps/desktop/src/gui/runtime/connection_runtime.cpp @@ -32,8 +32,8 @@ bool GuiRuntime::HasActiveSession() { std::shared_lock lock(connection_status_mutex_); return std::any_of(connection_status_.begin(), connection_status_.end(), [](const auto& entry) { - return entry.second == ConnectionStatus::Connecting || - entry.second == ConnectionStatus::Connected; + return entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnecting || + entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; }); } @@ -57,7 +57,7 @@ void GuiRuntime::UnmuteRemoteAudio(const std::shared_ptr& props) action.type = ControlType::audio_capture; action.a = true; const auto message = action.to_json(); - SendReliableDataFrame(props->peer_, message.data(), message.size(), + MiniRtcSendReliableDataFrame(props->peer_, message.data(), message.size(), props->control_data_label_.c_str()); } @@ -79,7 +79,7 @@ void GuiRuntime::HandleConnectionStatusChange() { const auto message = BuildDevicePresenceRequest(client_id_, recent_connection_ids_, true, {}, gallery_presence_ids_).dump(); - if (SendSignalMessage(peer_, message.data(), message.size()) == 0) { + if (MiniRtcSendSignalMessage(peer_, message.data(), message.size()) == 0) { next_presence_refresh_at_ = now + kPresenceRefreshInterval; } else { need_to_send_recent_connections_ = true; @@ -207,7 +207,7 @@ void GuiRuntime::HandleServerControllerDisconnected( codec_status_controllers_.erase(remote_id); privacy_sessions_.Disconnected(remote_id); for (const auto& [id, status] : connection_status_) { - if (status != ConnectionStatus::Connected) { + if (status != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { continue; } has_connected_controller = true; @@ -296,7 +296,7 @@ int GuiRuntime::RequestSingleDevicePresence(const std::string& remote_id, gallery_presence_ids_) .dump(); - int ret = SendSignalMessage(peer_, s.data(), s.size()); + int ret = MiniRtcSendSignalMessage(peer_, s.data(), s.size()); if (ret != 0) { std::lock_guard lock(pending_presence_probe_mutex_); pending_presence_probe_ = false; @@ -315,7 +315,7 @@ int GuiRuntime::ForceSignalReconnect() { LOG_WARN("Signal reconnect requested with no connection peer"); return -1; } - return ReconnectSignal(peer_); + return MiniRtcReconnectSignal(peer_); } void GuiRuntime::CloseRemoteSession(std::shared_ptr props) { @@ -332,7 +332,7 @@ void GuiRuntime::CloseRemoteSession(std::shared_ptr props) { } props->connection_established_ = false; props->streaming_ = false; - props->connection_status_.store(ConnectionStatus::Closed); + props->connection_status_.store(MiniRtcConnectionStatus::MiniRtcConnectionClosed); std::shared_ptr> frame_snapshot; int video_width = 0; int video_height = 0; @@ -365,7 +365,7 @@ void GuiRuntime::CloseRemoteSession(std::shared_ptr props) { video_frame_dirty_.store(true, std::memory_order_release); } - PeerPtr* peer = nullptr; + MiniRtcPeerPtr* peer = nullptr; { // Audio/clipboard senders hold a shared map lock while using this pointer. std::unique_lock lock(remote_sessions_mutex_); @@ -384,8 +384,8 @@ void GuiRuntime::CloseRemoteSession(std::shared_ptr props) { if (peer && !props->lan_session_) { LOG_INFO("[{}] Background leave connection [{}]", props->local_id_, props->remote_id_); - LeaveConnection(peer, props->remote_id_.c_str()); - DestroyPeer(&peer); + MiniRtcLeaveConnection(peer, props->remote_id_.c_str()); + MiniRtcDestroyPeer(&peer); } if (thumbnail && props->was_connected_) { const char* nv12 = frame_snapshot && !frame_snapshot->empty() @@ -430,7 +430,7 @@ void GuiRuntime::CloseServerController(const std::string& remote_id) { return; controller_cleanup_tasks_[remote_id] = session_cleanup_queue_.PostTask( [peer = peer_, transmission_id = std::string(client_id_), remote_id] { - if (DisconnectPeerConnection(peer, transmission_id.c_str(), + if (MiniRtcDisconnectPeerConnection(peer, transmission_id.c_str(), remote_id.c_str()) != 0) { LOG_WARN("[{}] Could not queue controller disconnect notification", remote_id); @@ -462,8 +462,8 @@ void GuiRuntime::CloseConnectionPeer() { HandleServerControllerDisconnected(id, "peer_closed"); signal_connected_ = false; device_presence_cache_.SetSignalConnected(false); - signal_status_ = SignalStatus::SignalClosed; - PeerPtr* peer; + signal_status_ = MiniRtcSignalStatus::MiniRtcSignalClosed; + MiniRtcPeerPtr* peer; { std::unique_lock lock(remote_sessions_mutex_); peer = std::exchange(peer_, nullptr); @@ -474,8 +474,8 @@ void GuiRuntime::CloseConnectionPeer() { [peer, handler = peer_events_, id = std::string(client_id_)]() mutable { handler->Deactivate(); LOG_INFO("[{}] Background connection peer cleanup", id); - LeaveConnection(peer, id.c_str()); - DestroyPeer(&peer); + MiniRtcLeaveConnection(peer, id.c_str()); + MiniRtcDestroyPeer(&peer); }); } @@ -673,9 +673,9 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password, if (exists && !stale->closing_.load() && !stale->connection_established_) { const auto status = stale->connection_status_.load(); - if (status == ConnectionStatus::Disconnected || - status == ConnectionStatus::Failed || - status == ConnectionStatus::Closed) { + if (status == MiniRtcConnectionStatus::MiniRtcConnectionDisconnected || + status == MiniRtcConnectionStatus::MiniRtcConnectionFailed || + status == MiniRtcConnectionStatus::MiniRtcConnectionClosed) { // The recreated session starts with an empty password; callers that // pass none expect the one stored by the previous attempt to be reused. const bool keep_stored_password = !password || !*password; @@ -692,7 +692,7 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password, } if (!exists) { - PeerPtr* peer_to_init = nullptr; + MiniRtcPeerPtr* peer_to_init = nullptr; std::string local_id; { @@ -707,13 +707,13 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password, props->control_mouse_ = !background; props->enable_mouse_control_ = !background; props->audio_capture_button_pressed_ = !background; - memcpy(&props->params_, ¶ms_, sizeof(Params)); + memcpy(&props->params_, ¶ms_, sizeof(MiniRtcParams)); props->params_.user_id = props->local_id_.c_str(); props->peer_events_ = std::make_shared(*this); props->params_.user_data = props->peer_events_.get(); - props->peer_ = CreatePeer(&props->params_); + props->peer_ = MiniRtcCreatePeer(&props->params_); - props->connection_status_.store(ConnectionStatus::Connecting); + props->connection_status_.store(MiniRtcConnectionStatus::MiniRtcConnectionConnecting); if (!background) show_connection_status_window_ = true; if (!props->peer_) { @@ -724,18 +724,18 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password, const auto& displays = devices_.display_info_list(); for (size_t index = 0; index < displays.size(); ++index) { const std::string stream_id = MakeDisplayStreamId(index); - AddVideoStream(props->peer_, stream_id.c_str()); + MiniRtcAddVideoStream(props->peer_, stream_id.c_str()); } - AddAudioStream(props->peer_, props->audio_label_.c_str()); - AddDataStream(props->peer_, props->data_label_.c_str(), false); - AddDataStream(props->peer_, props->mouse_label_.c_str(), true); - AddDataStream(props->peer_, props->keyboard_label_.c_str(), true); - AddDataStream(props->peer_, props->control_data_label_.c_str(), true); - AddDataStream(props->peer_, props->file_label_.c_str(), true); - AddDataStream(props->peer_, props->file_feedback_label_.c_str(), true); - AddDataStream(props->peer_, props->clipboard_label_.c_str(), true); + MiniRtcAddAudioStream(props->peer_, props->audio_label_.c_str()); + MiniRtcAddDataStream(props->peer_, props->data_label_.c_str(), false); + MiniRtcAddDataStream(props->peer_, props->mouse_label_.c_str(), true); + MiniRtcAddDataStream(props->peer_, props->keyboard_label_.c_str(), true); + MiniRtcAddDataStream(props->peer_, props->control_data_label_.c_str(), true); + MiniRtcAddDataStream(props->peer_, props->file_label_.c_str(), true); + MiniRtcAddDataStream(props->peer_, props->file_feedback_label_.c_str(), true); + MiniRtcAddDataStream(props->peer_, props->clipboard_label_.c_str(), true); - props->connection_status_.store(ConnectionStatus::Connecting); + props->connection_status_.store(MiniRtcConnectionStatus::MiniRtcConnectionConnecting); peer_to_init = props->peer_; local_id = props->local_id_; @@ -744,7 +744,7 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password, if (peer_to_init) { LOG_INFO("[{}] Create peer instance successful", local_id); - Init(peer_to_init); + MiniRtcInit(peer_to_init); LOG_INFO("[{}] Peer init finish", local_id); } } @@ -773,10 +773,10 @@ int GuiRuntime::ConnectTo(const std::string& remote_id, const char* password, props->rejoin_ = false; return 0; } - props->connection_status_.store(ConnectionStatus::Connecting); + props->connection_status_.store(MiniRtcConnectionStatus::MiniRtcConnectionConnecting); std::string remote_id_with_pwd = remote_id + "@" + props->remote_password_; if (props->peer_) { - ret = JoinConnection(props->peer_, remote_id_with_pwd.c_str()); + ret = MiniRtcJoinConnection(props->peer_, remote_id_with_pwd.c_str()); if (0 == ret) { props->rejoin_ = false; } else { diff --git a/apps/desktop/src/gui/runtime/device_login.cpp b/apps/desktop/src/gui/runtime/device_login.cpp index 0a4ab769..d5b98972 100644 --- a/apps/desktop/src/gui/runtime/device_login.cpp +++ b/apps/desktop/src/gui/runtime/device_login.cpp @@ -6,7 +6,7 @@ #include "runtime/trusted_devices.h" namespace crossdesk { -int DeviceLogin::Exchange(SignalExchangeStage stage, const nlohmann::json& message, +int DeviceLogin::Exchange(MiniRtcSignalExchangeStage stage, const nlohmann::json& message, const TrustedDevices* identity, char* response, size_t capacity) { auto output = [&](const nlohmann::json& reply) { const auto text = reply.dump(); @@ -14,7 +14,7 @@ int DeviceLogin::Exchange(SignalExchangeStage stage, const nlohmann::json& messa std::memcpy(response, text.data(), text.size()); return static_cast(text.size()); }; - if (stage == SignalExchangeStage::PrepareLogin) { + if (stage == MiniRtcSignalExchangeStage::PrepareLogin) { phase_ = Phase::Idle; used_password_ = false; password_.clear(); diff --git a/apps/desktop/src/gui/runtime/device_login.h b/apps/desktop/src/gui/runtime/device_login.h index d11b287b..2bde8777 100644 --- a/apps/desktop/src/gui/runtime/device_login.h +++ b/apps/desktop/src/gui/runtime/device_login.h @@ -18,7 +18,7 @@ class TrustedDevices; // One signaling connection's application authentication, owned by its callbacks. class DeviceLogin { public: - int Exchange(SignalExchangeStage stage, const nlohmann::json& message, + int Exchange(MiniRtcSignalExchangeStage stage, const nlohmann::json& message, const TrustedDevices* identity, char* response, size_t capacity); bool Pending() const { return phase_ != Phase::Idle; } bool UsedPassword() const { return used_password_; } diff --git a/apps/desktop/src/gui/runtime/device_trust_runtime.cpp b/apps/desktop/src/gui/runtime/device_trust_runtime.cpp index 86aaf3bf..a19546d2 100644 --- a/apps/desktop/src/gui/runtime/device_trust_runtime.cpp +++ b/apps/desktop/src/gui/runtime/device_trust_runtime.cpp @@ -53,8 +53,8 @@ void GuiRuntime::ForgetControllerTrust(const std::string& id, PeerEventHandler* int GuiRuntime::SendTrustMessage(const std::string& id, const nlohmann::json& message) { const auto text = message.dump(); - return WithController(id, [&](PeerPtr* peer, const std::string& wire) { - return SendReliableDataFrameToPeer(peer, text.data(), text.size(), + return WithController(id, [&](MiniRtcPeerPtr* peer, const std::string& wire) { + return MiniRtcSendReliableDataFrameToPeer(peer, text.data(), text.size(), control_data_label_.c_str(), wire.data(), wire.size()); }, false); } @@ -94,7 +94,7 @@ bool GuiRuntime::HandleDeviceTrustMessage(const std::string& id, PeerEventHandle const auto wire = events->WireId(id); const auto proof = trusted_devices_->Prove(message.at("nonce"), props->local_id_, GetHostName()).dump(); - SendReliableDataFrameToPeer(props->peer_, proof.data(), proof.size(), + MiniRtcSendReliableDataFrameToPeer(props->peer_, proof.data(), proof.size(), control_data_label_.c_str(), wire.data(), wire.size()); } else if (type == "device_trust_proof") { std::lock_guard lock(controller_trust_mutex_); @@ -156,7 +156,7 @@ void GuiRuntime::TickControllerTrust() { remote_input_.Disconnect(action.id); CloseServerController(action.id); } else if (action.kind > 0) { - events->ApplyConnectionStatus(ConnectionStatus::Connected, action.id); + events->ApplyConnectionStatus(MiniRtcConnectionStatus::MiniRtcConnectionConnected, action.id); if (!action.host_info.empty()) { const auto wire = events->WireId(action.id); PeerEventHandler::OnReceiveDataBuffer(action.host_info.data(), action.host_info.size(), diff --git a/apps/desktop/src/gui/runtime/gui_runtime.cpp b/apps/desktop/src/gui/runtime/gui_runtime.cpp index e08514e7..07e3a30f 100644 --- a/apps/desktop/src/gui/runtime/gui_runtime.cpp +++ b/apps/desktop/src/gui/runtime/gui_runtime.cpp @@ -99,7 +99,7 @@ void GuiRuntime::SendRemoteInput(const RemoteAction& action) { ? action.k.flag == KeyFlag::key_up : action.ks.pressed_count == 0; const auto available = [](const auto& props) { return props && props->peer_ && !props->closing_ && - props->connection_status_ == ConnectionStatus::Connected; + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected; }; std::shared_lock lock(remote_sessions_mutex_); const auto source = remote_sessions_.find(target_id); @@ -121,9 +121,9 @@ void GuiRuntime::SendRemoteInput(const RemoteAction& action) { // Use the negotiated unreliable stream; clicks and wheel events remain // on the reliable mouse stream, with their own absolute coordinates. const int result = mouse_move - ? SendDataFrame(props->peer_, message.data(), message.size(), + ? MiniRtcSendDataFrame(props->peer_, message.data(), message.size(), props->data_label_.c_str()) - : SendReliableDataFrame( + : MiniRtcSendReliableDataFrame( props->peer_, message.data(), message.size(), mouse ? props->mouse_label_.c_str() : props->keyboard_label_.c_str()); if (result != 0) @@ -256,15 +256,15 @@ int GuiRuntime::CreateConnectionPeer() { ConfigCenter::VIDEO_ENCODE_FORMAT::AV1 ? true : false; - params_.turn_mode = static_cast(config_center_->GetTurnMode()); + params_.turn_mode = static_cast(config_center_->GetTurnMode()); params_.enable_srtp = config_center_->IsEnableSrtp(); - params_.video_content_type = VideoContentType::ScreenContent; + params_.video_content_type = MiniRtcVideoContentType::ScreenContent; // Bootstrap outgoing media with fixed defaults. Live overrides come only // from the authorized controller and apply to its connection on this host. - params_.video_quality = VideoQuality::QualityHigh; + params_.video_quality = MiniRtcVideoQuality::MiniRtcVideoQualityHigh; params_.video_frame_rate = 60; params_.video_degradation_preference = - VideoDegradationPreference::MaintainResolution; + MiniRtcVideoDegradationPreference::MaintainResolution; params_.on_receive_video_buffer = nullptr; params_.on_receive_audio_buffer = PeerEventHandler::OnReceiveAudioBuffer; params_.on_receive_data_buffer = PeerEventHandler::OnReceiveDataBuffer; @@ -284,15 +284,15 @@ int GuiRuntime::CreateConnectionPeer() { signal_connected_ = false; device_presence_cache_.SetSignalConnected(false); need_to_send_recent_connections_ = true; - signal_status_ = SignalStatus::SignalConnecting; + signal_status_ = MiniRtcSignalStatus::MiniRtcSignalConnecting; { std::unique_lock lock(remote_sessions_mutex_); - peer_ = CreatePeer(¶ms_); + peer_ = MiniRtcCreatePeer(¶ms_); } if (peer_) { LOG_INFO("Create peer instance [{}] successful", client_id_); - Init(peer_); + MiniRtcInit(peer_); LOG_INFO("Peer [{}] init finish", client_id_); } else { LOG_INFO("Create peer [{}] instance failed", client_id_); @@ -302,19 +302,19 @@ int GuiRuntime::CreateConnectionPeer() { const auto &displays = devices_.display_info_list(); for (size_t index = 0; index < displays.size(); ++index) { const std::string stream_id = MakeDisplayStreamId(index); - AddVideoStream(peer_, stream_id.c_str()); + MiniRtcAddVideoStream(peer_, stream_id.c_str()); } - AddAudioStream(peer_, audio_label_.c_str()); - AddDataStream(peer_, data_label_.c_str(), false); - AddDataStream(peer_, mouse_label_.c_str(), true); - AddDataStream(peer_, keyboard_label_.c_str(), true); - AddDataStream(peer_, control_data_label_.c_str(), true); - AddDataStream(peer_, file_label_.c_str(), true); - AddDataStream(peer_, file_feedback_label_.c_str(), true); - AddDataStream(peer_, clipboard_label_.c_str(), true); + MiniRtcAddAudioStream(peer_, audio_label_.c_str()); + MiniRtcAddDataStream(peer_, data_label_.c_str(), false); + MiniRtcAddDataStream(peer_, mouse_label_.c_str(), true); + MiniRtcAddDataStream(peer_, keyboard_label_.c_str(), true); + MiniRtcAddDataStream(peer_, control_data_label_.c_str(), true); + MiniRtcAddDataStream(peer_, file_label_.c_str(), true); + MiniRtcAddDataStream(peer_, file_feedback_label_.c_str(), true); + MiniRtcAddDataStream(peer_, clipboard_label_.c_str(), true); if (!unattended_host_) - AddDataStream(peer_, web_clipboard::kStream, true); + MiniRtcAddDataStream(peer_, web_clipboard::kStream, true); return 0; } else { return -1; @@ -390,10 +390,10 @@ void GuiRuntime::SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len) { uint64_t captured_timestamp = 0; for (const auto &it : runtime->remote_sessions_) { auto props = it.second; - if (props->connection_status_.load() == ConnectionStatus::Connected) { + if (props->connection_status_.load() == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { if (props->peer_) { if (captured_timestamp == 0) { - const int64_t timestamp_us = GetSystemTimeMicros(props->peer_); + const int64_t timestamp_us = MiniRtcGetSystemTimeMicros(props->peer_); if (timestamp_us > 0) { captured_timestamp = static_cast(timestamp_us); } @@ -402,7 +402,7 @@ void GuiRuntime::SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len) { frame.data = reinterpret_cast(stream); frame.size = static_cast(len); frame.captured_timestamp = captured_timestamp; - SendAudioFrame(props->peer_, &frame, + MiniRtcSendAudioFrame(props->peer_, &frame, runtime->audio_label_.c_str()); } } diff --git a/apps/desktop/src/gui/runtime/gui_runtime.h b/apps/desktop/src/gui/runtime/gui_runtime.h index 3231ca77..4decfc91 100644 --- a/apps/desktop/src/gui/runtime/gui_runtime.h +++ b/apps/desktop/src/gui/runtime/gui_runtime.h @@ -60,12 +60,12 @@ class GuiRuntime : protected gui_detail::GuiState { void TickLan(); void BeginShutdown(); bool ShutdownDrained(); - void RegisterStreams(PeerPtr* peer, size_t display_count); + void RegisterStreams(MiniRtcPeerPtr* peer, size_t display_count); void ConnectLan(const std::string& address, unsigned port, std::string password, bool remember_password = false); int WithController( const std::string& id, - const std::function& operation, + const std::function& operation, bool require_trusted = true); int SendControllerData(const std::string& id, const char* data, size_t size, const char* label); diff --git a/apps/desktop/src/gui/runtime/lan_runtime.cpp b/apps/desktop/src/gui/runtime/lan_runtime.cpp index 16b3fb4b..14a2a97b 100644 --- a/apps/desktop/src/gui/runtime/lan_runtime.cpp +++ b/apps/desktop/src/gui/runtime/lan_runtime.cpp @@ -7,17 +7,17 @@ #endif namespace crossdesk { -void GuiRuntime::RegisterStreams(PeerPtr* peer, size_t displays) { +void GuiRuntime::RegisterStreams(MiniRtcPeerPtr* peer, size_t displays) { for (size_t i = 0; i < displays; ++i) { const auto id = MakeDisplayStreamId(i); - AddVideoStream(peer, id.c_str()); + MiniRtcAddVideoStream(peer, id.c_str()); } - AddAudioStream(peer, audio_label_.c_str()); - AddDataStream(peer, data_label_.c_str(), false); + MiniRtcAddAudioStream(peer, audio_label_.c_str()); + MiniRtcAddDataStream(peer, data_label_.c_str(), false); for (const auto& label : {mouse_label_, keyboard_label_, control_data_label_, file_label_, file_feedback_label_, clipboard_label_}) - AddDataStream(peer, label.c_str(), true); + MiniRtcAddDataStream(peer, label.c_str(), true); } void GuiRuntime::InitializeLan() { if (unattended_host_ || stopping_ || lan_ || @@ -37,8 +37,8 @@ void GuiRuntime::InitializeLan() { auto events = std::make_shared(*this); events->BindDirect(session); // Direct initialization must not depend on cloud login/configuration having - // successfully populated the managed peer's Params snapshot. - Params params{}; + // successfully populated the managed peer's MiniRtcParams snapshot. + MiniRtcParams params{}; std::snprintf(params.log_path, sizeof(params.log_path), "%s", dll_log_path_.c_str()); params.hardware_acceleration = true; @@ -46,12 +46,12 @@ void GuiRuntime::InitializeLan() { params.av1_encoding = config_center_->GetVideoEncodeFormat() == ConfigCenter::VIDEO_ENCODE_FORMAT::AV1; params.enable_srtp = true; - params.turn_mode = TurnMode::TurnDisabled; - params.video_content_type = VideoContentType::ScreenContent; - params.video_quality = VideoQuality::QualityHigh; + params.turn_mode = MiniRtcTurnMode::MiniRtcTurnDisabled; + params.video_content_type = MiniRtcVideoContentType::ScreenContent; + params.video_quality = MiniRtcVideoQuality::MiniRtcVideoQualityHigh; params.video_frame_rate = 60; params.video_degradation_preference = - VideoDegradationPreference::MaintainResolution; + MiniRtcVideoDegradationPreference::MaintainResolution; params.on_receive_video_frame = PeerEventHandler::OnReceiveVideoBuffer; params.on_receive_audio_buffer = PeerEventHandler::OnReceiveAudioBuffer; params.on_receive_data_buffer = PeerEventHandler::OnReceiveDataBuffer; @@ -69,7 +69,7 @@ void GuiRuntime::InitializeLan() { lan::SessionManager::Prepared result; result.callback_owner = events; result.drain_callbacks = [events] { events->Deactivate(); }; - result.peer = CreatePeer(¶ms); + result.peer = MiniRtcCreatePeer(¶ms); events->SetDirectPeer(result.peer); if (result.peer) RegisterStreams(result.peer, displays); return result; @@ -88,7 +88,7 @@ void GuiRuntime::InitializeLan() { hooks.connected = [this](const std::shared_ptr& session) { auto events = std::static_pointer_cast(session->callback_owner); - events->ApplyConnectionStatus(ConnectionStatus::Connected, session->key); + events->ApplyConnectionStatus(MiniRtcConnectionStatus::MiniRtcConnectionConnected, session->key); events->FlushEarlyData(); }; hooks.closed = [this](const std::shared_ptr& session) { @@ -101,7 +101,7 @@ void GuiRuntime::InitializeLan() { } if (events) { if (attached) - events->ApplyConnectionStatus(ConnectionStatus::Closed, session->key); + events->ApplyConnectionStatus(MiniRtcConnectionStatus::MiniRtcConnectionClosed, session->key); events->StopAccepting(); transfers_.Cancel(events.get()); } @@ -157,7 +157,7 @@ void GuiRuntime::ConnectLan(const std::string& address, unsigned port, lan_connecting_ = session; props->lan_session_ = session; props->remote_id_ = session->key; - props->connection_status_ = ConnectionStatus::Connecting; + props->connection_status_ = MiniRtcConnectionStatus::MiniRtcConnectionConnecting; props->connection_auth_.Complete(); { std::unique_lock lock(remote_sessions_mutex_); @@ -180,14 +180,14 @@ std::shared_ptr GuiRuntime::ControllerEvents( } int GuiRuntime::WithController( const std::string& id, - const std::function& operation, + const std::function& operation, bool require_trusted) { if (require_trusted && !TrustedControllerAllowed(id)) return -1; std::shared_lock lock(remote_sessions_mutex_); auto it = lan_controllers_.find(id); auto events = it == lan_controllers_.end() ? peer_events_ : it->second.events; if (it == lan_controllers_.end() && id.rfind("lan/", 0) == 0) return -1; - PeerPtr* peer = + MiniRtcPeerPtr* peer = it == lan_controllers_.end() ? peer_ : it->second.session->peer; if (!peer || !events || !events->DataAllowed()) return -1; auto callback = events->EnterCallback(); @@ -198,8 +198,8 @@ int GuiRuntime::WithController( } int GuiRuntime::SendControllerData(const std::string& id, const char* data, size_t size, const char* label) { - return WithController(id, [&](PeerPtr* peer, const std::string& wire) { - return SendReliableDataFrameToPeer(peer, data, size, label, wire.data(), + return WithController(id, [&](MiniRtcPeerPtr* peer, const std::string& wire) { + return MiniRtcSendReliableDataFrameToPeer(peer, data, size, label, wire.data(), wire.size()); }); } @@ -208,7 +208,7 @@ std::vector GuiRuntime::ConnectedControllers() { std::shared_lock lock(connection_status_mutex_); ids.reserve(connection_status_.size()); for (const auto& [id, status] : connection_status_) - if (status == ConnectionStatus::Connected) ids.push_back(id); + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) ids.push_back(id); return ids; } void GuiRuntime::BeginShutdown() { diff --git a/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp b/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp index 06227d53..5576c810 100644 --- a/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp +++ b/apps/desktop/src/gui/runtime/peer_data_callbacks.cpp @@ -176,7 +176,7 @@ void PeerEventHandler::OnReceiveDataBuffer( } const std::string wire_id = handler->WireId(remote_id); - PeerPtr* bound_peer = + MiniRtcPeerPtr* bound_peer = handler->IsDirect() ? handler->DirectPeer() : runtime->peer_; std::string json_str(data, size); if (json_str.find("\"automation\"") != std::string::npos) { @@ -204,31 +204,31 @@ void PeerEventHandler::OnReceiveDataBuffer( // their own demand. MiniRTC owns per-peer video/audio pause state. if (!previous || subscription->IsNewerThan(*previous)) { if (subscription->fps > 0) - accepted = UpdateVideoSettings( + accepted = MiniRtcUpdateVideoSettings( bound_peer, wire_id.data(), wire_id.size(), - static_cast(subscription->quality), + static_cast(subscription->quality), subscription->frame_rate, - static_cast( + static_cast( subscription->EncoderPreference())) == 0; if (accepted && (!previous || previous->max_bitrate_bps.value_or(0) != subscription->max_bitrate_bps.value_or(0))) - accepted = UpdateVideoBitrateLimit( + accepted = MiniRtcUpdateVideoBitrateLimit( bound_peer, wire_id.data(), wire_id.size(), subscription->max_bitrate_bps.value_or(0)) == 0; // Rebalancing bandwidth alone must not force every device to send a // keyframe. The pause API requests its own keyframes on resume. if (accepted && (!previous || previous->width != subscription->width || previous->height != subscription->height)) - accepted = UpdateVideoResolution(bound_peer, wire_id.data(), + accepted = MiniRtcUpdateVideoResolution(bound_peer, wire_id.data(), wire_id.size(), subscription->width, subscription->height) == 0; if (accepted) accepted = - SetVideoSendPaused(bound_peer, wire_id.data(), wire_id.size(), + MiniRtcSetVideoSendPaused(bound_peer, wire_id.data(), wire_id.size(), subscription->fps == 0) == 0; if (accepted) accepted = - SetAudioSendPaused(bound_peer, wire_id.data(), wire_id.size(), + MiniRtcSetAudioSendPaused(bound_peer, wire_id.data(), wire_id.size(), !subscription->audio) == 0; if (accepted && subscription->audio) runtime->devices_.StartSpeakerCapturer(); @@ -240,7 +240,7 @@ void PeerEventHandler::OnReceiveDataBuffer( {"request_id", subscription->request_id}, {"accepted", accepted}}.dump(); - SendReliableDataFrameToPeer(bound_peer, reply.data(), reply.size(), + MiniRtcSendReliableDataFrameToPeer(bound_peer, reply.data(), reply.size(), runtime->control_data_label_.c_str(), wire_id.data(), wire_id.size()); return; @@ -275,7 +275,7 @@ void PeerEventHandler::OnReceiveDataBuffer( if (auto props = runtime->FindRemoteSession(remote_id); props && source_id == props->control_data_label_ && !props->closing_ && - props->connection_status_ == ConnectionStatus::Connected) { + props->connection_status_ == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { props->net_traffic_stats_.StoreRemoteVideoEncoder(remote_action.vcs.encoder); } return; @@ -314,17 +314,17 @@ void PeerEventHandler::OnReceiveDataBuffer( return; const auto& settings = remote_action.vs; remote_action.vs.accepted = - UpdateVideoSettings( + MiniRtcUpdateVideoSettings( bound_peer, wire_id.data(), wire_id.size(), - static_cast(settings.quality), settings.frame_rate, - static_cast(settings.preference)) == 0; + static_cast(settings.quality), settings.frame_rate, + static_cast(settings.preference)) == 0; LOG_INFO("Video settings: peer={} source={} request={} quality={} fps={} " "preference={} accepted={}", remote_id, source_id, settings.request_id, settings.quality, settings.frame_rate, settings.preference, remote_action.vs.accepted); remote_action.type = ControlType::video_settings_status; const auto message = remote_action.to_json(); - SendReliableDataFrameToPeer(bound_peer, message.data(), message.size(), + MiniRtcSendReliableDataFrameToPeer(bound_peer, message.data(), message.size(), runtime->control_data_label_.c_str(), wire_id.data(), wire_id.size()); return; @@ -479,7 +479,7 @@ void PeerEventHandler::OnReceiveDataBuffer( props->video_settings_request_tick_ = SDL_GetTicks(); settings.vs = props->video_settings_; const auto message = settings.to_json(); - SendReliableDataFrame( + MiniRtcSendReliableDataFrame( handler->IsDirect() ? handler->DirectPeer() : props->peer_, message.data(), message.size(), props->control_data_label_.c_str()); @@ -530,7 +530,7 @@ void PeerEventHandler::OnReceiveDataBuffer( // command arrives after it (e.g. when unmuting an inactive window). const auto subscription = runtime->preview_subscriptions_.Get(remote_id); const bool paused = subscription ? !subscription->audio : !remote_action.a; - const int ret = SetAudioSendPaused(bound_peer, wire_id.data(), + const int ret = MiniRtcSetAudioSendPaused(bound_peer, wire_id.data(), wire_id.size(), paused); if (remote_action.a) runtime->devices_.StartSpeakerCapturer(); diff --git a/apps/desktop/src/gui/runtime/peer_event_handler.cpp b/apps/desktop/src/gui/runtime/peer_event_handler.cpp index 4cc8df29..4aa35998 100644 --- a/apps/desktop/src/gui/runtime/peer_event_handler.cpp +++ b/apps/desktop/src/gui/runtime/peer_event_handler.cpp @@ -65,7 +65,7 @@ bool PeerEventHandler::DataAllowed() const { return session && session->authorized && !session->closing; } -void PeerEventHandler::SendClientInfo(PeerPtr* peer, +void PeerEventHandler::SendClientInfo(MiniRtcPeerPtr* peer, const std::string& client_id) { if (!peer) { return; @@ -75,7 +75,7 @@ void PeerEventHandler::SendClientInfo(PeerPtr* peer, {"version", CROSSDESK_VERSION}, {"platform", HostPlatformName(kClientPlatform)}}; const std::string payload = message.dump(); - if (SendSignalMessage(peer, payload.data(), payload.size()) != 0) { + if (MiniRtcSendSignalMessage(peer, payload.data(), payload.size()) != 0) { LOG_WARN("[{}] failed to report client information", client_id); } } @@ -84,13 +84,13 @@ PeerEventHandler::PeerEventHandler(GuiRuntime& owner) : owner_(owner) { owner_.transfers_.Connected(this, ""); } -int PeerEventHandler::OnSignalExchange(SignalExchangeStage stage, const char* message, +int PeerEventHandler::OnSignalExchange(MiniRtcSignalExchangeStage stage, const char* message, size_t size, char* response, size_t capacity, void* user_data) { auto* handler = static_cast(user_data); if (!handler || !message) return -1; auto callback = handler->EnterCallback(); if (!callback) return -1; - if (stage == SignalExchangeStage::IncomingMessage && + if (stage == MiniRtcSignalExchangeStage::IncomingMessage && !handler->device_login_.Pending()) return 0; try { return handler->device_login_.Exchange(stage, @@ -209,7 +209,7 @@ void PeerEventHandler::OnSignalMessage(const char* message, size_t size, } } -void PeerEventHandler::OnSignalStatus(SignalStatus status, const char* user_id, +void PeerEventHandler::OnSignalStatus(MiniRtcSignalStatus status, const char* user_id, size_t user_id_size, void* user_data) { using RecoveryAction = GuiRuntime::CredentialRecoveryAction; auto* handler = static_cast(user_data); @@ -220,13 +220,13 @@ void PeerEventHandler::OnSignalStatus(SignalStatus status, const char* user_id, std::string client_id(user_id, user_id_size); if (client_id == runtime->client_id_) { - runtime->announcements_.SetConnected(status == SignalStatus::SignalConnected); + runtime->announcements_.SetConnected(status == MiniRtcSignalStatus::MiniRtcSignalConnected); runtime->signal_status_ = status; runtime->device_presence_cache_.SetSignalConnected( - status == SignalStatus::SignalConnected); - if (SignalStatus::SignalConnecting == status) { + status == MiniRtcSignalStatus::MiniRtcSignalConnected); + if (MiniRtcSignalStatus::MiniRtcSignalConnecting == status) { runtime->signal_connected_ = false; - } else if (SignalStatus::SignalConnected == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalConnected == status) { runtime->signal_connected_ = true; runtime->need_to_send_recent_connections_ = true; LOG_INFO("[{}] connected to signal server", client_id); @@ -241,20 +241,20 @@ void PeerEventHandler::OnSignalStatus(SignalStatus status, const char* user_id, runtime->credential_recovery_action_ = RecoveryAction::ClearPending; } } - } else if (SignalStatus::SignalFailed == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalFailed == status) { runtime->signal_connected_ = false; std::lock_guard lock(runtime->password_change_mutex_); if (runtime->credential_recovery_in_progress_ && runtime->credential_recovery_attempt_pending_) { runtime->credential_recovery_action_ = RecoveryAction::RetryActive; } - } else if (SignalStatus::SignalClosed == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalClosed == status) { runtime->signal_connected_ = false; - } else if (SignalStatus::SignalReconnecting == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalReconnecting == status) { runtime->signal_connected_ = false; - } else if (SignalStatus::SignalServerClosed == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalServerClosed == status) { runtime->signal_connected_ = false; - } else if (SignalStatus::SignalTlsCertError == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalTlsCertError == status) { runtime->signal_connected_ = false; } } else { @@ -266,27 +266,27 @@ void PeerEventHandler::OnSignalStatus(SignalStatus status, const char* user_id, auto props = runtime->FindRemoteSession(remote_id); if (!props) return; props->signal_status_ = status; - if (SignalStatus::SignalConnecting == status) { + if (MiniRtcSignalStatus::MiniRtcSignalConnecting == status) { props->signal_connected_ = false; - } else if (SignalStatus::SignalConnected == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalConnected == status) { props->signal_connected_ = true; LOG_INFO("[{}] connected to signal server", remote_id); SendClientInfo(props->peer_, client_id); - } else if (SignalStatus::SignalFailed == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalFailed == status) { props->signal_connected_ = false; - } else if (SignalStatus::SignalClosed == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalClosed == status) { props->signal_connected_ = false; - } else if (SignalStatus::SignalReconnecting == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalReconnecting == status) { props->signal_connected_ = false; - } else if (SignalStatus::SignalServerClosed == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalServerClosed == status) { props->signal_connected_ = false; - } else if (SignalStatus::SignalTlsCertError == status) { + } else if (MiniRtcSignalStatus::MiniRtcSignalTlsCertError == status) { props->signal_connected_ = false; } } } -void PeerEventHandler::OnConnectionStatus(ConnectionStatus status, +void PeerEventHandler::OnConnectionStatus(MiniRtcConnectionStatus status, const char* user_id, size_t size, void* context) { auto* handler = static_cast(context); @@ -300,7 +300,7 @@ void PeerEventHandler::OnConnectionStatus(ConnectionStatus status, DispatchConnectionStatus(status, user_id, size, context); } -void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, +void PeerEventHandler::DispatchConnectionStatus(MiniRtcConnectionStatus status, const char* user_id, const size_t user_id_size, void* user_data) { @@ -311,9 +311,9 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, GuiRuntime* runtime = &handler->owner_; std::string remote_id = handler->ConnectionKey(user_id, user_id_size); - if (status == ConnectionStatus::Connected) runtime->transfers_.Connected(handler, remote_id); - else if (status == ConnectionStatus::Disconnected || status == ConnectionStatus::Failed || - status == ConnectionStatus::Closed) runtime->transfers_.Cancel(handler, remote_id); + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) runtime->transfers_.Connected(handler, remote_id); + else if (status == MiniRtcConnectionStatus::MiniRtcConnectionDisconnected || status == MiniRtcConnectionStatus::MiniRtcConnectionFailed || + status == MiniRtcConnectionStatus::MiniRtcConnectionClosed) runtime->transfers_.Cancel(handler, remote_id); std::shared_ptr props; { std::shared_lock lock(runtime->remote_sessions_mutex_); @@ -324,7 +324,7 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, } if (!props) { - if (status == ConnectionStatus::Connected) { + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { if (!runtime->BeginControllerTrust(remote_id, handler)) return; } else { runtime->ForgetControllerTrust(remote_id, handler); @@ -335,11 +335,11 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, runtime->is_client_mode_ = true; if (!props->wall_managed_) runtime->show_connection_status_window_ = true; props->connection_status_.store(status); - if (status != ConnectionStatus::Connecting && status != ConnectionStatus::Gathering) + if (status != MiniRtcConnectionStatus::MiniRtcConnectionConnecting && status != MiniRtcConnectionStatus::MiniRtcConnectionGathering) props->connection_auth_.Complete(); switch (status) { - case ConnectionStatus::Connected: { + case MiniRtcConnectionStatus::MiniRtcConnectionConnected: { runtime->ResetRemoteServiceStatus(*props); { std::lock_guard lock(props->remote_cursor_state_mutex_); @@ -368,7 +368,7 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, information["device_trust_version"] = 1; std::string msg = information.dump(); const int ret = - SendReliableDataFrame(props->peer_, msg.data(), msg.size(), + MiniRtcSendReliableDataFrame(props->peer_, msg.data(), msg.size(), runtime->control_data_label_.c_str()); if (ret != 0) { LOG_WARN("[{}] host information send failed, ret={}", remote_id, @@ -386,9 +386,9 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, if (!props->wall_managed_) runtime->start_keyboard_capturer_ = true; break; } - case ConnectionStatus::Disconnected: - case ConnectionStatus::Failed: - case ConnectionStatus::Closed: { + case MiniRtcConnectionStatus::MiniRtcConnectionDisconnected: + case MiniRtcConnectionStatus::MiniRtcConnectionFailed: + case MiniRtcConnectionStatus::MiniRtcConnectionClosed: { runtime->keyboard_.ReleaseRemotePressedKeys(remote_id, "connection_closed"); props->connection_established_ = false; @@ -406,7 +406,7 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, props->gallery_video_latency_->Reset(); props->gallery_frame_timing_ = {}; } - props->traversal_mode_ = TraversalMode::UnknownMode; + props->traversal_mode_ = MiniRtcTraversalMode::MiniRtcTraversalUnknown; props->enable_mouse_control_ = false; props->preview_subscription_supported_ = false; props->preview_resolution_supported_ = false; @@ -477,7 +477,7 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, runtime->focus_on_stream_window_ = false; - if (status == ConnectionStatus::Closed) { + if (status == MiniRtcConnectionStatus::MiniRtcConnectionClosed) { props->remote_close_pending_.store(true, std::memory_order_release); } @@ -491,7 +491,7 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, runtime->show_connection_status_window_ = true; { std::unique_lock lock(runtime->connection_status_mutex_); - if (status == ConnectionStatus::Connected) { + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) { runtime->disconnect_lock_.Connected(remote_id); // Local privacy requires explicit desktop capability. Host info may // arrive before Connected; consume that saved capability here. @@ -500,19 +500,19 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, runtime->ApplyPrivacyAdmission(automatic_enable); } runtime->connection_status_[remote_id] = status; - if (status == ConnectionStatus::Connected) + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) runtime->remote_input_.Connect(remote_id); #if _WIN32 runtime->windows_rdp_handoff_connected_->store(std::any_of( runtime->connection_status_.begin(), runtime->connection_status_.end(), - [](const auto& entry) { return entry.second == ConnectionStatus::Connected; }), + [](const auto& entry) { return entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; }), std::memory_order_relaxed); #endif runtime->devices_.OnControllerConnectionsChanged(); } switch (status) { - case ConnectionStatus::Connected: { + case MiniRtcConnectionStatus::MiniRtcConnectionConnected: { runtime->preview_subscriptions_.Remove(remote_id); #if _WIN32 runtime->last_windows_service_status_tick_ = 0; @@ -557,9 +557,9 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, break; } - case ConnectionStatus::Disconnected: - case ConnectionStatus::Failed: - case ConnectionStatus::Closed: { + case MiniRtcConnectionStatus::MiniRtcConnectionDisconnected: + case MiniRtcConnectionStatus::MiniRtcConnectionFailed: + case MiniRtcConnectionStatus::MiniRtcConnectionClosed: { runtime->HandleServerControllerDisconnected(remote_id, "connection_closed"); break; @@ -571,7 +571,7 @@ void PeerEventHandler::DispatchConnectionStatus(ConnectionStatus status, } void PeerEventHandler::OnNetStatusReport( - const char* client_id, size_t client_id_size, TraversalMode mode, + const char* client_id, size_t client_id_size, MiniRtcTraversalMode mode, const MiniRtcNetTrafficStats* net_traffic_stats, const char* user_id, const size_t user_id_size, void* user_data) { auto* handler = static_cast(user_data); @@ -640,7 +640,7 @@ void PeerEventHandler::OnNetStatusReport( const auto status = runtime->connection_status_.find(remote_id); report_codecs = runtime->codec_status_controllers_.count(remote_id) != 0 && status != runtime->connection_status_.end() && - status->second == ConnectionStatus::Connected; + status->second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; } if (net_traffic_stats && report_codecs) { RemoteAction action{}; diff --git a/apps/desktop/src/gui/runtime/peer_event_handler.h b/apps/desktop/src/gui/runtime/peer_event_handler.h index 943a5c9b..36111271 100644 --- a/apps/desktop/src/gui/runtime/peer_event_handler.h +++ b/apps/desktop/src/gui/runtime/peer_event_handler.h @@ -37,10 +37,10 @@ public: std::string WireId(const std::string& key) const; bool DataAllowed() const; bool IsDirect() const { return direct_bound_; } - void SetDirectPeer(PeerPtr* peer) { direct_peer_ = peer; } - PeerPtr* DirectPeer() const { return direct_peer_; } + void SetDirectPeer(MiniRtcPeerPtr* peer) { direct_peer_ = peer; } + MiniRtcPeerPtr* DirectPeer() const { return direct_peer_; } void FlushEarlyData(); - void ApplyConnectionStatus(ConnectionStatus status, const std::string& id) { + void ApplyConnectionStatus(MiniRtcConnectionStatus status, const std::string& id) { DispatchConnectionStatus(status, id.data(), id.size(), this); } void StopAccepting() { callbacks_.StopAccepting(); } @@ -60,30 +60,30 @@ public: const char *user_id, size_t user_id_size, const char *src_id, size_t src_id_size, void *user_data); - static void OnSignalStatus(SignalStatus status, const char *user_id, + static void OnSignalStatus(MiniRtcSignalStatus status, const char *user_id, size_t user_id_size, void *user_data); static void OnSignalMessage(const char *message, size_t size, void *user_data); - static int OnSignalExchange(SignalExchangeStage stage, const char* message, + static int OnSignalExchange(MiniRtcSignalExchangeStage stage, const char* message, size_t size, char* response, size_t capacity, void* user_data); - static void OnConnectionStatus(ConnectionStatus status, const char *user_id, + static void OnConnectionStatus(MiniRtcConnectionStatus status, const char *user_id, size_t user_id_size, void *user_data); static void OnNetStatusReport(const char *client_id, size_t client_id_size, - TraversalMode mode, + MiniRtcTraversalMode mode, const MiniRtcNetTrafficStats *net_traffic_stats, const char *user_id, size_t user_id_size, void *user_data); private: - static void DispatchConnectionStatus(ConnectionStatus status, const char* id, + static void DispatchConnectionStatus(MiniRtcConnectionStatus status, const char* id, size_t size, void* context); - static void SendClientInfo(PeerPtr* peer, const std::string& client_id); + static void SendClientInfo(MiniRtcPeerPtr* peer, const std::string& client_id); bool QueueEarlyData(const char* data, size_t size, const char* label, size_t label_size); std::weak_ptr direct_; bool direct_bound_ = false; - PeerPtr* direct_peer_ = nullptr; + MiniRtcPeerPtr* direct_peer_ = nullptr; std::mutex early_data_mutex_; std::vector early_data_; size_t early_data_bytes_ = 0; diff --git a/apps/desktop/src/gui/runtime/peer_media_callbacks.cpp b/apps/desktop/src/gui/runtime/peer_media_callbacks.cpp index fb10acb3..f6025258 100644 --- a/apps/desktop/src/gui/runtime/peer_media_callbacks.cpp +++ b/apps/desktop/src/gui/runtime/peer_media_callbacks.cpp @@ -51,7 +51,7 @@ void PeerEventHandler::OnReceiveVideoBuffer( if (props->connection_established_) { const auto timing_now = VideoLatencyFrame::Clock::now(); // Pair the clocks before preview conversion so its cost is included. - const auto local_now_us = GetSystemTimeMicros( + const auto local_now_us = MiniRtcGetSystemTimeMicros( handler->IsDirect() ? handler->DirectPeer() : props->peer_); const auto* received_native = GetNativeVideoFrame(video_frame); props->received_video_stats_.Record( diff --git a/apps/desktop/src/gui/runtime/privacy_runtime.cpp b/apps/desktop/src/gui/runtime/privacy_runtime.cpp index 47aa68a8..615874d5 100644 --- a/apps/desktop/src/gui/runtime/privacy_runtime.cpp +++ b/apps/desktop/src/gui/runtime/privacy_runtime.cpp @@ -26,7 +26,7 @@ bool GuiRuntime::IsAuthorizedController(const std::string& remote_id) { std::shared_lock lock(connection_status_mutex_); const auto found = connection_status_.find(remote_id); return found != connection_status_.end() && - found->second == ConnectionStatus::Connected; + found->second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; } void GuiRuntime::SetControllerPrivacySupport(const std::string& remote_id, @@ -34,9 +34,9 @@ void GuiRuntime::SetControllerPrivacySupport(const std::string& remote_id, std::unique_lock lock(connection_status_mutex_); const auto found = connection_status_.find(remote_id); if (found == connection_status_.end()) return; - if (found->second != ConnectionStatus::Connected) { - if (found->second == ConnectionStatus::Connecting || - found->second == ConnectionStatus::Gathering) { + if (found->second != MiniRtcConnectionStatus::MiniRtcConnectionConnected) { + if (found->second == MiniRtcConnectionStatus::MiniRtcConnectionConnecting || + found->second == MiniRtcConnectionStatus::MiniRtcConnectionGathering) { privacy_sessions_.RememberSupport(remote_id, supported); LOG_INFO("Privacy: retained early controller capability, peer={}, supported={}", remote_id, supported); @@ -64,7 +64,7 @@ void GuiRuntime::QueuePrivacyCommand(const std::string& remote_id, std::shared_lock session_lock(connection_status_mutex_); const auto found = connection_status_.find(remote_id); if (found == connection_status_.end() || - found->second != ConnectionStatus::Connected || + found->second != MiniRtcConnectionStatus::MiniRtcConnectionConnected || !privacy_sessions_.Supports(remote_id)) return; std::lock_guard lock(privacy_commands_mutex_); if (privacy_commands_.size() >= 32) return; @@ -94,7 +94,7 @@ void GuiRuntime::HandlePrivacy() { std::shared_lock lock(connection_status_mutex_); const auto found = connection_status_.find(remote_id); if (found == connection_status_.end() || - found->second != ConnectionStatus::Connected || + found->second != MiniRtcConnectionStatus::MiniRtcConnectionConnected || !privacy_sessions_.Supports(remote_id)) continue; if (command.flag == PrivacyCommandFlag::enable) { if (privacy_sessions_.CanEnable()) @@ -124,7 +124,7 @@ void GuiRuntime::HandlePrivacy() { privacy_.CancelAutomaticResume(); status = privacy_.Snapshot(); for (const auto& [id, state] : connection_status_) - if (state == ConnectionStatus::Connected && + if (state == MiniRtcConnectionStatus::MiniRtcConnectionConnected && privacy_sessions_.Supports(id)) controllers.push_back(id); if (!privacy_sessions_.CanEnable()) { diff --git a/apps/desktop/src/gui/runtime/remote_session.h b/apps/desktop/src/gui/runtime/remote_session.h index df6aad26..cefe24d3 100644 --- a/apps/desktop/src/gui/runtime/remote_session.h +++ b/apps/desktop/src/gui/runtime/remote_session.h @@ -112,8 +112,8 @@ struct RemoteSession { std::mutex gallery_conversion_mutex_; std::vector gallery_nv12_, gallery_scaled_, gallery_scratch_; std::shared_ptr lan_session_; - Params params_; - PeerPtr* peer_ = nullptr; + MiniRtcParams params_; + MiniRtcPeerPtr* peer_ = nullptr; std::shared_ptr peer_events_; std::atomic closing_{false}; // Transport callbacks request tab closure; only the UI thread destroys it. @@ -130,7 +130,7 @@ struct RemoteSession { std::string remote_id_; bool exit_ = false; bool signal_connected_ = false; - SignalStatus signal_status_ = SignalStatus::SignalClosed; + MiniRtcSignalStatus signal_status_ = MiniRtcSignalStatus::MiniRtcSignalClosed; bool connection_established_ = false; std::atomic was_connected_{false}; // Transport callbacks publish changes; the UI thread persists history. @@ -211,8 +211,8 @@ struct RemoteSession { bool remote_cursor_state_received_ = false; CursorPresentation cursor_presentation_; // Shared by minirtc callbacks, Slint rendering and SDL audio callbacks. - std::atomic connection_status_ = ConnectionStatus::Closed; - std::atomic traversal_mode_{TraversalMode::UnknownMode}; + std::atomic connection_status_ = MiniRtcConnectionStatus::MiniRtcConnectionClosed; + std::atomic traversal_mode_{MiniRtcTraversalMode::MiniRtcTraversalUnknown}; int fps_ = 0; int frame_count_ = 0; std::chrono::steady_clock::time_point last_time_; diff --git a/apps/desktop/src/gui/runtime/runtime_state.h b/apps/desktop/src/gui/runtime/runtime_state.h index d992800f..d54bc90e 100644 --- a/apps/desktop/src/gui/runtime/runtime_state.h +++ b/apps/desktop/src/gui/runtime/runtime_state.h @@ -67,11 +67,11 @@ struct RecentConnectionsState { }; struct PeerState { - SignalStatus signal_status_ = SignalStatus::SignalClosed; + MiniRtcSignalStatus signal_status_ = MiniRtcSignalStatus::MiniRtcSignalClosed; std::string signal_status_str_; std::atomic signal_connected_{false}; - PeerPtr *peer_ = nullptr; - PeerPtr *peer_reserved_ = nullptr; + MiniRtcPeerPtr *peer_ = nullptr; + MiniRtcPeerPtr *peer_reserved_ = nullptr; std::string video_primary_label_ = "primary_display"; std::string video_secondary_label_ = "secondary_display"; std::string audio_label_ = "audio"; @@ -83,7 +83,7 @@ struct PeerState { std::string file_label_ = kFileStream; std::string file_feedback_label_ = kFileFeedbackStream; std::string clipboard_label_ = kClipboardStream; - Params params_{}; + MiniRtcParams params_{}; }; // OS-specific service and permission state is kept separate from transport @@ -203,7 +203,7 @@ struct ConnectionState { std::unordered_map pending_reconnects_; std::shared_mutex connection_status_mutex_; - std::unordered_map connection_status_; + std::unordered_map connection_status_; std::unordered_map connection_host_names_; std::unordered_set codec_status_controllers_; // Cursor position is sampled asynchronously after remote mouse input has diff --git a/apps/desktop/src/network/lan/lan_session_manager.cpp b/apps/desktop/src/network/lan/lan_session_manager.cpp index 3223fe3e..1fae1e44 100644 --- a/apps/desktop/src/network/lan/lan_session_manager.cpp +++ b/apps/desktop/src/network/lan/lan_session_manager.cpp @@ -83,13 +83,13 @@ void Session::Error(MiniRtcDirectError error, void* context) { s->failed = true; } } -void Session::Status(ConnectionStatus status) { +void Session::Status(MiniRtcConnectionStatus status) { if (closing) return; - if (status == ConnectionStatus::Connected) + if (status == MiniRtcConnectionStatus::MiniRtcConnectionConnected) ready = true; - else if (status == ConnectionStatus::Closed || - status == ConnectionStatus::Failed || - status == ConnectionStatus::Disconnected) + else if (status == MiniRtcConnectionStatus::MiniRtcConnectionClosed || + status == MiniRtcConnectionStatus::MiniRtcConnectionFailed || + status == MiniRtcConnectionStatus::MiniRtcConnectionDisconnected) failed = true; } SessionManager::SessionManager(std::filesystem::path path, Hooks hooks) @@ -417,9 +417,9 @@ void SessionManager::Prepare(const SessionPtr& s) { options.send_signal = Session::SendSignal; options.on_error = Session::Error; options.context = s.get(); - if (InitDirectPeer(prepared.peer, &options) != 0 || + if (MiniRtcInitDirectPeer(prepared.peer, &options) != 0 || (!s->closing && - StartDirectSession(prepared.peer, !s->incoming) != 0)) + MiniRtcStartDirectSession(prepared.peer, !s->incoming) != 0)) s->failed = true; return prepared; })}); @@ -560,7 +560,7 @@ void SessionManager::Message(const SessionPtr& s, const std::string& text) { Check(type == "candidate" && (s->phase == Session::AwaitAnswer || s->phase == Session::Negotiating || s->phase == Session::Connected)); - if (ReceiveDirectSignal(s->peer, text.data(), text.size()) != 0) + if (MiniRtcReceiveDirectSignal(s->peer, text.data(), text.size()) != 0) Fail(s, "InvalidSignal"); } void SessionManager::Dispose(const SessionPtr& s) { @@ -571,8 +571,8 @@ void SessionManager::Dispose(const SessionPtr& s) { cleanup_jobs_.push_back( std::async(std::launch::async, [s, peer, owner, drain]() mutable { if (drain) drain(); - CloseDirectSession(peer); - DestroyPeer(&peer); + MiniRtcCloseDirectSession(peer); + MiniRtcDestroyPeer(&peer); })); } void SessionManager::Close(const SessionPtr& s, const std::string& error) { diff --git a/apps/desktop/src/network/lan/lan_session_manager.h b/apps/desktop/src/network/lan/lan_session_manager.h index 2429d2ea..28459e10 100644 --- a/apps/desktop/src/network/lan/lan_session_manager.h +++ b/apps/desktop/src/network/lan/lan_session_manager.h @@ -43,7 +43,7 @@ struct Session { bool incoming = false; uint64_t epoch = 0, receive_seq = 0, send_seq = 0; std::chrono::steady_clock::time_point deadline; - PeerPtr* peer = nullptr; // Only published/cleared by the manager. + MiniRtcPeerPtr* peer = nullptr; // Only published/cleared by the manager. std::atomic closing{false}, authorized{false}, ready{false}, failed{false}; std::atomic failure_code{-1}; @@ -54,7 +54,7 @@ struct Session { std::function drain_callbacks; static int SendSignal(const char* data, size_t size, void* context); static void Error(MiniRtcDirectError error, void* context); - void Status(ConnectionStatus status); + void Status(MiniRtcConnectionStatus status); }; // All public methods run on the GUI manager thread. Only Session's bounded @@ -63,7 +63,7 @@ class SessionManager { public: using SessionPtr = std::shared_ptr; struct Prepared { - PeerPtr* peer = nullptr; + MiniRtcPeerPtr* peer = nullptr; std::shared_ptr callback_owner; std::function drain_callbacks; }; diff --git a/apps/desktop/src/platform/windows/gui/runtime/windows_service_runtime.cpp b/apps/desktop/src/platform/windows/gui/runtime/windows_service_runtime.cpp index aae116c4..1b8cb0b2 100644 --- a/apps/desktop/src/platform/windows/gui/runtime/windows_service_runtime.cpp +++ b/apps/desktop/src/platform/windows/gui/runtime/windows_service_runtime.cpp @@ -120,7 +120,7 @@ void GuiRuntime::HandleWindowsServiceIntegration() { std::shared_lock lock(connection_status_mutex_); return std::any_of(connection_status_.begin(), connection_status_.end(), [](const auto &entry) { - return entry.second == ConnectionStatus::Connected; + return entry.second == MiniRtcConnectionStatus::MiniRtcConnectionConnected; }); }(); if (!has_connected_remote) { diff --git a/apps/desktop/tests/connection_status_protocol_test.cpp b/apps/desktop/tests/connection_status_protocol_test.cpp index 774dab9a..5ad2f012 100644 --- a/apps/desktop/tests/connection_status_protocol_test.cpp +++ b/apps/desktop/tests/connection_status_protocol_test.cpp @@ -80,7 +80,7 @@ int main() { ReadFile(repo_root / "apps/desktop/src/gui/application/application_state.h"); bool ok = true; - ok &= ExpectContains("minirtc.h", minirtc_api, "RemoteUnavailable"); + ok &= ExpectContains("minirtc.h", minirtc_api, "MiniRtcConnectionRemoteUnavailable"); ok &= ExpectNotContains("minirtc.h", minirtc_api, "DeviceOffline"); ok &= ExpectContains("peer_connection.cpp", peer_connection, "on_connection_status_(ParseJoinFailure(j).status,"); @@ -88,17 +88,17 @@ int main() { "IsCurrentPeerConnection"); ok &= ExpectContains( "peer_connection.cpp", peer_connection, - "on_connection_status_(ConnectionStatus::Closed, remote_user_id.data()"); + "on_connection_status_(MiniRtcConnectionStatus::MiniRtcConnectionClosed, remote_user_id.data()"); ok &= ExpectNotContains("peer_connection.cpp", peer_connection, "\"Device offline\""); ok &= ExpectNotContains("peer_connection.cpp", peer_connection, - "ConnectionStatus::DeviceOffline"); + "MiniRtcConnectionStatus::MiniRtcConnectionDeviceOffline"); ok &= ExpectContains("main_window.slint", main_window, "in property connection-dialog-open: false;"); ok &= ExpectContains("main_window.slint", main_window, - "text: root.connection-status-text;"); + "text: root.prompt-status-text;"); ok &= ExpectContains("gui_application.cpp", gui_application, - "case ConnectionStatus::RemoteUnavailable:"); + "case MiniRtcConnectionStatus::MiniRtcConnectionRemoteUnavailable:"); ok &= ExpectContains("gui_application.cpp", gui_application, "return localization::device_offline[language];"); ok &= ExpectContains("runtime_state.h", runtime_state_h, @@ -116,7 +116,7 @@ int main() { // Reading a terminal transport status to reconnect is valid. This guard // prohibits synthesizing a failure locally, not comparisons with Failed. const std::regex synthetic_failure( - R"((connection_status_\s*(=\s*|\.\s*(store|exchange)\s*\(\s*)|OnConnectionStatus\s*\(\s*)ConnectionStatus::Failed\b)"); + R"((connection_status_\s*(=\s*|\.\s*(store|exchange)\s*\(\s*)|OnConnectionStatus\s*\(\s*)MiniRtcConnectionStatus::MiniRtcConnectionFailed\b)"); if (std::regex_search(connection_runtime_cpp, synthetic_failure)) { std::cerr << "connection_runtime.cpp synthesizes a Failed status\n"; ok = false; @@ -124,7 +124,7 @@ int main() { ok &= ExpectContains("peer_event_handler.cpp", peer_event_handler_cpp, "props->connection_status_.store(status);"); ok &= ExpectContains("peer_event_handler.cpp", peer_event_handler_cpp, - "case ConnectionStatus::Failed:"); + "case MiniRtcConnectionStatus::MiniRtcConnectionFailed:"); ok &= ExpectContains("connection_runtime.cpp", connection_runtime_cpp, "HandleServerControllerDisconnected"); ok &= ExpectContains("peer_event_handler.cpp", peer_event_handler_cpp, diff --git a/apps/harmony/native/mobile_session.cpp b/apps/harmony/native/mobile_session.cpp index fb81a2ca..92d649e2 100644 --- a/apps/harmony/native/mobile_session.cpp +++ b/apps/harmony/native/mobile_session.cpp @@ -100,23 +100,23 @@ class MobileSession { if (self->Current(controller, generation)) fn(self, controller); }); } - static void Signal(SignalStatus status, const char*, size_t, void* user) { + static void Signal(MiniRtcSignalStatus status, const char*, size_t, void* user) { Dispatch(user, [status](MobileSession* s, bool controller) { if (!controller) { - s->online_ = status == SignalConnected; + s->online_ = status == MiniRtcSignalConnected; if (s->signal_status_ != status) { ++s->signal_generation_; - if (s->signal_status_ == SignalConnected) s->signal_started_ = Clock::now(); + if (s->signal_status_ == MiniRtcSignalConnected) s->signal_started_ = Clock::now(); } s->signal_status_ = status; if (s->online_) { constexpr char info[] = R"({"type":"client_info","version":"harmony-mobile","platform":"harmonyos"})"; - SendSignalMessage(s->identity_, info, sizeof(info)-1); + MiniRtcSendSignalMessage(s->identity_, info, sizeof(info)-1); } } s->Event({{"type", "signal"}, {"controller", controller}, {"status", status}, {"generation", s->signal_generation_}, {"id", s->login_.substr(0, s->login_.find('@'))}}); - if (controller && status >= SignalFailed && status != SignalReconnecting) s->Disconnect("远程会话信令连接失败"); + if (controller && status >= MiniRtcSignalFailed && status != MiniRtcSignalReconnecting) s->Disconnect("远程会话信令连接失败"); }); } static void SignalMessage(const char* data, size_t size, void* user) { @@ -130,29 +130,29 @@ class MobileSession { s->Event({{"type", "signalMessage"}, {"message", value}, {"generation", s->signal_generation_}}); }); } - static void Connection(ConnectionStatus status, const char* id, size_t size, void* user) { + static void Connection(MiniRtcConnectionStatus status, const char* id, size_t size, void* user) { const std::string remote(id ? id : "", id ? size : 0); Dispatch(user, [status, remote](MobileSession* s, bool controller) { if (!controller) { // Defense in depth if a server tries to attach a guest to our identity. - if (status == Connected && s->identity_) - DisconnectPeerConnection(s->identity_, s->login_.substr(0,s->login_.find('@')).c_str(), remote.c_str()); + if (status == MiniRtcConnectionConnected && s->identity_) + MiniRtcDisconnectPeerConnection(s->identity_, s->login_.substr(0,s->login_.find('@')).c_str(), remote.c_str()); return; } s->Event({{"type", "connection"}, {"status", status}}, true); - if (status == Connected && !s->connected_) { + if (status == MiniRtcConnectionConnected && !s->connected_) { s->connecting_ = false; s->connected_ = true; auto info = MakeHostInformation("CrossDesk HarmonyOS Mobile", {}, true, s->version_, HostPlatform::HarmonyOS); info.i.supports_video_codec_status = true; s->Send(info); FreeRemoteAction(info); RemoteAction audio{}; audio.type = audio_capture; audio.a = !s->muted_; s->Send(audio); s->audio_.Start(); - } else if (status >= Disconnected) s->Disconnect(""); + } else if (status >= MiniRtcConnectionDisconnected) s->Disconnect(""); }); } - static void Network(const char* id, size_t size, TraversalMode mode, const MiniRtcNetTrafficStats* stats, + static void Network(const char* id, size_t size, MiniRtcTraversalMode mode, const MiniRtcNetTrafficStats* stats, const char*, size_t, void* user) { - if (mode == UnknownMode && id && size) { + if (mode == MiniRtcTraversalUnknown && id && size) { const std::string login(id, size); Dispatch(user, [login](MobileSession* s, bool controller) { if (!controller) { @@ -198,13 +198,13 @@ class MobileSession { auto* c = static_cast(user); auto* s = c->owner; if (c->controller && c->generation == s->connection_ && s->connected_ && !s->muted_ && !s->suspended_) s->audio_.Push(data,size); } - Params Parameters(bool controller) { - Params p{}; + MiniRtcParams Parameters(bool controller) { + MiniRtcParams p{}; std::snprintf(p.signal_server_ip,sizeof(p.signal_server_ip),"%s",server_.c_str()); std::snprintf(p.log_path,sizeof(p.log_path),"%s",logs_.c_str()); - p.signal_server_port = port_; p.enable_srtp = true; p.turn_mode = TurnAutoUdpTcp; - p.video_content_type = VideoContentType::ScreenContent; p.video_quality = QualityMedium; p.video_frame_rate = 30; - p.video_degradation_preference = VideoDegradationPreference::MaintainResolution; + p.signal_server_port = port_; p.enable_srtp = true; p.turn_mode = MiniRtcTurnAutoUdpTcp; + p.video_content_type = MiniRtcVideoContentType::ScreenContent; p.video_quality = MiniRtcVideoQualityMedium; p.video_frame_rate = 30; + p.video_degradation_preference = MiniRtcVideoDegradationPreference::MaintainResolution; p.hardware_acceleration = true; p.user_id = controller ? controller_login_.c_str() : login_.c_str(); p.user_data = controller ? control_context_.get() : identity_context_.get(); @@ -214,7 +214,7 @@ class MobileSession { } void Send(const RemoteAction& action, const char* stream = kControlStream) { if (!controller_) return; - const auto bytes = action.to_json(); SendReliableDataFrame(controller_,bytes.data(),bytes.size(),stream); + const auto bytes = action.to_json(); MiniRtcSendReliableDataFrame(controller_,bytes.data(),bytes.size(),stream); } void Release() { for (int key : keys_) { RemoteAction a{}; a.type=keyboard; a.k={size_t(key),0,false,key_up}; Send(a,kKeyboardStream); } @@ -236,14 +236,14 @@ class MobileSession { const bool active = controller_ != nullptr; Release(); connected_=false; connecting_=false; ++video_generation_; CancelPreview(); - if (controller_) { LeaveConnection(controller_,remote_.c_str()); DestroyPeer(&controller_); } + if (controller_) { MiniRtcLeaveConnection(controller_,remote_.c_str()); MiniRtcDestroyPeer(&controller_); } files_.reset(); renderer_.Clear(); audio_.Stop(); if (active) Event({{"type","ended"},{"reason",reason}},true); ++connection_; display_=0; frame_id_=0; } void Stop() { Disconnect(""); online_=false; - if (identity_) DestroyPeer(&identity_); + if (identity_) MiniRtcDestroyPeer(&identity_); ++session_; login_.clear(); signal_status_=-1; } void Execute(const json& v) { @@ -260,8 +260,8 @@ class MobileSession { if (MiniRtcConfigureLogging(MiniRtcLogOff, nullptr, nullptr) != 0) throw std::runtime_error("Unable to configure MiniRTC logging"); identity_context_=std::make_unique(Context{this,false,session_}); - auto p=Parameters(false); identity_=CreatePeer(&p); signal_started_=Clock::now(); - if (!identity_||Init(identity_)!=0) { throw std::runtime_error("Identity initialization failed"); } + auto p=Parameters(false); identity_=MiniRtcCreatePeer(&p); signal_started_=Clock::now(); + if (!identity_||MiniRtcInit(identity_)!=0) { throw std::runtime_error("Identity initialization failed"); } } else if (op=="stop") Stop(); else if (op=="version") { const auto body=v.at("body").get(), current=v.value("version",""); @@ -279,25 +279,25 @@ class MobileSession { throw std::runtime_error("Invalid remote credentials"); muted_=false; suspended_=false; controller_login_="C-"+login_.substr(0,login_.find('@')); control_context_=std::make_unique(Context{this,true,connection_}); - auto p=Parameters(true); controller_=CreatePeer(&p); connecting_=true; connection_started_=Clock::now(); + auto p=Parameters(true); controller_=MiniRtcCreatePeer(&p); connecting_=true; connection_started_=Clock::now(); if (!controller_) throw std::runtime_error("Peer creation failed"); - AddAudioStream(controller_,kAudioStream); AddDataStream(controller_,kDataStream,false); + MiniRtcAddAudioStream(controller_,kAudioStream); MiniRtcAddDataStream(controller_,kDataStream,false); for (auto stream : {kMouseStream,kKeyboardStream,kControlStream,kClipboardStream,kFileStream,kFileFeedbackStream}) - AddDataStream(controller_,stream,true); + MiniRtcAddDataStream(controller_,stream,true); files_=std::make_unique( - [this](const char* stream,const char* data,size_t size) { return controller_?SendReliableDataFrame(controller_,data,size,stream):-1; }, + [this](const char* stream,const char* data,size_t size) { return controller_?MiniRtcSendReliableDataFrame(controller_,data,size,stream):-1; }, [this](const std::string& name,double progress,bool sending,const std::string& path) { Event({{"type","file"},{"name",name},{"progress",progress},{"sending",sending},{"path",path}},true); }); files_->SetDirectory(directory_+"/received"); - if (Init(controller_)!=0||JoinConnection(controller_,(remote_+"@"+password).c_str())!=0) Disconnect("无法发起连接"); + if (MiniRtcInit(controller_)!=0||MiniRtcJoinConnection(controller_,(remote_+"@"+password).c_str())!=0) Disconnect("无法发起连接"); } else if (op=="disconnect") Disconnect(""); else if (op=="release") Release(); else if (op=="signal" && online_ && identity_) { auto request=v.at("message"); const auto type=request.value("type",""); if (type!="announcements_list"&&type!="recent_connections_presence") return; request["user_id"]=login_.substr(0,login_.find('@')); - const auto bytes=request.dump(); const bool ok=SendSignalMessage(identity_,bytes.data(),bytes.size())==0; + const auto bytes=request.dump(); const bool ok=MiniRtcSendSignalMessage(identity_,bytes.data(),bytes.size())==0; if (!ok) Event({{"type","requestFailed"},{"request",request.value("request_id","")}}); } else if (connected_) { if (op=="pointer") { @@ -323,22 +323,22 @@ class MobileSession { RemoteAction a{}; a.type=audio_capture; a.a=!muted_; Send(a); } else if (op=="clipboard") { const auto text=v.at("text").get(); - if(!text.empty()&&text.size()<=kMaxClipboardBytes) SendReliableDataFrame(controller_,text.data(),text.size(),kClipboardStream); + if(!text.empty()&&text.size()<=kMaxClipboardBytes) MiniRtcSendReliableDataFrame(controller_,text.data(),text.size(),kClipboardStream); } else if (op=="videoSettings") { const int q=v.at("quality"),fps=v.at("frameRate"),pref=v.at("preference"); if(q<0||q>2||(fps!=30&&fps!=60)||pref<0||pref>2)return; auto bytes=mobile_controller::VideoSettingsMessage(q,fps,pref,v.at("request").get()); - if(SendReliableDataFrame(controller_,bytes.data(),bytes.size(),kControlStream)!=0) + if(MiniRtcSendReliableDataFrame(controller_,bytes.data(),bytes.size(),kControlStream)!=0) Event({{"type","settingsFailed"},{"request",v.at("request")}},true); } else if (op=="privacy") { const auto bytes = mobile_controller::PrivacyMessage( v.at("flag").get(), v.at("blockLocalInput").get()); if (bytes.empty() || - SendReliableDataFrame(controller_, bytes.data(), bytes.size(), kControlStream) != 0) + MiniRtcSendReliableDataFrame(controller_, bytes.data(), bytes.size(), kControlStream) != 0) Event({{"type", "privacyFailed"}, {"request", v.at("request")}}, true); } else if (op=="sas") { const auto bytes=mobile_controller::SecureAttentionMessage(); - const bool ok=SendReliableDataFrame(controller_,bytes.data(),bytes.size(),kControlStream)==0; + const bool ok=MiniRtcSendReliableDataFrame(controller_,bytes.data(),bytes.size(),kControlStream)==0; Event({{"type","feedback"},{"text",ok?"已发送 Ctrl+Alt+Del":"指令发送失败,请重试"}},true); } else if (op=="sendFile") { const auto path=v.at("path").get(),name=v.at("name").get(); @@ -368,7 +368,7 @@ class MobileSession { for(int key:keys_) { if(a.ks.pressed_count>=kMaxKeyboardStateKeys)break; a.ks.pressed_keys[a.ks.pressed_count++]={size_t(key),0,false}; } Send(a,kKeyboardStream); keyboard_sent_=now; const auto local=std::chrono::duration_cast(now.time_since_epoch()).count(); - const auto rtc=GetSystemTimeMicros(controller_); if(rtc>0)clock_offset_=rtc-local; + const auto rtc=MiniRtcGetSystemTimeMicros(controller_); if(rtc>0)clock_offset_=rtc-local; } } void Run() { @@ -391,8 +391,8 @@ class MobileSession { std::atomic session_{0},connection_{0},video_generation_{1},frame_id_{0}; std::atomic clock_offset_{0}; std::atomic display_{0}; - PeerPtr* identity_=nullptr; - PeerPtr* controller_=nullptr; + MiniRtcPeerPtr* identity_=nullptr; + MiniRtcPeerPtr* controller_=nullptr; std::unique_ptr identity_context_,control_context_; std::unique_ptr files_; std::string server_,logs_,login_,controller_login_,remote_,directory_,preview_directory_,preview_path_,version_; diff --git a/apps/harmony/tests/mobile_synthetic_host.cpp b/apps/harmony/tests/mobile_synthetic_host.cpp index bee620c9..456d14e1 100644 --- a/apps/harmony/tests/mobile_synthetic_host.cpp +++ b/apps/harmony/tests/mobile_synthetic_host.cpp @@ -13,10 +13,10 @@ #include using namespace crossdesk; struct Fixture { - PeerPtr* peer=nullptr; std::atomic connected{false}; std::atomic selected{0}; + MiniRtcPeerPtr* peer=nullptr; std::atomic connected{false}; std::atomic selected{0}; std::mutex mutex; std::vector> messages; std::string remote; std::atomic signal{-1}; int keys=0,mouse=0,settings=0,clipboard=0; - void Send(RemoteAction& a) {const auto s=a.to_json();SendReliableDataFrame(peer,s.data(),s.size(),kControlStream);} + void Send(RemoteAction& a) {const auto s=a.to_json();MiniRtcSendReliableDataFrame(peer,s.data(),s.size(),kControlStream);} }; int main(int argc,char**argv) { if(argc<3)return 2;umask(0077); @@ -24,19 +24,19 @@ int main(int argc,char**argv) { setenv("SSL_CERT_DIR","/etc/security/certificates",1); #endif std::string login;{std::ifstream input("fixture-login");input>>login;} - Fixture f;Params p{};snprintf(p.signal_server_ip,sizeof(p.signal_server_ip),"%s",argv[1]);p.signal_server_port=atoi(argv[2]);p.user_id=login.c_str();p.user_data=&f; - p.turn_mode=TurnAutoUdpTcp;p.enable_srtp=true;p.av1_encoding=argc>3;p.video_frame_rate=30;p.video_quality=QualityMedium; - p.video_content_type=VideoContentType::ScreenContent;p.video_degradation_preference=VideoDegradationPreference::MaintainResolution; - p.on_signal_status=[](SignalStatus s,const char*,size_t,void*u){static_cast(u)->signal=s;}; - p.on_net_status_report=[](const char*id,size_t n,TraversalMode mode,const MiniRtcNetTrafficStats*,const char*,size_t,void*){ - if(mode==UnknownMode&&id&&n&&std::string(id,n).find('@')!=std::string::npos){std::ofstream out("fixture-login");out.write(id,n);} + Fixture f;MiniRtcParams p{};snprintf(p.signal_server_ip,sizeof(p.signal_server_ip),"%s",argv[1]);p.signal_server_port=atoi(argv[2]);p.user_id=login.c_str();p.user_data=&f; + p.turn_mode=MiniRtcTurnAutoUdpTcp;p.enable_srtp=true;p.av1_encoding=argc>3;p.video_frame_rate=30;p.video_quality=MiniRtcVideoQualityMedium; + p.video_content_type=MiniRtcVideoContentType::ScreenContent;p.video_degradation_preference=MiniRtcVideoDegradationPreference::MaintainResolution; + p.on_signal_status=[](MiniRtcSignalStatus s,const char*,size_t,void*u){static_cast(u)->signal=s;}; + p.on_net_status_report=[](const char*id,size_t n,MiniRtcTraversalMode mode,const MiniRtcNetTrafficStats*,const char*,size_t,void*){ + if(mode==MiniRtcTraversalUnknown&&id&&n&&std::string(id,n).find('@')!=std::string::npos){std::ofstream out("fixture-login");out.write(id,n);} }; - p.on_connection_status=[](ConnectionStatus s,const char*id,size_t n,void*u){auto*f=static_cast(u);std::lock_guard lock(f->mutex);f->remote.assign(id,n);f->connected=s==Connected;if(s==Connected)f->selected=0;}; + p.on_connection_status=[](MiniRtcConnectionStatus s,const char*id,size_t n,void*u){auto*f=static_cast(u);std::lock_guard lock(f->mutex);f->remote.assign(id,n);f->connected=s==MiniRtcConnectionConnected;if(s==MiniRtcConnectionConnected)f->selected=0;}; p.on_receive_data_buffer=[](const char*d,size_t n,const char*,size_t,const char*s,size_t l,void*u){auto*f=static_cast(u);std::lock_guard lock(f->mutex);f->messages.emplace_back(std::string(s,l),std::string(d,n));}; - f.peer=CreatePeer(&p);AddVideoStream(f.peer,"Display1");AddVideoStream(f.peer,"Display2");AddAudioStream(f.peer,kAudioStream);AddDataStream(f.peer,kDataStream,false); - for(auto s:{kKeyboardStream,kMouseStream,kControlStream,kClipboardStream,kFileStream,kFileFeedbackStream})AddDataStream(f.peer,s,true); - if(Init(f.peer))return 3; - mobile_controller::FileTransferSession files([&](const char*s,const char*b,size_t n){return SendReliableDataFrame(f.peer,b,n,s);}, + f.peer=MiniRtcCreatePeer(&p);MiniRtcAddVideoStream(f.peer,"Display1");MiniRtcAddVideoStream(f.peer,"Display2");MiniRtcAddAudioStream(f.peer,kAudioStream);MiniRtcAddDataStream(f.peer,kDataStream,false); + for(auto s:{kKeyboardStream,kMouseStream,kControlStream,kClipboardStream,kFileStream,kFileFeedbackStream})MiniRtcAddDataStream(f.peer,s,true); + if(MiniRtcInit(f.peer))return 3; + mobile_controller::FileTransferSession files([&](const char*s,const char*b,size_t n){return MiniRtcSendReliableDataFrame(f.peer,b,n,s);}, [](const std::string&,double p,bool,const std::string&path){if(p==1&&!path.empty())std::ofstream("received-result")< pixels(640*360*3/2,128);int16_t pcm[480]{}; @@ -44,27 +44,27 @@ int main(int argc,char**argv) { while(std::chrono::steady_clock::now()> messages;{std::lock_guard lock(f.mutex);messages.swap(f.messages);} if(f.connected&&!info){auto a=MakeHostInformation("Synthetic mobile fixture",{{"Test pattern",0,0,640,360},{"Second display",0,0,640,360}},true,"1.6.1",HostPlatform::Windows);a.i.supports_video_settings=true;f.Send(a);FreeRemoteAction(a);info=true; - const std::string clip="CrossDesk synthetic clipboard";SendReliableDataFrame(f.peer,clip.data(),clip.size(),kClipboardStream); + const std::string clip="CrossDesk synthetic clipboard";MiniRtcSendReliableDataFrame(f.peer,clip.data(),clip.size(),kClipboardStream); {std::ofstream out("sample.txt");out<<"Synthetic mobile file transfer\n";}files.Start("sample.txt","fixture.txt");} if(!f.connected)info=false; for(auto&[stream,bytes]:messages){ if(stream==kFileStream)files.Receive(bytes.data(),bytes.size());else if(stream==kFileFeedbackStream)files.Ack(bytes.data(),bytes.size()); - else if(stream==kClipboardStream){f.clipboard++;SendReliableDataFrame(f.peer,bytes.data(),bytes.size(),kClipboardStream);} + else if(stream==kClipboardStream){f.clipboard++;MiniRtcSendReliableDataFrame(f.peer,bytes.data(),bytes.size(),kClipboardStream);} else {RemoteAction a{};if(!a.from_json(bytes))continue; if(a.type==host_infomation)info=false; if(a.type==keyboard)f.keys++;if(a.type==mouse)f.mouse++;if(a.type==display_id)f.selected=a.d; if(a.type==video_settings){f.settings++;a.type=video_settings_status;a.vs.accepted=true;f.Send(a);}FreeRemoteAction(a);} } if(f.connected){ - files.Pump();MiniRtcAudioFrame audio{};audio.data=reinterpret_cast(pcm);audio.size=sizeof(pcm);SendAudioFrame(f.peer,&audio,kAudioStream); + files.Pump();MiniRtcAudioFrame audio{};audio.data=reinterpret_cast(pcm);audio.size=sizeof(pcm);MiniRtcSendAudioFrame(f.peer,&audio,kAudioStream); if(iteration%3==0){for(int y=0;y<360;y++)for(int x=0;x<640;x++)pixels[y*640+x]=uint8_t(35+(x/80)*24+((y+iteration)%180<12?30:0)); std::fill(pixels.begin()+640*360,pixels.end(),128);for(size_t i=640*360;i(pixels.data()); frame.captured_timestamp=std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); - SendVideoFrame(f.peer,&frame,f.selected?"Display2":"Display1");} + MiniRtcSendVideoFrame(f.peer,&frame,f.selected?"Display2":"Display1");} } if(iteration++%100==0)std::ofstream("fixture-status")<<"signal="< presence_requests; bool identity_recovery_attempted = false; @@ -337,7 +337,7 @@ void DispatchMain(dispatch_block_t block) { sourceIDSize:(size_t)sourceIDSize generation:(uint64_t)generation; - (void)handleStats:(const MiniRtcNetTrafficStats *)stats - mode:(TraversalMode)mode + mode:(MiniRtcTraversalMode)mode generation:(uint64_t)generation; - (void)sendMessage:(const std::string &)message reliable:(BOOL)reliable @@ -389,7 +389,7 @@ void OnDataBuffer(const char *data, size_t size, const char *, size_t, } } -void OnSignalState(SignalStatus status, const char *, size_t, void *user_data) { +void OnSignalState(MiniRtcSignalStatus status, const char *, size_t, void *user_data) { auto *context = static_cast(user_data); CrossDeskRTCBridge *owner = context ? context->owner : nil; if (owner && @@ -410,7 +410,7 @@ void OnSignalMessage(const char *message, size_t size, void *user_data) { } } -void OnConnectionState(ConnectionStatus status, const char *remote_id, +void OnConnectionState(MiniRtcConnectionStatus status, const char *remote_id, size_t remote_id_size, void *user_data) { auto *context = static_cast(user_data); CrossDeskRTCBridge *owner = context ? context->owner : nil; @@ -425,12 +425,12 @@ void OnConnectionState(ConnectionStatus status, const char *remote_id, } void OnNetworkStats(const char *peer_id, size_t peer_id_size, - TraversalMode mode, const MiniRtcNetTrafficStats *stats, + MiniRtcTraversalMode mode, const MiniRtcNetTrafficStats *stats, const char *, size_t, void *user_data) { auto *context = static_cast(user_data); CrossDeskRTCBridge *owner = context ? context->owner : nil; if (!owner) return; - if (context->role == PeerRole::Identity && mode == TraversalMode::UnknownMode && + if (context->role == PeerRole::Identity && mode == MiniRtcTraversalMode::MiniRtcTraversalUnknown && peer_id && peer_id_size > 0) { [owner handleProvisionedIdentity:std::string(peer_id, peer_id_size) generation:context->generation]; @@ -440,9 +440,9 @@ void OnNetworkStats(const char *peer_id, size_t peer_id_size, } } -Params MakeParams(const RTCState &state, const std::string &user_id, +MiniRtcParams MakeParams(const RTCState &state, const std::string &user_id, CallbackContext *context) { - Params params{}; + MiniRtcParams params{}; params.use_cfg_file = false; CopyCString(params.signal_server_ip, sizeof(params.signal_server_ip), state.signal_host); @@ -452,10 +452,10 @@ Params MakeParams(const RTCState &state, const std::string &user_id, params.hardware_acceleration = true; params.native_video_output = true; params.av1_encoding = false; - params.turn_mode = TurnMode::TurnAutoUdpTcp; + params.turn_mode = MiniRtcTurnMode::MiniRtcTurnAutoUdpTcp; params.enable_srtp = true; - params.video_content_type = VideoContentType::ScreenContent; - params.video_quality = VideoQuality::QualityHigh; + params.video_content_type = MiniRtcVideoContentType::ScreenContent; + params.video_quality = MiniRtcVideoQuality::MiniRtcVideoQualityHigh; params.video_frame_rate = 60; params.video_degradation_preference = state.video_adaptation_policy; params.on_receive_video_buffer = nullptr; @@ -654,16 +654,16 @@ Params MakeParams(const RTCState &state, const std::string &user_id, switch (policy) { case CrossDeskVideoAdaptationPolicyFrameRatePriority: self->_state->video_adaptation_policy = - VideoDegradationPreference::MaintainFrameRate; + MiniRtcVideoDegradationPreference::MaintainFrameRate; break; case CrossDeskVideoAdaptationPolicyBalanced: self->_state->video_adaptation_policy = - VideoDegradationPreference::Balanced; + MiniRtcVideoDegradationPreference::Balanced; break; case CrossDeskVideoAdaptationPolicyQualityPriority: default: self->_state->video_adaptation_policy = - VideoDegradationPreference::MaintainResolution; + MiniRtcVideoDegradationPreference::MaintainResolution; break; } }); @@ -685,7 +685,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, networking_generation != self->_networkingGeneration.load()) return; if (self->_state->identity_peer && self->_state->identity_ready && !self->_state->identity_base.empty() && - SendSignalMessage(self->_state->identity_peer, + MiniRtcSendSignalMessage(self->_state->identity_peer, static_cast(payload.bytes), payload.length) == 0) return; DispatchMain(^{ if (generation != self->_identityGeneration.load() || @@ -714,7 +714,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, action.vs = {static_cast(quality), static_cast(frameRate), static_cast(preference), requestID, false}; const auto message = action.to_json(); - if (SendReliableDataFrame(self->_state->controller_peer, message.data(), + if (MiniRtcSendReliableDataFrame(self->_state->controller_peer, message.data(), message.size(), kControlStream) != 0) { [self notifyVideoSettings:action.vs generation:generation]; } @@ -771,7 +771,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, options:0 error:nil]; if (!payload) return; - if (SendSignalMessage(self->_state->identity_peer, + if (MiniRtcSendSignalMessage(self->_state->identity_peer, static_cast(payload.bytes), payload.length) == 0) { // Both old and new servers return snapshots in request order. Retain the @@ -844,7 +844,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, if (self->_state->controller_peer) { const std::string stream = crossdesk::MakeDisplayStreamId( static_cast(self->_selectedDisplay.load())); - RequestVideoKeyFrame(self->_state->controller_peer, stream.c_str()); + MiniRtcRequestVideoKeyFrame(self->_state->controller_peer, stream.c_str()); } }); } @@ -896,19 +896,19 @@ Params MakeParams(const RTCState &state, const std::string &user_id, if (!mapping.valid) continue; if (mapping.shift) { const std::string shift_down = KeyJSON(0x10, true); - SendReliableDataFrame(self->_state->controller_peer, + MiniRtcSendReliableDataFrame(self->_state->controller_peer, shift_down.data(), shift_down.size(), kKeyboardStream); } const std::string key_down = KeyJSON(mapping.key_code, true); const std::string key_up = KeyJSON(mapping.key_code, false); - SendReliableDataFrame(self->_state->controller_peer, key_down.data(), + MiniRtcSendReliableDataFrame(self->_state->controller_peer, key_down.data(), key_down.size(), kKeyboardStream); - SendReliableDataFrame(self->_state->controller_peer, key_up.data(), + MiniRtcSendReliableDataFrame(self->_state->controller_peer, key_up.data(), key_up.size(), kKeyboardStream); if (mapping.shift) { const std::string shift_up = KeyJSON(0x10, false); - SendReliableDataFrame(self->_state->controller_peer, shift_up.data(), + MiniRtcSendReliableDataFrame(self->_state->controller_peer, shift_up.data(), shift_up.size(), kKeyboardStream); } } @@ -1032,7 +1032,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, send_result = -1; break; } - send_result = SendReliableDataFrame(self->_state->controller_peer, + send_result = MiniRtcSendReliableDataFrame(self->_state->controller_peer, chunk.data(), chunk.size(), kFileStream); offset += bytes_read; @@ -1063,7 +1063,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, static_cast(blockLocalInput)}; const auto message = action.to_json(); const BOOL success = self->_state->controller_peer && - SendReliableDataFrame(self->_state->controller_peer, message.data(), + MiniRtcSendReliableDataFrame(self->_state->controller_peer, message.data(), message.size(), kControlStream) == 0; DispatchMain(^{ if (![self isControllerGenerationActive:generation]) return; @@ -1083,7 +1083,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, action.c.flag = ServiceCommandFlag::send_sas; const auto message = action.to_json(); const BOOL success = self->_state->controller_peer && - SendReliableDataFrame(self->_state->controller_peer, message.data(), message.size(), kControlStream) == 0; + MiniRtcSendReliableDataFrame(self->_state->controller_peer, message.data(), message.size(), kControlStream) == 0; DispatchMain(^{ if (![self isControllerGenerationActive:generation]) return; id delegate = self.delegate; @@ -1107,11 +1107,11 @@ Params MakeParams(const RTCState &state, const std::string &user_id, if (![self isControllerGenerationActive:generation] || !self->_state->controller_peer) return; if (reliable) { - SendReliableDataFrame(self->_state->controller_peer, + MiniRtcSendReliableDataFrame(self->_state->controller_peer, owned_message.data(), owned_message.size(), owned_stream.c_str()); } else { - SendDataFrame(self->_state->controller_peer, owned_message.data(), + MiniRtcSendDataFrame(self->_state->controller_peer, owned_message.data(), owned_message.size(), owned_stream.c_str()); } }); @@ -1134,10 +1134,10 @@ Params MakeParams(const RTCState &state, const std::string &user_id, - (void)createIdentityPeer { if (_state->identity_peer || _state->signal_host.empty()) return; _state->identity_context.generation = _identityGeneration.fetch_add(1) + 1; - Params params = MakeParams(*_state, _state->identity_with_password, + MiniRtcParams params = MakeParams(*_state, _state->identity_with_password, &_state->identity_context); - _state->identity_peer = CreatePeer(¶ms); - if (!_state->identity_peer || Init(_state->identity_peer) != 0) { + _state->identity_peer = MiniRtcCreatePeer(¶ms); + if (!_state->identity_peer || MiniRtcInit(_state->identity_peer) != 0) { [self destroyIdentityPeer]; [self handleSignalState:CrossDeskSignalStateFailed role:PeerRole::Identity @@ -1155,9 +1155,9 @@ Params MakeParams(const RTCState &state, const std::string &user_id, _state->controller_context.generation = generation; _activeControllerGeneration.store(generation); _state->controller_login = "C-" + _state->identity_base; - Params params = MakeParams(*_state, _state->controller_login, + MiniRtcParams params = MakeParams(*_state, _state->controller_login, &_state->controller_context); - _state->controller_peer = CreatePeer(¶ms); + _state->controller_peer = MiniRtcCreatePeer(¶ms); if (!_state->controller_peer) { _activeControllerGeneration.store(0); [self handleConnectionState:CrossDeskConnectionStateFailed @@ -1168,16 +1168,16 @@ Params MakeParams(const RTCState &state, const std::string &user_id, // This native iOS peer is controller-only and does not publish a local // display. Remote display receivers are created from the host's SDP. - AddAudioStream(_state->controller_peer, kAudioStream); - AddDataStream(_state->controller_peer, kDataStream, false); - AddDataStream(_state->controller_peer, kMouseStream, true); - AddDataStream(_state->controller_peer, kKeyboardStream, true); - AddDataStream(_state->controller_peer, kControlStream, true); - AddDataStream(_state->controller_peer, kFileStream, true); - AddDataStream(_state->controller_peer, kFileFeedbackStream, true); - AddDataStream(_state->controller_peer, kClipboardStream, true); + MiniRtcAddAudioStream(_state->controller_peer, kAudioStream); + MiniRtcAddDataStream(_state->controller_peer, kDataStream, false); + MiniRtcAddDataStream(_state->controller_peer, kMouseStream, true); + MiniRtcAddDataStream(_state->controller_peer, kKeyboardStream, true); + MiniRtcAddDataStream(_state->controller_peer, kControlStream, true); + MiniRtcAddDataStream(_state->controller_peer, kFileStream, true); + MiniRtcAddDataStream(_state->controller_peer, kFileFeedbackStream, true); + MiniRtcAddDataStream(_state->controller_peer, kClipboardStream, true); - if (Init(_state->controller_peer) != 0) { + if (MiniRtcInit(_state->controller_peer) != 0) { [self destroyControllerPeer]; [self handleConnectionState:CrossDeskConnectionStateFailed remoteID:_state->pending_remote_id @@ -1186,7 +1186,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, } const std::string join_id = _state->pending_remote_id + "@" + _state->pending_password; - JoinConnection(_state->controller_peer, join_id.c_str()); + MiniRtcJoinConnection(_state->controller_peer, join_id.c_str()); // Joining authenticates with "remote-id@password", while leaving is routed // by the remote peer ID alone (the same contract used by the desktop app). @@ -1198,7 +1198,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, _presenceGeneration.fetch_add(1); _state->presence_requests.clear(); if (_state->identity_peer) { - DestroyPeer(&_state->identity_peer); + MiniRtcDestroyPeer(&_state->identity_peer); } _state->identity_ready = false; } @@ -1207,10 +1207,10 @@ Params MakeParams(const RTCState &state, const std::string &user_id, _activeControllerGeneration.store(0); if (_state->controller_peer) { if (!_state->transmission_id.empty()) { - LeaveConnection(_state->controller_peer, + MiniRtcLeaveConnection(_state->controller_peer, _state->transmission_id.c_str()); } - DestroyPeer(&_state->controller_peer); + MiniRtcDestroyPeer(&_state->controller_peer); } _state->controller_login.clear(); _state->transmission_id.clear(); @@ -1248,7 +1248,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, constexpr char client_info[] = "{\"type\":\"client_info\",\"version\":\"ios-native\"," "\"platform\":\"ios\"}"; - SendSignalMessage(self->_state->identity_peer, client_info, + MiniRtcSendSignalMessage(self->_state->identity_peer, client_info, sizeof(client_info) - 1); } if (state == CrossDeskSignalStateFailed && @@ -1456,11 +1456,11 @@ Params MakeParams(const RTCState &state, const std::string &user_id, action.i.right = nullptr; action.i.bottom = nullptr; const std::string host_info = action.to_json(); - SendReliableDataFrame(self->_state->controller_peer, host_info.data(), + MiniRtcSendReliableDataFrame(self->_state->controller_peer, host_info.data(), host_info.size(), kControlStream); const std::string stream = crossdesk::MakeDisplayStreamId( static_cast(self->_selectedDisplay.load())); - RequestVideoKeyFrame(self->_state->controller_peer, stream.c_str()); + MiniRtcRequestVideoKeyFrame(self->_state->controller_peer, stream.c_str()); }); } DispatchMain(^{ @@ -1506,7 +1506,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, // Translate the transport's calibrated capture time once, while the peer is // alive. Carry it with the exact pixels through coalescing and UI submission. const NSTimeInterval now = NSProcessInfo.processInfo.systemUptime; - const int64_t peer_now = GetSystemTimeMicros(_state->controller_peer); + const int64_t peer_now = MiniRtcGetSystemTimeMicros(_state->controller_peer); NSTimeInterval capture_uptime = 0; if (frame->captured_timestamp > 0 && peer_now > 0 && frame->captured_timestamp <= static_cast(peer_now) && @@ -2009,7 +2009,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, if ([self isControllerGenerationActive:generation] && self->_state->controller_peer) { const auto encoded_ack = crossdesk::EncodeFileTransferAck(ack); - SendReliableDataFrame(self->_state->controller_peer, + MiniRtcSendReliableDataFrame(self->_state->controller_peer, encoded_ack.data(), encoded_ack.size(), kFileFeedbackStream); } @@ -2035,7 +2035,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id, } - (void)handleStats:(const MiniRtcNetTrafficStats *)stats - mode:(TraversalMode)mode + mode:(MiniRtcTraversalMode)mode generation:(uint64_t)generation { if (!stats) return; const auto traffic = [](const MiniRtcInboundStats &inbound, @@ -2049,8 +2049,8 @@ Params MakeParams(const RTCState &state, const std::string &user_id, traffic(stats->data_inbound_stats, stats->data_outbound_stats), traffic(stats->total_inbound_stats, stats->total_outbound_stats), stats->rtt_ms, static_cast(stats->srtp_active), - mode == TraversalMode::P2P ? CrossDeskTraversalModeDirect - : mode == TraversalMode::Relay ? CrossDeskTraversalModeRelay + mode == MiniRtcTraversalMode::MiniRtcTraversalP2P ? CrossDeskTraversalModeDirect + : mode == MiniRtcTraversalMode::MiniRtcTraversalRelay ? CrossDeskTraversalModeRelay : CrossDeskTraversalModeUnknown}; NSString *decoder = [[NSString alloc] initWithBytes:stats->video_decoder diff --git a/deps/submodules/minirtc b/deps/submodules/minirtc index 903d7a06..d58bb8b9 160000 --- a/deps/submodules/minirtc +++ b/deps/submodules/minirtc @@ -1 +1 @@ -Subproject commit 903d7a06cc015f9f124e3859882999e8180e11e3 +Subproject commit d58bb8b9dd1aebea2d483afd6c550e1f8a144f40 diff --git a/docs/connection-architecture.md b/docs/connection-architecture.md index ae6e8445..d68751b8 100644 --- a/docs/connection-architecture.md +++ b/docs/connection-architecture.md @@ -76,9 +76,9 @@ sequenceDiagram end ``` -1. `GuiRuntime::CreateConnectionPeer()` 创建本机的常驻 MiniRTC Peer,`Init()` 连接信令服务并登录。控制另一个设备时,`ConnectTo()` 创建或复用对应的 `RemoteSession` 和控制端 Peer;该会话 Peer 以 `C-<本机ID>` 作为登录身份,使用独立的信令连接。 +1. `GuiRuntime::CreateConnectionPeer()` 创建本机的常驻 MiniRTC Peer,`MiniRtcInit()` 连接信令服务并登录。控制另一个设备时,`ConnectTo()` 创建或复用对应的 `RemoteSession` 和控制端 Peer;该会话 Peer 以 `C-<本机ID>` 作为登录身份,使用独立的信令连接。 2. 普通交互连接在需要时进行在线探测;桌面墙后台连接可以直接由 Join 结果判定可用性。没有密码时先在本地弹窗收集,不先发送一次空密码请求。 -3. 当前桌面调用为 `JoinConnection(peer, "目标ID@密码")`,MiniRTC 将其放入 `join_transmission` 的 `transmission_id`,经 WSS 提交给信令服务。登录尚未完成时,Join 会等待登录结果。 +3. 当前桌面调用为 `MiniRtcJoinConnection(peer, "目标ID@密码")`,MiniRTC 将其放入 `join_transmission` 的 `transmission_id`,经 WSS 提交给信令服务。登录尚未完成时,Join 会等待登录结果。 4. 服务端的加入通知驱动被控端发起 offer,控制端回复 answer;双方通过服务端转发 ICE 候选。支持新版协议的服务端提供每次连接的 ICE 配置及有效期,客户端仍保留旧服务端兼容路径。 5. MiniRTC 根据中继设置、对端能力和网络条件选择直连或中继。数据不通过信令 WebSocket 搬运。当前桌面端始终请求 SRTP;原生 ID 会话仍允许第 4.1 节所述的旧端兼容行为,因此请求 SRTP 不代表所有数据最终都经过加密。 @@ -160,9 +160,9 @@ sequenceDiagram end ``` -IP 直连由**控制端**发起 offer。双方内部 ID 和随机 `session_id` 用于本次会话路由,不需要用户填写设备 ID。协商消息带会话 ID 和严格递增序号;会话管理器检查状态顺序,再调用 `ReceiveDirectSignal()`。MiniRTC 进一步检查 SDP、候选数量、地址和 ICE 标识一致性,并去重候选。 +IP 直连由**控制端**发起 offer。双方内部 ID 和随机 `session_id` 用于本次会话路由,不需要用户填写设备 ID。协商消息带会话 ID 和严格递增序号;会话管理器检查状态顺序,再调用 `MiniRtcReceiveDirectSignal()`。MiniRTC 进一步检查 SDP、候选数量、地址和 ICE 标识一致性,并去重候选。 -SessionManager 将当前 WSS socket 的本地与对端 IPv4/IPv6 传入 `InitDirectPeer()`,由 MiniRTC 构造 `HostOnly` 策略,启动独立 ICE worker,不执行云端登录。MiniRTC 通过 `SignalSender` 回调把协商消息交给 SessionManager,再由 WSS 发送。 +SessionManager 将当前 WSS socket 的本地与对端 IPv4/IPv6 传入 `MiniRtcInitDirectPeer()`,由 MiniRTC 构造 `HostOnly` 策略,启动独立 ICE worker,不执行云端登录。MiniRTC 通过 `SignalSender` 回调把协商消息交给 SessionManager,再由 WSS 发送。 MiniRTC 关闭 STUN/TURN 服务器访问、UPnP、ICE TCP 和公网打洞扩展,仅收集指定本机 IPv4/IPv6 的 UDP host 候选。libnice 的 `direct-peer-address` 补丁同时检查远端候选和入站来源:在解析 STUN 连通性检查、学习新候选或回复数据之前,拒绝不匹配的 IP。ICE 自身的 STUN 检查报文仍会在双方之间使用,这与访问 STUN 服务器是两回事。 @@ -188,7 +188,7 @@ WSS 在连接成功后继续承担心跳和会话关闭消息。当前心跳约 旧 ID 首次升级时,客户端先完成签名证明,再按服务端要求提交原有密码;密码验证成功后仅允许绑定一次公钥,保留 ID 和密码。绑定后撤销旧重连令牌并拒绝密码登录,不能用密码覆盖公钥;尚未完成绑定的旧 ID 按来源 IP 及“来源 IP → 目标 ID”限流,不保留目标 ID 的总失败次数。部署时先升级服务端;新桌面客户端要求签名协议,不自动回退到旧服务端的密码登录。混部或回滚到忽略公钥绑定的旧服务端会失去这项保护。 -MiniRTC 的可选 `OnSignalExchange` 回调提供登录请求替换、入站消息处理及回复发送能力,不包含设备密钥、可信名单或 CrossDesk 协议字段。应用层负责签名和协议状态;未配置回调的使用方保留原有登录及内存重连令牌行为。改密中断后,签名登录不代表待定密码已生效,客户端重发持久保存的改密请求,收到成功回复后才更新本地密码。 +MiniRTC 的可选 `MiniRtcOnSignalExchange` 回调提供登录请求替换、入站消息处理及回复发送能力,不包含设备密钥、可信名单或 CrossDesk 协议字段。应用层负责签名和协议状态;未配置回调的使用方保留原有登录及内存重连令牌行为。改密中断后,签名登录不代表待定密码已生效,客户端重发持久保存的改密请求,收到成功回复后才更新本地密码。 连接目标设备时,控制端会话 Peer 仍将 `目标ID@目标密码` 放入 Join,由服务端返回成功、凭据错误、限流或繁忙结果。设备签名登录仅证明本机 ID 所有权,不授予控制其他设备的权限。服务端按已验证控制端 B 和“B → A”组合累计失败(分别为 20/5 次),不保留 A 的总失败次数;B 的失败不会触发 C 连接 A 的密码冷却。认证队列和计算额度也按已验证控制端隔离。未验证的旧客户端、Web/CLI 临时身份按来源 IP 处理,无法通过自称 `C-B` 获得 B 的预算。已绑定 B 的 `C-B` 登录必须支持签名协议;同一 NAT 下旧客户端仍共享 IP 限制,显式 IP 风控与服务器资源上限仍然适用。 @@ -249,7 +249,7 @@ MiniRTC 仅通过现有可靠数据通道收发这些应用消息,不提供可 flowchart TD UI["MainWindow / GuiApplication"] --> ID["GuiRuntime::ConnectTo"] UI --> IP["GuiRuntime::ConnectLan"] - ID --> Managed["MiniRTC Init / JoinConnection"] + ID --> Managed["MiniRtcInit / MiniRtcJoinConnection"] IP --> LAN["LAN SessionManager / Transport"] LAN --> Direct["MiniRTC InitDirectPeer / StartDirectSession"] Managed --> Common["MiniRtcConnection / IceTransport / IceAgent"] @@ -265,7 +265,7 @@ flowchart TD - **业务复用:** `ControllerEvents()`、`WithController()` 等根据会话类型路由到正确 Peer。视频、音频、键鼠、文件、剪贴板仍交给原有回调和功能模块;采集设备按整体连接需求管理。 - **线程分工:** SessionManager 的公开操作和 `Tick()` 在 GUI 管理线程运行;Transport 使用一个共享 Asio 网络线程,回调仅提交有界事件。密码计算、Peer 准备与销毁在后台任务执行,MiniRTC 自身处理 ICE 和媒体工作。 - **数据放行:** LAN 业务回调检查会话授权和关闭状态。加密就绪通知与数据到达可能交错,少量早期控制消息会在有界队列中暂存,授权后按序处理;其他业务数据不因排队而提前获得授权。 -- **关闭顺序:** 标记关闭并停止新回调,取消会话相关传输,关闭 WSS;后台排空已有回调,再执行 `CloseDirectSession()` 和 `DestroyPeer()`。网络回调中不直接销毁 Peer。 +- **关闭顺序:** 标记关闭并停止新回调,取消会话相关传输,关闭 WSS;后台排空已有回调,再执行 `MiniRtcCloseDirectSession()` 和 `MiniRtcDestroyPeer()`。网络回调中不直接销毁 Peer。 - **资源边界:** 当前管理器最多保留 24 个通道,未认证接入最多 16 个,异步密码验证与 Peer 准备各最多 2 个任务,同时准入的准备中/已认证会话最多 8 个。协商还设有消息数量、字节和阶段超时限制,防止无限队列或等待。 关闭 IP 功能时,运行时等待会话、密码任务、准备任务及清理任务全部结束,再释放 LAN 管理器和网络线程。快速关闭后重新开启会等待旧实例排空;应用退出时不会重新创建监听。 diff --git a/docs/deskhub.md b/docs/deskhub.md index a591c4e7..58c1f380 100644 --- a/docs/deskhub.md +++ b/docs/deskhub.md @@ -59,11 +59,11 @@ 可靠控制通道的 `deskhub_preview` v2 保留 v1 的 `request_id`、`fps`、`quality`、`frame_rate`、`preference`、`audio` 字段,新增必填 `width`、`height` 整数,单位为物理像素。两个值均为 0 表示恢复源尺寸上限,否则两个值均须在 2~16384 之间;非法或缺失的值不应用。`deskhub_preview_status` 回传请求的协议版本、请求 ID 与 `accepted`。请求 ID 跳过 0,支持 32 位回绕,重复或过期请求不会覆盖新设置。断开会话清除订阅和 15 FPS 协商能力,再连接会重新发送当前需求。15 FPS 扩展通过可选能力 `supports_deskhub_fps15` 协商,沿用 v1/v2 的字段结构,使用 `fps=15, frame_rate=30`,在编码前将实际输入限制为 15 FPS。 -带宽扩展沿用 v1/v2,增加可选整数 `max_bitrate_bps`(0~100000000,单位 bps),仅向声明 `supports_deskhub_bandwidth` 的对端发送。0 或缺省表示解除额外的视频预算限制;暂停视频仍使用 `fps=0`。非法字段拒绝整个订阅,断开后清除能力,重连重新协商。MiniRTC 的 `UpdateVideoBitrateLimit(peer, remote_id, remote_id_size, max_bitrate_bps)` 为指定连接的所有视频流设置合计预算,不改变音频与数据发送;返回 0 表示已进入拥塞控制队列,-1 表示参数、连接或传输不支持。 +带宽扩展沿用 v1/v2,增加可选整数 `max_bitrate_bps`(0~100000000,单位 bps),仅向声明 `supports_deskhub_bandwidth` 的对端发送。0 或缺省表示解除额外的视频预算限制;暂停视频仍使用 `fps=0`。非法字段拒绝整个订阅,断开后清除能力,重连重新协商。MiniRTC 的 `MiniRtcUpdateVideoBitrateLimit(peer, remote_id, remote_id_size, max_bitrate_bps)` 为指定连接的所有视频流设置合计预算,不改变音频与数据发送;返回 0 表示已进入拥塞控制队列,-1 表示参数、连接或传输不支持。 -MiniRTC 新增 `UpdateVideoResolution(peer, remote_id, remote_id_size, width, height)` 接口,返回 0 表示已接受,-1 表示参数、连接或传输类型不支持。它为指定控制端的所有显示流设置独立尺寸上限,切换时丢弃旧设置尚未发出的编码结果,并请求新关键帧;底层自适应也以这个上限作为有效源尺寸。 +MiniRTC 新增 `MiniRtcUpdateVideoResolution(peer, remote_id, remote_id_size, width, height)` 接口,返回 0 表示已接受,-1 表示参数、连接或传输类型不支持。它为指定控制端的所有显示流设置独立尺寸上限,切换时丢弃旧设置尚未发出的编码结果,并请求新关键帧;底层自适应也以这个上限作为有效源尺寸。 -`SetVideoSendPaused(peer, remote_id, remote_id_size, paused)` 与 `SetAudioSendPaused(peer, remote_id, remote_id_size, paused)` 分别控制指定连接的所有视频/音频发送通道,`true` 暂停、`false` 恢复。重复设置不产生额外操作;返回 0 表示接受,-1 表示参数、连接或传输类型不支持。视频暂停阻止新帧进入编码,废弃旧编码结果,并在发送队列上清除待发视频/重传/纠错包,停止探测和填充;恢复请求新关键帧。音频暂停阻止 PCM 编码并清理待发音频,恢复时仅发送新音频。已交给网络的包无法撤回。API 保留连接、采集源、码率与画质设置以及其他媒体/数据通道,也不改变其他控制端的发送状态。 +`MiniRtcSetVideoSendPaused(peer, remote_id, remote_id_size, paused)` 与 `MiniRtcSetAudioSendPaused(peer, remote_id, remote_id_size, paused)` 分别控制指定连接的所有视频/音频发送通道,`true` 暂停、`false` 恢复。重复设置不产生额外操作;返回 0 表示接受,-1 表示参数、连接或传输类型不支持。视频暂停阻止新帧进入编码,废弃旧编码结果,并在发送队列上清除待发视频/重传/纠错包,停止探测和填充;恢复请求新关键帧。音频暂停阻止 PCM 编码并清理待发音频,恢复时仅发送新音频。已交给网络的包无法撤回。API 保留连接、采集源、码率与画质设置以及其他媒体/数据通道,也不改变其他控制端的发送状态。 桌面墙将 `fps=0` 和 `audio=false` 分别映射到上述 API;应用层仅保留低帧率节流,不再使用 `1 bps` 代替视频暂停或在采集回调中过滤静音音频。接收端仍保留静音门控及播放队列清理,以立即停止播放网络中已在途的音频。旧版 `audio_capture` 命令在支持新 API 的传输中也按连接静音,已有订阅的音频状态优先;不支持 API 的旧/Web 传输沿用采集开关回退。 diff --git a/docs/gui-architecture.md b/docs/gui-architecture.md index 7b8aeceb..7aeb7c8f 100644 --- a/docs/gui-architecture.md +++ b/docs/gui-architecture.md @@ -170,7 +170,7 @@ MainWindow::connect_requested → GuiRuntime::ConnectTo → 在线状态探测 → 创建或复用 RemoteSession - → MiniRTC JoinConnection + → MiniRtcJoinConnection → PeerEventHandler 接收连接状态 → SyncStreamWindow 创建串流窗口并开始呈现视频 ``` diff --git a/libs/controller/include/controller_session.h b/libs/controller/include/controller_session.h index e35d5050..bd8113ae 100644 --- a/libs/controller/include/controller_session.h +++ b/libs/controller/include/controller_session.h @@ -113,12 +113,12 @@ private: void Enqueue(Event event) noexcept; void Fail(const char *reason); void ClosePeers(); - Params Parameters(); + MiniRtcParams Parameters(); bool Send(const char *stream, const std::string &payload); bool SendInput(const char *stream, const RemoteAction &action); void Preview(); - static void Signal(SignalStatus, const char *, size_t, void *); - static void Connection(ConnectionStatus, const char *, size_t, void *); + static void Signal(MiniRtcSignalStatus, const char *, size_t, void *); + static void Connection(MiniRtcConnectionStatus, const char *, size_t, void *); static void Data(const char *, size_t, const char *, size_t, const char *, size_t, void *); static void Audio(const char *, size_t, const char *, size_t, @@ -127,11 +127,11 @@ private: const char *, size_t, void *); static int EncodedVideo(const uint8_t *, size_t, int64_t, const char *, size_t, const char *, size_t, void *); - static void Network(const char *, size_t, TraversalMode, + static void Network(const char *, size_t, MiniRtcTraversalMode, const MiniRtcNetTrafficStats *, const char *, size_t, void *); SessionOptions options_; - PeerPtr *peer_ = nullptr; + MiniRtcPeerPtr *peer_ = nullptr; std::string state_ = "idle", error_, device_, password_, client_id_; nlohmann::json remote_capabilities_ = nlohmann::json::object(); uint64_t remote_sequence_ = 0, capability_request_ = 0; @@ -160,7 +160,7 @@ private: uint64_t callback_generation_ = 0; int callback_display_ = 0; MiniRtcNetTrafficStats network_{}; - TraversalMode traversal_ = UnknownMode; + MiniRtcTraversalMode traversal_ = MiniRtcTraversalUnknown; LatestFrame frames_; bool audio_enabled_ = false; size_t audio_bytes_ = 0; diff --git a/libs/controller/include/mobile_controller_protocol.h b/libs/controller/include/mobile_controller_protocol.h index 445b0404..0a49e4b2 100644 --- a/libs/controller/include/mobile_controller_protocol.h +++ b/libs/controller/include/mobile_controller_protocol.h @@ -34,7 +34,7 @@ inline std::string VideoSettingsMessage(int quality, int frame_rate, int prefere return action.to_json(); } -inline nlohmann::json NetworkReport(const MiniRtcNetTrafficStats& stats, TraversalMode mode) { +inline nlohmann::json NetworkReport(const MiniRtcNetTrafficStats& stats, MiniRtcTraversalMode mode) { const auto traffic = [](const MiniRtcInboundStats& in, const MiniRtcOutboundStats& out) { return nlohmann::json{{"inbound", in.bitrate}, {"outbound", out.bitrate}, {"loss", in.loss_rate}}; }; diff --git a/libs/controller/src/controller_session.cpp b/libs/controller/src/controller_session.cpp index f6414497..d2c5078a 100644 --- a/libs/controller/src/controller_session.cpp +++ b/libs/controller/src/controller_session.cpp @@ -25,7 +25,7 @@ void ControllerSession::Enqueue(Event e) noexcept { } catch (...) { /* Allocation failure cannot escape a C callback. */ } } -void ControllerSession::Signal(SignalStatus s, const char *id, size_t n, +void ControllerSession::Signal(MiniRtcSignalStatus s, const char *id, size_t n, void *p) { try { static_cast(p)->Enqueue( @@ -33,7 +33,7 @@ void ControllerSession::Signal(SignalStatus s, const char *id, size_t n, } catch (...) { } } -void ControllerSession::Connection(ConnectionStatus s, const char *, size_t, +void ControllerSession::Connection(MiniRtcConnectionStatus s, const char *, size_t, void *p) { auto &session = *static_cast(p); session.Enqueue({1, s, {}}); @@ -73,7 +73,7 @@ void ControllerSession::Video(const MiniRtcVideoFrame *f, const char *, size_t, } catch (...) { } } -void ControllerSession::Network(const char *, size_t, TraversalMode mode, +void ControllerSession::Network(const char *, size_t, MiniRtcTraversalMode mode, const MiniRtcNetTrafficStats *stats, const char *, size_t, void *p) { auto &session = *static_cast(p); @@ -83,8 +83,8 @@ void ControllerSession::Network(const char *, size_t, TraversalMode mode, session.traversal_ = mode; } } -Params ControllerSession::Parameters() { - Params p{}; +MiniRtcParams ControllerSession::Parameters() { + MiniRtcParams p{}; std::snprintf(p.signal_server_ip, sizeof(p.signal_server_ip), "%s", options_.host.c_str()); std::snprintf(p.log_path, sizeof(p.log_path), "%s", @@ -93,13 +93,13 @@ Params ControllerSession::Parameters() { p.hardware_acceleration = options_.hardware_acceleration; p.native_video_output = true; p.av1_encoding = false; - p.turn_mode = TurnAutoUdpTcp; + p.turn_mode = MiniRtcTurnAutoUdpTcp; p.enable_srtp = true; - p.video_content_type = VideoContentType::ScreenContent; - p.video_quality = QualityLow; + p.video_content_type = MiniRtcVideoContentType::ScreenContent; + p.video_quality = MiniRtcVideoQualityLow; p.video_frame_rate = 30; p.video_degradation_preference = - VideoDegradationPreference::MaintainResolution; + MiniRtcVideoDegradationPreference::MaintainResolution; p.on_signal_status = Signal; p.on_connection_status = Connection; p.on_net_status_report = Network; @@ -149,7 +149,7 @@ void ControllerSession::Connect(SessionOptions options, std::string device, overflow_ = false; events_.clear(); network_ = {}; - traversal_ = UnknownMode; + traversal_ = MiniRtcTraversalUnknown; callback_generation_ = ++generation_; callback_display_ = options_.display; frames_.Reset(generation_); @@ -160,19 +160,19 @@ void ControllerSession::Connect(SessionOptions options, std::string device, InitializeControllerDiagnostics(options_.log_directory); WriteControllerDiagnostic("Session registering"); auto p = Parameters(); - peer_ = CreatePeer(&p); + peer_ = MiniRtcCreatePeer(&p); if (!peer_) { Fail("media_initialization_failed"); return; } - AddAudioStream(peer_, kAudioStream); - AddDataStream(peer_, kDataStream, false); + MiniRtcAddAudioStream(peer_, kAudioStream); + MiniRtcAddDataStream(peer_, kDataStream, false); for (auto stream : {kMouseStream, kKeyboardStream, kControlStream}) - AddDataStream(peer_, stream, true); - AddDataStream(peer_, web_clipboard::kStream, true); - AddDataStream(peer_, kFileStream, true); - AddDataStream(peer_, kFileFeedbackStream, true); - if (Init(peer_) != 0) + MiniRtcAddDataStream(peer_, stream, true); + MiniRtcAddDataStream(peer_, web_clipboard::kStream, true); + MiniRtcAddDataStream(peer_, kFileStream, true); + MiniRtcAddDataStream(peer_, kFileFeedbackStream, true); + if (MiniRtcInit(peer_) != 0) Fail("media_initialization_failed"); } void ControllerSession::Tick() { @@ -198,26 +198,26 @@ void ControllerSession::Tick() { break; if (e.kind == 0) { WriteControllerDiagnostic("Signal status: " + std::to_string(e.code)); - if (e.code == SignalTlsCertError) { + if (e.code == MiniRtcSignalTlsCertError) { Fail("tls_certificate_error"); break; } - if (e.code == SignalFailed) { + if (e.code == MiniRtcSignalFailed) { Fail("signaling_login_failed"); break; } // The initial signaling transport can recover before a remote join is // sent. Keep its backoff worker alive within the original deadline. - if (e.code == SignalReconnecting && state_ == "registering") { + if (e.code == MiniRtcSignalReconnecting && state_ == "registering") { WriteControllerDiagnostic("Initial signaling retry within connection deadline"); continue; } - if (e.code == SignalClosed || e.code == SignalServerClosed || - e.code == SignalReconnecting) { + if (e.code == MiniRtcSignalClosed || e.code == MiniRtcSignalServerClosed || + e.code == MiniRtcSignalReconnecting) { Fail("signaling_disconnected"); break; } - if (e.code != SignalConnected) + if (e.code != MiniRtcSignalConnected) continue; if (state_ == "registering") { if (e.data.size() != 13 || e.data.rfind("cli-", 0) != 0 || @@ -228,14 +228,14 @@ void ControllerSession::Tick() { client_id_ = e.data; state_ = "connecting"; const auto join = device_ + "@" + password_; - if (JoinConnection(peer_, join.c_str()) != 0) + if (MiniRtcJoinConnection(peer_, join.c_str()) != 0) Fail("join_request_failed"); std::fill(password_.begin(), password_.end(), '\0'); password_.clear(); } } else if (e.kind == 1) { WriteControllerDiagnostic("Connection status: " + std::to_string(e.code) + " (session " + state_ + ")"); - if (e.code == ::Connected && !Connected()) { + if (e.code == MiniRtcConnectionConnected && !Connected()) { state_ = "connected"; auto hello = MakeHostInformation("CrossDesk CLI", {}, false); Send(kControlStream, hello.to_json()); @@ -245,15 +245,15 @@ void ControllerSession::Tick() { mute.a = false; Send(kControlStream, mute.to_json()); capability_request_ = RequestRemote("capabilities"); - } else if (e.code == IncorrectPassword) + } else if (e.code == MiniRtcConnectionIncorrectPassword) Fail("incorrect_password"); - else if (e.code == NoSuchTransmissionId) + else if (e.code == MiniRtcConnectionNoSuchTransmissionId) Fail("device_not_found"); - else if (e.code == RemoteUnavailable) + else if (e.code == MiniRtcConnectionRemoteUnavailable) Fail("device_offline_or_unavailable"); - else if (e.code == Failed) + else if (e.code == MiniRtcConnectionFailed) Fail(Connected() ? "connection_lost" : "connection_failed"); - else if (e.code == Closed || e.code == Disconnected) + else if (e.code == MiniRtcConnectionClosed || e.code == MiniRtcConnectionDisconnected) Fail("remote_disconnected"); } else if ((e.kind == 4 || e.kind == 5) && Connected()) { if (files_) files_->Receive(e.data.data(), e.data.size(), e.kind == 5); @@ -299,7 +299,7 @@ void ControllerSession::Tick() { if (remote_capabilities_.value("files", json{}) == true) files_ = std::make_unique([this](const char *stream, const std::string &data) { if (!peer_ || !Connected()) return false; - return SendReliableDataFrame(peer_, data.data(), data.size(), stream) == 0; + return MiniRtcSendReliableDataFrame(peer_, data.data(), data.size(), stream) == 0; }); remote_results_.erase(found); } @@ -340,7 +340,7 @@ void ControllerSession::Tick() { } bool ControllerSession::Send(const char *stream, const std::string &payload) { return peer_ && Connected() && !payload.empty() && - SendReliableDataFrame(peer_, payload.data(), payload.size(), stream) == + MiniRtcSendReliableDataFrame(peer_, payload.data(), payload.size(), stream) == 0; } void ControllerSession::ClosePeers() { @@ -355,8 +355,8 @@ void ControllerSession::ClosePeers() { frames_.Reset(generation_); } if (peer_) { - LeaveConnection(peer_, device_.c_str()); - DestroyPeer(&peer_); + MiniRtcLeaveConnection(peer_, device_.c_str()); + MiniRtcDestroyPeer(&peer_); } std::fill(password_.begin(), password_.end(), '\0'); password_.clear(); @@ -431,7 +431,7 @@ void ControllerSession::Preview() { s.frame_rate = options_.fps > 30 ? 60 : 30; // Preserve desktop text detail at every cadence, including 30 FPS previews. s.preference = - static_cast(VideoDegradationPreference::MaintainResolution); + static_cast(MiniRtcVideoDegradationPreference::MaintainResolution); s.audio = audio_enabled_; s.quality = options_.quality; if (resolution_) {