Better RTCError handling + tests
This commit is contained in:
Generated
+40
-6
@@ -439,9 +439,9 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
"prost",
|
"prost 0.11.0",
|
||||||
"prost-build",
|
"prost-build",
|
||||||
"prost-types",
|
"prost-types 0.11.1",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
@@ -456,6 +456,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"libwebrtc-sys",
|
"libwebrtc-sys",
|
||||||
"log",
|
"log",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -597,7 +598,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e"
|
checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"prost-derive",
|
"prost-derive 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "399c3c31cdec40583bb68f0b18403400d01ec4289c383aa047560439952c4dd7"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"prost-derive 0.11.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -615,8 +626,8 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"multimap",
|
"multimap",
|
||||||
"petgraph",
|
"petgraph",
|
||||||
"prost",
|
"prost 0.10.4",
|
||||||
"prost-types",
|
"prost-types 0.10.1",
|
||||||
"regex",
|
"regex",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"which",
|
"which",
|
||||||
@@ -635,6 +646,19 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-derive"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"itertools",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prost-types"
|
name = "prost-types"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
@@ -642,7 +666,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68"
|
checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"prost",
|
"prost 0.10.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-types"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4dfaa718ad76a44b3415e6c4d53b17c8f99160dcb3a99b10470fce8ad43f6e3e"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"prost 0.11.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
name = "livekit-core"
|
name = "livekit-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
crate-type = ["lib"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
@@ -10,9 +9,9 @@ tokio-tungstenite = "0.17.2"
|
|||||||
tokio = { version = "1.20.1", features = ["full"] }
|
tokio = { version = "1.20.1", features = ["full"] }
|
||||||
url = "2.2.2"
|
url = "2.2.2"
|
||||||
futures-util = "0.3.23"
|
futures-util = "0.3.23"
|
||||||
thiserror = "1.0.32"
|
thiserror = "1.0"
|
||||||
prost = "0.10"
|
prost = "0.11.0"
|
||||||
prost-types = "0.10"
|
prost-types = "0.11.1"
|
||||||
anyhow = "1.0.63"
|
anyhow = "1.0.63"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ libwebrtc-sys = { path = "./libwebrtc-sys" }
|
|||||||
tokio = { version = "1.20.1", features = ["full"] }
|
tokio = { version = "1.20.1", features = ["full"] }
|
||||||
cxx = "1.0"
|
cxx = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.9"
|
env_logger = "0.9"
|
||||||
@@ -235,21 +235,22 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(theomonnom) Only add this define when building tests
|
||||||
|
builder.define("LIVEKIT_TEST", None);
|
||||||
|
|
||||||
builder.warnings(false).compile("lkwebrtc");
|
builder.warnings(false).compile("lkwebrtc");
|
||||||
|
|
||||||
for entry in glob::glob("./src/**/*.cpp").unwrap() {
|
for entry in glob::glob("./src/**/*.cpp").unwrap() {
|
||||||
println!(
|
println!(
|
||||||
"cargo:rerun-if-changed={}",
|
"cargo:rerun-if-changed={}",
|
||||||
entry.unwrap().display().to_string()
|
entry.unwrap().display()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for entry in glob::glob("./include/**/*.h").unwrap() {
|
for entry in glob::glob("./include/**/*.h").unwrap() {
|
||||||
println!(
|
println!(
|
||||||
"cargo:rerun-if-changed={}",
|
"cargo:rerun-if-changed={}",
|
||||||
entry.unwrap().display().to_string()
|
entry.unwrap().display()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/main.rs");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,20 @@
|
|||||||
#define CLIENT_SDK_NATIVE_RTC_ERROR_H
|
#define CLIENT_SDK_NATIVE_RTC_ERROR_H
|
||||||
|
|
||||||
#include "api/rtc_error.h"
|
#include "api/rtc_error.h"
|
||||||
|
#include "libwebrtc-sys/src/rtc_error.rs.h"
|
||||||
|
#include "rust_types.h"
|
||||||
|
#include "rust/cxx.h"
|
||||||
|
|
||||||
namespace livekit {
|
namespace livekit {
|
||||||
|
|
||||||
class RTCError {
|
RTCError to_error(const webrtc::RTCError &error);
|
||||||
public:
|
std::string serialize_error(const RTCError &error); // to be used inside cxx::Exception msg
|
||||||
explicit RTCError(webrtc::RTCError error);
|
|
||||||
|
|
||||||
private:
|
#ifdef LIVEKIT_TEST
|
||||||
webrtc::RTCError rtc_error_;
|
rust::String serialize_deserialize();
|
||||||
};
|
void throw_error();
|
||||||
|
#endif
|
||||||
|
|
||||||
static std::unique_ptr<RTCError> _unique_rtc_error(){
|
|
||||||
return nullptr; // Ignore
|
|
||||||
}
|
|
||||||
} // livekit
|
} // livekit
|
||||||
|
|
||||||
#endif //CLIENT_SDK_NATIVE_RTC_ERROR_H
|
#endif //CLIENT_SDK_NATIVE_RTC_ERROR_H
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace livekit {
|
|||||||
|
|
||||||
// Shared types
|
// Shared types
|
||||||
struct RTCOfferAnswerOptions;
|
struct RTCOfferAnswerOptions;
|
||||||
|
struct RTCError;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //RUST_TYPES_H
|
#endif //RUST_TYPES_H
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "livekit/rtc_error.h"
|
||||||
#include "livekit/jsep.h"
|
#include "livekit/jsep.h"
|
||||||
#include "libwebrtc-sys/src/jsep.rs.h"
|
#include "libwebrtc-sys/src/jsep.rs.h"
|
||||||
#include "api/make_ref_counted.h"
|
#include "api/make_ref_counted.h"
|
||||||
@@ -39,7 +40,7 @@ namespace livekit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NativeCreateSdpObserver::OnFailure(webrtc::RTCError error) {
|
void NativeCreateSdpObserver::OnFailure(webrtc::RTCError error) {
|
||||||
observer_->on_failure(std::make_unique<RTCError>(error));
|
observer_->on_failure(to_error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<NativeCreateSdpObserverHandle> create_native_create_sdp_observer(rust::Box<CreateSdpObserverWrapper> observer){
|
std::unique_ptr<NativeCreateSdpObserverHandle> create_native_create_sdp_observer(rust::Box<CreateSdpObserverWrapper> observer){
|
||||||
@@ -55,7 +56,7 @@ namespace livekit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NativeSetLocalSdpObserver::OnSetLocalDescriptionComplete(webrtc::RTCError error) {
|
void NativeSetLocalSdpObserver::OnSetLocalDescriptionComplete(webrtc::RTCError error) {
|
||||||
observer_->on_set_local_description_complete(std::make_unique<RTCError>(error));
|
observer_->on_set_local_description_complete(to_error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<NativeSetLocalSdpObserverHandle> create_native_set_local_sdp_observer(rust::Box<SetLocalSdpObserverWrapper> observer){
|
std::unique_ptr<NativeSetLocalSdpObserverHandle> create_native_set_local_sdp_observer(rust::Box<SetLocalSdpObserverWrapper> observer){
|
||||||
@@ -71,7 +72,7 @@ namespace livekit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NativeSetRemoteSdpObserver::OnSetRemoteDescriptionComplete(webrtc::RTCError error) {
|
void NativeSetRemoteSdpObserver::OnSetRemoteDescriptionComplete(webrtc::RTCError error) {
|
||||||
observer_->on_set_remote_description_complete(std::make_unique<RTCError>(error));
|
observer_->on_set_remote_description_complete(to_error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<NativeSetRemoteSdpObserverHandle> create_native_set_remote_sdp_observer(rust::Box<SetRemoteSdpObserverWrapper> observer){
|
std::unique_ptr<NativeSetRemoteSdpObserverHandle> create_native_set_remote_sdp_observer(rust::Box<SetRemoteSdpObserverWrapper> observer){
|
||||||
|
|||||||
@@ -5,21 +5,22 @@ use crate::rtc_error::ffi::RTCError;
|
|||||||
|
|
||||||
#[cxx::bridge(namespace = "livekit")]
|
#[cxx::bridge(namespace = "livekit")]
|
||||||
pub mod ffi {
|
pub mod ffi {
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
type CreateSdpObserverWrapper;
|
type CreateSdpObserverWrapper;
|
||||||
fn on_success(self: &CreateSdpObserverWrapper, session_description: UniquePtr<SessionDescription>);
|
fn on_success(self: &CreateSdpObserverWrapper, session_description: UniquePtr<SessionDescription>);
|
||||||
fn on_failure(self: &CreateSdpObserverWrapper, error: UniquePtr<RTCError>);
|
fn on_failure(self: &CreateSdpObserverWrapper, error: RTCError);
|
||||||
|
|
||||||
type SetLocalSdpObserverWrapper;
|
type SetLocalSdpObserverWrapper;
|
||||||
fn on_set_local_description_complete(self: &SetLocalSdpObserverWrapper, error: UniquePtr<RTCError>);
|
fn on_set_local_description_complete(self: &SetLocalSdpObserverWrapper, error: RTCError);
|
||||||
|
|
||||||
type SetRemoteSdpObserverWrapper;
|
type SetRemoteSdpObserverWrapper;
|
||||||
fn on_set_remote_description_complete(self: &SetRemoteSdpObserverWrapper, error: UniquePtr<RTCError>);
|
fn on_set_remote_description_complete(self: &SetRemoteSdpObserverWrapper, error: RTCError);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
|
include!("libwebrtc-sys/src/rtc_error.rs.h");
|
||||||
include!("livekit/jsep.h");
|
include!("livekit/jsep.h");
|
||||||
include!("livekit/rtc_error.h");
|
|
||||||
|
|
||||||
type RTCError = crate::rtc_error::ffi::RTCError;
|
type RTCError = crate::rtc_error::ffi::RTCError;
|
||||||
type IceCandidate;
|
type IceCandidate;
|
||||||
@@ -41,7 +42,7 @@ pub mod ffi {
|
|||||||
|
|
||||||
pub trait CreateSdpObserver: Send + Sync {
|
pub trait CreateSdpObserver: Send + Sync {
|
||||||
fn on_success(&self, session_description: UniquePtr<ffi::SessionDescription>);
|
fn on_success(&self, session_description: UniquePtr<ffi::SessionDescription>);
|
||||||
fn on_failure(&self, error: UniquePtr<RTCError>);
|
fn on_failure(&self, error: RTCError);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CreateSdpObserverWrapper {
|
pub struct CreateSdpObserverWrapper {
|
||||||
@@ -59,7 +60,7 @@ impl CreateSdpObserverWrapper {
|
|||||||
self.observer.on_success(session_description);
|
self.observer.on_success(session_description);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_failure(&self, error: UniquePtr<RTCError>) {
|
fn on_failure(&self, error: RTCError) {
|
||||||
self.observer.on_failure(error);
|
self.observer.on_failure(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +68,7 @@ impl CreateSdpObserverWrapper {
|
|||||||
// SetLocalSdpObserver
|
// SetLocalSdpObserver
|
||||||
|
|
||||||
pub trait SetLocalSdpObserver: Send + Sync {
|
pub trait SetLocalSdpObserver: Send + Sync {
|
||||||
fn on_set_local_description_complete(&self, error: UniquePtr<RTCError>);
|
fn on_set_local_description_complete(&self, error: RTCError);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SetLocalSdpObserverWrapper {
|
pub struct SetLocalSdpObserverWrapper {
|
||||||
@@ -81,7 +82,7 @@ impl SetLocalSdpObserverWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_set_local_description_complete(&self, error: UniquePtr<RTCError>) {
|
fn on_set_local_description_complete(&self, error: RTCError) {
|
||||||
self.observer.on_set_local_description_complete(error);
|
self.observer.on_set_local_description_complete(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,7 +90,7 @@ impl SetLocalSdpObserverWrapper {
|
|||||||
// SetRemoteSdpObserver
|
// SetRemoteSdpObserver
|
||||||
|
|
||||||
pub trait SetRemoteSdpObserver: Send + Sync {
|
pub trait SetRemoteSdpObserver: Send + Sync {
|
||||||
fn on_set_remote_description_complete(&self, error: UniquePtr<RTCError>);
|
fn on_set_remote_description_complete(&self, error: RTCError);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SetRemoteSdpObserverWrapper {
|
pub struct SetRemoteSdpObserverWrapper {
|
||||||
@@ -103,7 +104,7 @@ impl SetRemoteSdpObserverWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_set_remote_description_complete(&self, error: UniquePtr<RTCError>) {
|
fn on_set_remote_description_complete(&self, error: RTCError) {
|
||||||
self.observer.on_set_remote_description_complete(error);
|
self.observer.on_set_remote_description_complete(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,44 +24,44 @@ pub mod ffi {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum PeerConnectionState {
|
pub enum PeerConnectionState {
|
||||||
kNew,
|
New,
|
||||||
kConnecting,
|
Connecting,
|
||||||
kConnected,
|
Connected,
|
||||||
kDisconnected,
|
Disconnected,
|
||||||
kFailed,
|
Failed,
|
||||||
kClosed,
|
Closed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum SignalingState {
|
pub enum SignalingState {
|
||||||
kStable,
|
Stable,
|
||||||
kHaveLocalOffer,
|
HaveLocalOffer,
|
||||||
kHaveLocalPrAnswer,
|
HaveLocalPrAnswer,
|
||||||
kHaveRemoteOffer,
|
HaveRemoteOffer,
|
||||||
kHaveRemotePrAnswer,
|
HaveRemotePrAnswer,
|
||||||
kClosed,
|
Closed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum IceConnectionState {
|
pub enum IceConnectionState {
|
||||||
kIceConnectionNew,
|
IceConnectionNew,
|
||||||
kIceConnectionChecking,
|
IceConnectionChecking,
|
||||||
kIceConnectionConnected,
|
IceConnectionConnected,
|
||||||
kIceConnectionCompleted,
|
IceConnectionCompleted,
|
||||||
kIceConnectionFailed,
|
IceConnectionFailed,
|
||||||
kIceConnectionDisconnected,
|
IceConnectionDisconnected,
|
||||||
kIceConnectionClosed,
|
IceConnectionClosed,
|
||||||
kIceConnectionMax,
|
IceConnectionMax,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum IceGatheringState {
|
pub enum IceGatheringState {
|
||||||
kIceGatheringNew,
|
IceGatheringNew,
|
||||||
kIceGatheringGathering,
|
IceGatheringGathering,
|
||||||
kIceGatheringComplete
|
IceGatheringComplete
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "api/task_queue/default_task_queue_factory.h"
|
#include "api/task_queue/default_task_queue_factory.h"
|
||||||
#include "api/rtc_event_log/rtc_event_log_factory.h"
|
#include "api/rtc_event_log/rtc_event_log_factory.h"
|
||||||
#include "libwebrtc-sys/src/peer_connection_factory.rs.h"
|
#include "libwebrtc-sys/src/peer_connection_factory.rs.h"
|
||||||
|
#include "livekit/rtc_error.h"
|
||||||
|
|
||||||
namespace livekit{
|
namespace livekit{
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ namespace livekit{
|
|||||||
auto result = peer_factory_->CreatePeerConnectionOrError(*config, std::move(deps));
|
auto result = peer_factory_->CreatePeerConnectionOrError(*config, std::move(deps));
|
||||||
|
|
||||||
if(!result.ok()){
|
if(!result.ok()){
|
||||||
throw std::runtime_error(result.error().message()); // TODO(theomonnom) Bridge RTCError - Mb use ProtoBuf
|
throw std::runtime_error(serialize_error(to_error(result.error())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_unique<PeerConnection>(std::move(result.value()), std::move(observer));
|
return std::make_unique<PeerConnection>(std::move(result.value()), std::move(observer));
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ pub mod ffi {
|
|||||||
|
|
||||||
unsafe fn create_peer_connection(self: &PeerConnectionFactory, config: UniquePtr<NativeRTCConfiguration>, observer: UniquePtr<NativePeerConnectionObserver>) -> Result<UniquePtr<PeerConnection>>;
|
unsafe fn create_peer_connection(self: &PeerConnectionFactory, config: UniquePtr<NativeRTCConfiguration>, observer: UniquePtr<NativePeerConnectionObserver>) -> Result<UniquePtr<PeerConnection>>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -51,6 +50,7 @@ pub mod ffi {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -182,5 +182,5 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,54 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "livekit/rtc_error.h"
|
#include "livekit/rtc_error.h"
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace livekit {
|
namespace livekit {
|
||||||
RTCError::RTCError(webrtc::RTCError error) : rtc_error_(std::move(error)) {
|
|
||||||
|
|
||||||
|
RTCError to_error(const webrtc::RTCError &error) {
|
||||||
|
RTCError lk_error;
|
||||||
|
lk_error.error_detail = static_cast<RTCErrorDetailType>(error.error_detail());
|
||||||
|
lk_error.error_type = static_cast<RTCErrorType>(error.type());
|
||||||
|
lk_error.has_sctp_cause_code = error.sctp_cause_code().has_value();
|
||||||
|
lk_error.sctp_cause_code = error.sctp_cause_code().value();
|
||||||
|
lk_error.message = error.message();
|
||||||
|
return lk_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string serialize_error(const RTCError &error) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << std::setfill('0');
|
||||||
|
ss << std::setw(8) << (uint32_t) error.error_type;
|
||||||
|
ss << std::setw(8) << (uint32_t) error.error_detail;
|
||||||
|
ss << std::setw(2) << (uint16_t) error.has_sctp_cause_code;
|
||||||
|
ss << std::setw(4) << (uint16_t) error.sctp_cause_code;
|
||||||
|
ss << std::dec << std::setw(1) << std::string(error.message);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef LIVEKIT_TEST
|
||||||
|
rust::String serialize_deserialize(){
|
||||||
|
RTCError lk_error;
|
||||||
|
lk_error.error_type = RTCErrorType::InternalError;
|
||||||
|
lk_error.error_detail = RTCErrorDetailType::DataChannelFailure;
|
||||||
|
lk_error.has_sctp_cause_code = true;
|
||||||
|
lk_error.sctp_cause_code = 24;
|
||||||
|
lk_error.message = "this is not a test, I repeat, this is not a test";
|
||||||
|
return serialize_error(lk_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void throw_error() {
|
||||||
|
RTCError lk_error;
|
||||||
|
lk_error.error_type = RTCErrorType::InvalidModification;
|
||||||
|
lk_error.error_detail = RTCErrorDetailType::None;
|
||||||
|
lk_error.has_sctp_cause_code = false;
|
||||||
|
lk_error.sctp_cause_code = 0;
|
||||||
|
lk_error.message = "exception is thrown!";
|
||||||
|
throw std::runtime_error(serialize_error(lk_error));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // livekit
|
} // livekit
|
||||||
@@ -1,13 +1,115 @@
|
|||||||
|
use std::fmt::{Display, Formatter};
|
||||||
// TODO(theomonnom) Don't use RTCError as Opaque. I should use a Struct and serialize/deserialize when needed for Result<>
|
use std::error::Error;
|
||||||
|
|
||||||
#[cxx::bridge(namespace = "livekit")]
|
#[cxx::bridge(namespace = "livekit")]
|
||||||
pub mod ffi {
|
pub mod ffi {
|
||||||
unsafe extern "C++" {
|
|
||||||
include!("livekit/rtc_error.h");
|
|
||||||
|
|
||||||
type RTCError;
|
#[derive(Debug)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum RTCErrorType {
|
||||||
|
None,
|
||||||
|
UnsupportedOperation,
|
||||||
|
UnsupportedParameter,
|
||||||
|
InvalidParameter,
|
||||||
|
InvalidRange,
|
||||||
|
SyntaxError,
|
||||||
|
InvalidState,
|
||||||
|
InvalidModification,
|
||||||
|
NetworkError,
|
||||||
|
ResourceExhausted,
|
||||||
|
InternalError,
|
||||||
|
OperationErrorWithData,
|
||||||
|
}
|
||||||
|
|
||||||
fn _unique_rtc_error() -> UniquePtr<RTCError>;
|
#[derive(Debug)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum RTCErrorDetailType {
|
||||||
|
None,
|
||||||
|
DataChannelFailure,
|
||||||
|
DtlsFailure,
|
||||||
|
FingerprintFailure,
|
||||||
|
SctpFailure,
|
||||||
|
SdpSyntaxError,
|
||||||
|
HardwareEncoderNotAvailable,
|
||||||
|
HardwareEncoderError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RTCError {
|
||||||
|
pub error_type: RTCErrorType,
|
||||||
|
pub message: String,
|
||||||
|
pub error_detail: RTCErrorDetailType,
|
||||||
|
pub has_sctp_cause_code: bool, // cxx doesn't support the Option trait
|
||||||
|
pub sctp_cause_code: u16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ffi::RTCError {
|
||||||
|
/// # Safety
|
||||||
|
/// The value must be correctly encoded
|
||||||
|
pub unsafe fn from(value: &str) -> Self {
|
||||||
|
// Parse the hex encoded error from c++
|
||||||
|
let error_type = u32::from_str_radix(&value[0..8], 16).unwrap();
|
||||||
|
let error_detail = u32::from_str_radix(&value[8..16], 16).unwrap();
|
||||||
|
let has_scp_cause_code = u8::from_str_radix(&value[16..18], 16).unwrap();
|
||||||
|
let sctp_cause_code = u16::from_str_radix(&value[18..22], 16).unwrap();
|
||||||
|
let message = String::from(&value[22..]); // msg isn't encoded
|
||||||
|
|
||||||
|
Self {
|
||||||
|
error_type: unsafe { std::mem::transmute(error_type) },
|
||||||
|
error_detail: unsafe { std::mem::transmute(error_detail) },
|
||||||
|
sctp_cause_code,
|
||||||
|
has_sctp_cause_code: has_scp_cause_code == 1,
|
||||||
|
message,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for ffi::RTCError {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ffi::RTCError {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "RtcError occurred {:?}: {}", self.error_type, self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::rtc_error::ffi::{RTCError, RTCErrorDetailType, RTCErrorType};
|
||||||
|
|
||||||
|
#[cxx::bridge(namespace = "livekit")]
|
||||||
|
pub mod ffi {
|
||||||
|
unsafe extern "C++" {
|
||||||
|
include!("livekit/rtc_error.h");
|
||||||
|
|
||||||
|
fn serialize_deserialize() -> String;
|
||||||
|
fn throw_error() -> Result<()>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serialize_deserialize(){
|
||||||
|
let str = ffi::serialize_deserialize();
|
||||||
|
let error = unsafe { RTCError::from(&str) };
|
||||||
|
|
||||||
|
assert_eq!(error.error_type, RTCErrorType::InternalError);
|
||||||
|
assert_eq!(error.error_detail, RTCErrorDetailType::DataChannelFailure);
|
||||||
|
assert_eq!(error.has_sctp_cause_code, true);
|
||||||
|
assert_eq!(error.sctp_cause_code, 24);
|
||||||
|
assert_eq!(error.message, "this is not a test, I repeat, this is not a test");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn throw_error(){
|
||||||
|
let exc: cxx::Exception = ffi::throw_error().err().unwrap();
|
||||||
|
let error = unsafe { RTCError::from(exc.what()) };
|
||||||
|
|
||||||
|
assert_eq!(error.error_type, RTCErrorType::InvalidModification);
|
||||||
|
assert_eq!(error.error_detail, RTCErrorDetailType::None);
|
||||||
|
assert_eq!(error.has_sctp_cause_code, false);
|
||||||
|
assert_eq!(error.sctp_cause_code, 0);
|
||||||
|
assert_eq!(error.message, "exception is thrown!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use cxx::UniquePtr;
|
use cxx::UniquePtr;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::{mpsc, oneshot};
|
||||||
use libwebrtc_sys::peer_connection as sys_pc;
|
use libwebrtc_sys::peer_connection as sys_pc;
|
||||||
use libwebrtc_sys::jsep as sys_jsep;
|
use libwebrtc_sys::jsep as sys_jsep;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::data_channel::DataChannel;
|
use crate::data_channel::DataChannel;
|
||||||
use crate::media_stream::MediaStream;
|
use crate::media_stream::MediaStream;
|
||||||
@@ -18,6 +19,14 @@ pub use libwebrtc_sys::peer_connection::ffi::IceConnectionState;
|
|||||||
pub use libwebrtc_sys::peer_connection::ffi::IceGatheringState;
|
pub use libwebrtc_sys::peer_connection::ffi::IceGatheringState;
|
||||||
pub use libwebrtc_sys::peer_connection::ffi::RTCOfferAnswerOptions;
|
pub use libwebrtc_sys::peer_connection::ffi::RTCOfferAnswerOptions;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum SdpError {
|
||||||
|
#[error("recv failure: {0}")]
|
||||||
|
RecvError(String),
|
||||||
|
#[error("internal libwebrtc error")]
|
||||||
|
RTCError(#[from] RTCError),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PeerConnection {
|
pub struct PeerConnection {
|
||||||
cxx_handle: UniquePtr<sys_pc::ffi::PeerConnection>,
|
cxx_handle: UniquePtr<sys_pc::ffi::PeerConnection>,
|
||||||
observer: InternalObserver
|
observer: InternalObserver
|
||||||
@@ -51,18 +60,43 @@ impl PeerConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_offer(&mut self) -> Result<SessionDescription, RTCError> {
|
pub async fn create_offer(&mut self) -> Result<SessionDescription, SdpError> {
|
||||||
let (tx, mut rx) = mpsc::channel(1);
|
let (tx, mut rx) = mpsc::channel(1);
|
||||||
|
|
||||||
let wrapper = sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx }));
|
let wrapper = sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx }));
|
||||||
let native_wrapper = sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper));
|
let native_wrapper = sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper));
|
||||||
|
|
||||||
self.cxx_handle.pin_mut().create_offer(native_wrapper, RTCOfferAnswerOptions::default());
|
self.cxx_handle.pin_mut().create_offer(native_wrapper, RTCOfferAnswerOptions::default());
|
||||||
rx.recv().await.unwrap()
|
|
||||||
|
match rx.recv().await {
|
||||||
|
Some(value) => value.map_err(Into::into),
|
||||||
|
None => Err(SdpError::RecvError("channel closed".to_string())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_answer(&mut self) -> Result<SessionDescription, RTCError> {
|
pub async fn create_answer(&mut self) -> Result<SessionDescription, SdpError> {
|
||||||
|
let (tx, mut rx) = mpsc::channel(1);
|
||||||
|
|
||||||
|
let wrapper = sys_jsep::CreateSdpObserverWrapper::new(Box::new(InternalCreateSdpObserver { tx }));
|
||||||
|
let native_wrapper = sys_jsep::ffi::create_native_create_sdp_observer(Box::new(wrapper));
|
||||||
|
|
||||||
|
self.cxx_handle.pin_mut().create_answer(native_wrapper, RTCOfferAnswerOptions::default());
|
||||||
|
|
||||||
|
match rx.recv().await {
|
||||||
|
Some(value) => value.map_err(Into::into),
|
||||||
|
None => Err(SdpError::RecvError("channel closed".to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_local_description(&mut self, desc: SessionDescription) -> Result<(), SdpError> {
|
||||||
|
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_remote_description(&mut self, desc: SessionDescription) -> Result<(), SdpError> {
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_signaling_change(&mut self, handler: OnSignalingChangeHandler) {
|
pub fn on_signaling_change(&mut self, handler: OnSignalingChangeHandler) {
|
||||||
@@ -149,11 +183,36 @@ impl sys_jsep::CreateSdpObserver for InternalCreateSdpObserver {
|
|||||||
self.tx.blocking_send(Ok(SessionDescription{})).unwrap(); // TODO
|
self.tx.blocking_send(Ok(SessionDescription{})).unwrap(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_failure(&self, error: UniquePtr<libwebrtc_sys::rtc_error::ffi::RTCError>) {
|
fn on_failure(&self, error: RTCError) {
|
||||||
self.tx.blocking_send(Err(RTCError{})).unwrap(); // TODO
|
self.tx.blocking_send(Err(error)).unwrap(); // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLocalSdpObserver
|
||||||
|
|
||||||
|
struct InternalSetLocalSdpObserver {
|
||||||
|
tx: mpsc::Sender<Result<(), RTCError>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sys_jsep::SetLocalSdpObserver for InternalSetLocalSdpObserver {
|
||||||
|
fn on_set_local_description_complete(&self, error: RTCError) {
|
||||||
|
self.tx.blocking_send(Ok(())).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRemoteSdpObserver
|
||||||
|
|
||||||
|
struct InternalSetRemoteSdpObserver {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sys_jsep::SetRemoteSdpObserver for InternalSetRemoteSdpObserver {
|
||||||
|
fn on_set_remote_description_complete(&self, error: RTCError) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// PeerConnectionObserver
|
// PeerConnectionObserver
|
||||||
|
|
||||||
// TODO(theomonnom) Should we return futures?
|
// TODO(theomonnom) Should we return futures?
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ impl PeerConnectionFactory {
|
|||||||
|
|
||||||
match pc_result {
|
match pc_result {
|
||||||
Ok(cxx_handle) => {
|
Ok(cxx_handle) => {
|
||||||
let pc = PeerConnection::new(cxx_handle);
|
Ok(PeerConnection::new(cxx_handle))
|
||||||
Ok(pc)
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
Err(RTCError{}) // TODO
|
Err(unsafe {RTCError::from(e.what()) }) // TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub use libwebrtc_sys::rtc_error::ffi::RTCError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct RTCError {
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user