Skip to content

Commit 8d95518

Browse files
authored
webrtc: Add support for unordered unreliable data channels (webrtc-rs#609)
1 parent 76f780a commit 8d95518

File tree

5 files changed

+147
-44
lines changed

5 files changed

+147
-44
lines changed

webrtc/src/data_channel/data_channel_parameters.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub struct DataChannelParameters {
66
pub label: String,
77
pub protocol: String,
88
pub ordered: bool,
9-
pub max_packet_life_time: u16,
10-
pub max_retransmits: u16,
9+
pub max_packet_life_time: Option<u16>,
10+
pub max_retransmits: Option<u16>,
1111
pub negotiated: Option<u16>,
1212
}

webrtc/src/data_channel/data_channel_test.rs

Lines changed: 107 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ async fn test_data_channel_parameters_max_packet_life_time_exchange() -> Result<
377377
);
378378
assert_eq!(
379379
dc.max_packet_lifetime(),
380-
max_packet_life_time,
380+
Some(max_packet_life_time),
381381
"should match"
382382
);
383383

@@ -394,7 +394,7 @@ async fn test_data_channel_parameters_max_packet_life_time_exchange() -> Result<
394394
);
395395
assert_eq!(
396396
d.max_packet_lifetime(),
397-
max_packet_life_time,
397+
Some(max_packet_life_time),
398398
"should match"
399399
);
400400
let done_tx2 = Arc::clone(&done_tx);
@@ -428,7 +428,7 @@ async fn test_data_channel_parameters_max_retransmits_exchange() -> Result<()> {
428428

429429
// Check if parameters are correctly set
430430
assert!(!dc.ordered(), "Ordered should be set to false");
431-
assert_eq!(dc.max_retransmits(), max_retransmits, "should match");
431+
assert_eq!(dc.max_retransmits(), Some(max_retransmits), "should match");
432432

433433
let done_tx = Arc::new(Mutex::new(Some(done_tx)));
434434
answer_pc.on_data_channel(Box::new(move |d: Arc<RTCDataChannel>| {
@@ -440,7 +440,58 @@ async fn test_data_channel_parameters_max_retransmits_exchange() -> Result<()> {
440440

441441
// Check if parameters are correctly set
442442
assert!(!d.ordered(), "Ordered should be set to false");
443-
assert_eq!(max_retransmits, d.max_retransmits(), "should match");
443+
assert_eq!(Some(max_retransmits), d.max_retransmits(), "should match");
444+
let done_tx2 = Arc::clone(&done_tx);
445+
Box::pin(async move {
446+
let mut done = done_tx2.lock().await;
447+
done.take();
448+
})
449+
}));
450+
451+
close_reliability_param_test(&mut offer_pc, &mut answer_pc, done_rx).await?;
452+
453+
Ok(())
454+
}
455+
456+
#[tokio::test]
457+
async fn test_data_channel_parameters_unreliable_unordered_exchange() -> Result<()> {
458+
let mut m = MediaEngine::default();
459+
m.register_default_codecs()?;
460+
let api = APIBuilder::new().with_media_engine(m).build();
461+
462+
let ordered = false;
463+
let max_retransmits = Some(0);
464+
let max_packet_life_time = None;
465+
let options = RTCDataChannelInit {
466+
ordered: Some(ordered),
467+
max_retransmits,
468+
max_packet_life_time,
469+
..Default::default()
470+
};
471+
472+
let (mut offer_pc, mut answer_pc, dc, done_tx, done_rx) =
473+
set_up_data_channel_parameters_test(&api, Some(options)).await?;
474+
475+
// Check if parameters are correctly set
476+
assert_eq!(
477+
dc.ordered(),
478+
ordered,
479+
"Ordered should be same value as set in DataChannelInit"
480+
);
481+
assert_eq!(dc.max_retransmits, max_retransmits, "should match");
482+
483+
let done_tx = Arc::new(Mutex::new(Some(done_tx)));
484+
answer_pc.on_data_channel(Box::new(move |d: Arc<RTCDataChannel>| {
485+
if d.label() != EXPECTED_LABEL {
486+
return Box::pin(async {});
487+
}
488+
// Check if parameters are correctly set
489+
assert_eq!(
490+
d.ordered(),
491+
ordered,
492+
"Ordered should be same value as set in DataChannelInit"
493+
);
494+
assert_eq!(d.max_retransmits(), max_retransmits, "should match");
444495
let done_tx2 = Arc::clone(&done_tx);
445496
Box::pin(async move {
446497
let mut done = done_tx2.lock().await;
@@ -453,6 +504,56 @@ async fn test_data_channel_parameters_max_retransmits_exchange() -> Result<()> {
453504
Ok(())
454505
}
455506

507+
#[tokio::test]
508+
async fn test_data_channel_parameters_reliable_unordered_exchange() -> Result<()> {
509+
let mut m = MediaEngine::default();
510+
m.register_default_codecs()?;
511+
let api = APIBuilder::new().with_media_engine(m).build();
512+
513+
let ordered = false;
514+
let max_retransmits = None;
515+
let max_packet_life_time = None;
516+
let options = RTCDataChannelInit {
517+
ordered: Some(ordered),
518+
max_retransmits,
519+
max_packet_life_time,
520+
..Default::default()
521+
};
522+
523+
let (mut offer_pc, mut answer_pc, dc, done_tx, done_rx) =
524+
set_up_data_channel_parameters_test(&api, Some(options)).await?;
525+
526+
// Check if parameters are correctly set
527+
assert_eq!(
528+
dc.ordered(),
529+
ordered,
530+
"Ordered should be same value as set in DataChannelInit"
531+
);
532+
assert_eq!(dc.max_retransmits, max_retransmits, "should match");
533+
534+
let done_tx = Arc::new(Mutex::new(Some(done_tx)));
535+
answer_pc.on_data_channel(Box::new(move |d: Arc<RTCDataChannel>| {
536+
if d.label() != EXPECTED_LABEL {
537+
return Box::pin(async {});
538+
}
539+
// Check if parameters are correctly set
540+
assert_eq!(
541+
d.ordered(),
542+
ordered,
543+
"Ordered should be same value as set in DataChannelInit"
544+
);
545+
assert_eq!(d.max_retransmits(), max_retransmits, "should match");
546+
let done_tx2 = Arc::clone(&done_tx);
547+
Box::pin(async move {
548+
let mut done = done_tx2.lock().await;
549+
done.take();
550+
})
551+
}));
552+
553+
close_reliability_param_test(&mut offer_pc, &mut answer_pc, done_rx).await?;
554+
555+
Ok(())
556+
}
456557
#[tokio::test]
457558
async fn test_data_channel_parameters_protocol_exchange() -> Result<()> {
458559
let mut m = MediaEngine::default();
@@ -743,7 +844,7 @@ async fn test_data_channel_parameters_go() -> Result<()> {
743844
// Check if parameters are correctly set
744845
assert!(dc.ordered(), "Ordered should be set to true");
745846
assert_eq!(
746-
max_packet_life_time,
847+
Some(max_packet_life_time),
747848
dc.max_packet_lifetime(),
748849
"should match"
749850
);
@@ -759,7 +860,7 @@ async fn test_data_channel_parameters_go() -> Result<()> {
759860
// Check if parameters are correctly set
760861
assert!(d.ordered, "Ordered should be set to true");
761862
assert_eq!(
762-
max_packet_life_time,
863+
Some(max_packet_life_time),
763864
d.max_packet_lifetime(),
764865
"should match"
765866
);

webrtc/src/data_channel/mod.rs

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ pub struct RTCDataChannel {
6060
pub(crate) stats_id: String,
6161
pub(crate) label: String,
6262
pub(crate) ordered: bool,
63-
pub(crate) max_packet_lifetime: u16,
64-
pub(crate) max_retransmits: u16,
63+
pub(crate) max_packet_lifetime: Option<u16>,
64+
pub(crate) max_retransmits: Option<u16>,
6565
pub(crate) protocol: String,
6666
pub(crate) negotiated: bool,
6767
pub(crate) id: AtomicU16,
@@ -137,26 +137,32 @@ impl RTCDataChannel {
137137
let channel_type;
138138
let reliability_parameter;
139139

140-
if self.max_packet_lifetime == 0 && self.max_retransmits == 0 {
141-
reliability_parameter = 0u32;
142-
if self.ordered {
143-
channel_type = ChannelType::Reliable;
144-
} else {
145-
channel_type = ChannelType::ReliableUnordered;
140+
match (self.max_retransmits, self.max_packet_lifetime) {
141+
(None, None) => {
142+
reliability_parameter = 0u32;
143+
if self.ordered {
144+
channel_type = ChannelType::Reliable;
145+
} else {
146+
channel_type = ChannelType::ReliableUnordered;
147+
}
146148
}
147-
} else if self.max_retransmits != 0 {
148-
reliability_parameter = self.max_retransmits as u32;
149-
if self.ordered {
150-
channel_type = ChannelType::PartialReliableRexmit;
151-
} else {
152-
channel_type = ChannelType::PartialReliableRexmitUnordered;
149+
150+
(Some(max_retransmits), _) => {
151+
reliability_parameter = max_retransmits as u32;
152+
if self.ordered {
153+
channel_type = ChannelType::PartialReliableRexmit;
154+
} else {
155+
channel_type = ChannelType::PartialReliableRexmitUnordered;
156+
}
153157
}
154-
} else {
155-
reliability_parameter = self.max_packet_lifetime as u32;
156-
if self.ordered {
157-
channel_type = ChannelType::PartialReliableTimed;
158-
} else {
159-
channel_type = ChannelType::PartialReliableTimedUnordered;
158+
159+
(None, Some(max_packet_lifetime)) => {
160+
reliability_parameter = max_packet_lifetime as u32;
161+
if self.ordered {
162+
channel_type = ChannelType::PartialReliableTimed;
163+
} else {
164+
channel_type = ChannelType::PartialReliableTimedUnordered;
165+
}
160166
}
161167
}
162168

@@ -454,13 +460,13 @@ impl RTCDataChannel {
454460

455461
/// max_packet_lifetime represents the length of the time window (msec) during
456462
/// which transmissions and retransmissions may occur in unreliable mode.
457-
pub fn max_packet_lifetime(&self) -> u16 {
463+
pub fn max_packet_lifetime(&self) -> Option<u16> {
458464
self.max_packet_lifetime
459465
}
460466

461467
/// max_retransmits represents the maximum number of retransmissions that are
462468
/// attempted in unreliable mode.
463-
pub fn max_retransmits(&self) -> u16 {
469+
pub fn max_retransmits(&self) -> Option<u16> {
464470
self.max_retransmits
465471
}
466472

webrtc/src/peer_connection/mod.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,14 +1849,10 @@ impl RTCPeerConnection {
18491849
}
18501850

18511851
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #7)
1852-
if let Some(max_packet_life_time) = options.max_packet_life_time {
1853-
params.max_packet_life_time = max_packet_life_time;
1854-
}
1852+
params.max_packet_life_time = options.max_packet_life_time;
18551853

18561854
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #8)
1857-
if let Some(max_retransmits) = options.max_retransmits {
1858-
params.max_retransmits = max_retransmits;
1859-
}
1855+
params.max_retransmits = options.max_retransmits;
18601856

18611857
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #10)
18621858
if let Some(protocol) = options.protocol {
@@ -1878,7 +1874,7 @@ impl RTCPeerConnection {
18781874
));
18791875

18801876
// https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #16)
1881-
if d.max_packet_lifetime != 0 && d.max_retransmits != 0 {
1877+
if d.max_packet_lifetime.is_some() && d.max_retransmits.is_some() {
18821878
return Err(Error::ErrRetransmitsOrPacketLifeTime);
18831879
}
18841880

webrtc/src/sctp_transport/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ impl RTCSctpTransport {
244244
}
245245
};
246246

247-
let mut max_retransmits = 0;
248-
let mut max_packet_lifetime = 0;
247+
let mut max_retransmits = None;
248+
let mut max_packet_life_time = None;
249249
let val = dc.config.reliability_parameter as u16;
250250
let ordered;
251251

@@ -258,19 +258,19 @@ impl RTCSctpTransport {
258258
}
259259
ChannelType::PartialReliableRexmit => {
260260
ordered = true;
261-
max_retransmits = val;
261+
max_retransmits = Some(val);
262262
}
263263
ChannelType::PartialReliableRexmitUnordered => {
264264
ordered = false;
265-
max_retransmits = val;
265+
max_retransmits = Some(val);
266266
}
267267
ChannelType::PartialReliableTimed => {
268268
ordered = true;
269-
max_packet_lifetime = val;
269+
max_packet_life_time = Some(val);
270270
}
271271
ChannelType::PartialReliableTimedUnordered => {
272272
ordered = false;
273-
max_packet_lifetime = val;
273+
max_packet_life_time = Some(val);
274274
}
275275
};
276276

@@ -285,7 +285,7 @@ impl RTCSctpTransport {
285285
protocol: dc.config.protocol.clone(),
286286
negotiated,
287287
ordered,
288-
max_packet_life_time: max_packet_lifetime,
288+
max_packet_life_time,
289289
max_retransmits,
290290
},
291291
Arc::clone(&param.setting_engine),

0 commit comments

Comments
 (0)