/* * Copyright 2026 LiveKit * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "livekit/local_data_track.h" #include "data_track.pb.h" #include "data_track_proto_converter.h" #include "ffi.pb.h" #include "ffi_client.h" #include "livekit/data_track_error.h" #include "lk_log.h" namespace livekit { LocalDataTrack::LocalDataTrack(const proto::OwnedLocalDataTrack& owned) : handle_(static_cast(owned.handle().id())), info_(fromProto(owned.info())) {} Result LocalDataTrack::tryPush(const DataTrackFrame& frame) { return tryPush(frame.payload.data(), frame.payload.size(), frame.user_timestamp); } Result LocalDataTrack::tryPush(std::vector&& payload, std::optional user_timestamp) { const DataTrackFrame frame(std::move(payload), user_timestamp); return tryPush(frame); } Result LocalDataTrack::tryPush(const std::uint8_t* data, std::size_t size, std::optional user_timestamp) { if (!handle_.valid()) { return Result::failure(LocalDataTrackTryPushError{ LocalDataTrackTryPushErrorCode::INVALID_HANDLE, "LocalDataTrack::tryPush: invalid FFI handle"}); } if (size == 0) { return Result::success(); } if (data == nullptr) { return Result::failure(LocalDataTrackTryPushError{ LocalDataTrackTryPushErrorCode::INTERNAL, "LocalDataTrack::tryPush: payload pointer is null"}); } try { proto::FfiRequest req; auto* msg = req.mutable_local_data_track_try_push(); msg->set_track_handle(static_cast(handle_.get())); auto* pf = msg->mutable_frame(); pf->set_payload(data, size); if (user_timestamp.has_value()) { pf->set_user_timestamp(user_timestamp.value()); } const proto::FfiResponse resp = FfiClient::instance().sendRequest(req); const auto& r = resp.local_data_track_try_push(); if (r.has_error()) { return Result::failure(LocalDataTrackTryPushError::fromProto(r.error())); } return Result::success(); } catch (const std::exception& e) { return Result::failure( LocalDataTrackTryPushError{LocalDataTrackTryPushErrorCode::INTERNAL, e.what()}); } } bool LocalDataTrack::isPublished() const { if (!handle_.valid()) { return false; } proto::FfiRequest req; auto* msg = req.mutable_local_data_track_is_published(); msg->set_track_handle(static_cast(handle_.get())); const proto::FfiResponse resp = FfiClient::instance().sendRequest(req); return resp.local_data_track_is_published().is_published(); } void LocalDataTrack::unpublishDataTrack() { if (!handle_.valid()) { return; } proto::FfiRequest req; auto* msg = req.mutable_local_data_track_unpublish(); msg->set_track_handle(static_cast(handle_.get())); (void)FfiClient::instance().sendRequest(req); } } // namespace livekit