File
Blob: firmware/vendor/str0m/tests/data-channel-direct.rs
| 1 | use std::net::Ipv4Addr; |
| 2 | use std::time::{Duration, Instant}; |
| 3 | |
| 4 | use str0m::channel::ChannelConfig; |
| 5 | use str0m::{Candidate, Event, RtcConfig, RtcError}; |
| 6 | use tracing::info_span; |
| 7 | |
| 8 | mod common; |
| 9 | use common::{Peer, TestRtc, init_crypto_default, init_log, progress}; |
| 10 | |
| 11 | #[test] |
| 12 | pub fn data_channel_direct() -> Result<(), RtcError> { |
| 13 | init_log(); |
| 14 | init_crypto_default(); |
| 15 | |
| 16 | let mut l = TestRtc::new(Peer::Left); |
| 17 | |
| 18 | let rtc_r = RtcConfig::new().set_ice_lite(true).build(Instant::now()); |
| 19 | let mut r = TestRtc::new_with_rtc(info_span!("R"), rtc_r); |
| 20 | |
| 21 | let host1 = Candidate::host((Ipv4Addr::new(1, 1, 1, 1), 1000).into(), "udp")?; |
| 22 | let host2 = Candidate::host((Ipv4Addr::new(2, 2, 2, 2), 2000).into(), "udp")?; |
| 23 | l.add_local_candidate(host1.clone()).unwrap(); |
| 24 | l.add_remote_candidate(host2.clone()); |
| 25 | r.add_local_candidate(host2).unwrap(); |
| 26 | r.add_remote_candidate(host1); |
| 27 | |
| 28 | let finger_l = l.direct_api().local_dtls_fingerprint().clone(); |
| 29 | let finger_r = r.direct_api().local_dtls_fingerprint().clone(); |
| 30 | |
| 31 | l.direct_api().set_remote_fingerprint(finger_r); |
| 32 | r.direct_api().set_remote_fingerprint(finger_l); |
| 33 | |
| 34 | let creds_l = l.direct_api().local_ice_credentials(); |
| 35 | let creds_r = r.direct_api().local_ice_credentials(); |
| 36 | |
| 37 | l.direct_api().set_remote_ice_credentials(creds_r); |
| 38 | r.direct_api().set_remote_ice_credentials(creds_l); |
| 39 | |
| 40 | l.direct_api().set_ice_controlling(true); |
| 41 | r.direct_api().set_ice_controlling(false); |
| 42 | |
| 43 | l.direct_api().start_dtls(true).unwrap(); |
| 44 | r.direct_api().start_dtls(false).unwrap(); |
| 45 | |
| 46 | l.direct_api().start_sctp(true); |
| 47 | r.direct_api().start_sctp(false); |
| 48 | |
| 49 | let config = ChannelConfig { |
| 50 | negotiated: Some(1), |
| 51 | label: "my-chan".into(), |
| 52 | ..Default::default() |
| 53 | }; |
| 54 | let cid = l.direct_api().create_data_channel(config.clone()); |
| 55 | r.direct_api().create_data_channel(config); |
| 56 | |
| 57 | loop { |
| 58 | if l.is_connected() || r.is_connected() { |
| 59 | break; |
| 60 | } |
| 61 | progress(&mut l, &mut r)?; |
| 62 | } |
| 63 | |
| 64 | let max = l.last.max(r.last); |
| 65 | l.last = max; |
| 66 | r.last = max; |
| 67 | |
| 68 | loop { |
| 69 | if let Some(mut chan) = l.channel(cid) { |
| 70 | chan.write(false, "Hello world! ".as_bytes()) |
| 71 | .expect("to write string"); |
| 72 | } |
| 73 | |
| 74 | progress(&mut l, &mut r)?; |
| 75 | |
| 76 | if l.duration() > Duration::from_secs(10) { |
| 77 | break; |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | l.direct_api().close_data_channel(cid); |
| 82 | |
| 83 | loop { |
| 84 | progress(&mut l, &mut r)?; |
| 85 | |
| 86 | if l.duration() > Duration::from_secs(12) { |
| 87 | break; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | assert!( |
| 92 | l.events |
| 93 | .iter() |
| 94 | .any(|(_, event)| event == &Event::ChannelOpen(cid, "my-chan".into())) |
| 95 | ); |
| 96 | assert!(r.events.len() > 120); |
| 97 | assert!( |
| 98 | l.events |
| 99 | .iter() |
| 100 | .any(|(_, event)| event == &Event::ChannelClose(cid)) |
| 101 | ); |
| 102 | |
| 103 | // Assert that ChannelOpen happens quickly after IceConnectionStateChange(Completed) |
| 104 | let ice_completed_time = l |
| 105 | .events |
| 106 | .iter() |
| 107 | .find_map(|(t, e)| match e { |
| 108 | Event::IceConnectionStateChange(str0m::IceConnectionState::Completed) => Some(*t), |
| 109 | _ => None, |
| 110 | }) |
| 111 | .expect("IceConnectionStateChange(Completed) event"); |
| 112 | let channel_open_time = l |
| 113 | .events |
| 114 | .iter() |
| 115 | .find_map(|(t, e)| match e { |
| 116 | Event::ChannelOpen(_, _) => Some(*t), |
| 117 | _ => None, |
| 118 | }) |
| 119 | .expect("ChannelOpen event"); |
| 120 | let channel_open_delay = channel_open_time.duration_since(ice_completed_time); |
| 121 | assert!( |
| 122 | channel_open_delay < Duration::from_millis(250), |
| 123 | "ChannelOpen should happen within 250ms of ICE completing, but took {:?}", |
| 124 | channel_open_delay |
| 125 | ); |
| 126 | |
| 127 | Ok(()) |
| 128 | } |