rtc 0.9.0

Sans-I/O WebRTC implementation in Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
# RTC Integration Tests

## Overview

This directory contains integration tests for the `rtc` library:

- **Interoperability tests** with the `webrtc` library (Tests 1-5)
- **Pure rtc-to-rtc tests** using only the sansio API (Test 6)
- **Interceptor integration tests** for RTCP report generation (Test 15)

---

## Dependencies

The tests require:

- `webrtc = "0.14.0"` - WebRTC async implementation
- `interceptor = "0.15.0"` - For webrtc interceptor registry
- `tokio` - Async runtime
- `anyhow` - Error handling

---

## Architecture

The integration tests demonstrate how to use both APIs together:

- **RTC API** (sansio): Poll-based, no async/await, uses `poll_write()`, `poll_event()`, and `handle_read()`
- **WebRTC API** (async): Fully async with tokio, uses `async/await` and event handlers

The tests successfully bridge these two different programming models in a single test function.

---

## Future Tests

Consider adding tests for:

- Multiple data channels
- RTP transceiver interop (audio/video)
- Reconnection scenarios
- Error handling and edge cases
- Different ICE transport policies
- DTLS role negotiation variations

---

## Test Summary

| Test | File                                                        | Description                             |
|------|-------------------------------------------------------------|-----------------------------------------|
| 1    | `data_channels_interop.rs`                                  | rtc ↔ webrtc (webrtc offers)            |
| 2    | `data_channels_create_interop.rs`                           | rtc ↔ webrtc (rtc offers)               |
| 3    | `data_channels_close_by_rtc_interop.rs`                     | Close initiated by rtc                  |
| 4    | `data_channels_close_by_webrtc_interop.rs`                  | Close initiated by webrtc               |
| 5    | `ice_restart_by_webrtc_interop.rs`                          | ICE restart initiated by webrtc         |
| 6    | `ice_restart_by_rtc_interop.rs`                             | ICE restart initiated by rtc            |
| 7    | `play_from_disk_vpx_interop.rs`                             | Media streaming: rtc→webrtc             |
| 8    | `play_from_disk_rtc_set_remote_before_add_track_interop.rs` | Media with track order variation        |
| 9    | `reflect_webrtc_to_rtc_interop.rs`                          | Media reflection: webrtc→rtc→webrtc     |
| 10   | `reflect_rtc_to_webrtc_interop.rs`                          | Media reflection: rtc→webrtc→rtc        |
| 11   | `save_to_disk_vpx_interop.rs`                               | Media capture: webrtc→rtc→disk          |
| 12   | `simulcast_webrtc_to_rtc_interop.rs`                        | simulcast: webrtc→rtc (IGNORED)         |
| 13   | `simulcast_rtc_to_webrtc_interop.rs`                        | Simulcast: rtc→webrtc (IGNORED)         |
| 14   | `offer_answer_rtc2rtc.rs`                                   | **Pure rtc ↔ rtc (no webrtc)**          |
| 15   | `interceptor_rtcp_reports_interop.rs`                       | **RTCP report interceptor integration** |

---

## Test 1: Data Channels Interop (Answer Mode)

**File:** `data_channels_interop.rs`

**Purpose:** Verifies that the `rtc` library (using the sansio/polling-based API) can successfully establish a peer
connection and exchange data with the `webrtc` library (using the async API).

### Test Flow

1. **WebRTC Peer (Offerer)**:
    - Creates a WebRTC peer connection using the async API
    - Creates a data channel
    - Generates an offer with ICE candidates
    - Sets up message handlers to receive echoed messages

2. **RTC Peer (Answerer)**:
    - Creates an RTC peer connection using the sansio/polling API
    - Receives the offer from WebRTC peer
    - Binds a UDP socket and adds local ICE candidate
    - Generates an answer

3. **Connection Establishment**:
    - Both peers exchange SDP descriptions
    - The test runs both event loops in a single async context:
        - RTC peer uses polling-based API (`poll_write()`, `poll_event()`, `handle_read()`)
        - WebRTC peer uses async handlers

4. **Data Exchange**:
    - Once connected, WebRTC sends a message: "Hello from WebRTC!"
    - RTC peer receives the message and echoes it back
    - WebRTC peer receives the echo
    - Test succeeds if the echo is received within timeout

### Running the Test

```bash
RUST_LOG=info cargo test --test data_channels_interop -- --nocapture
```

### Key Features Tested

- ✅ SDP offer/answer exchange between rtc and webrtc (RTC as answerer)
- ✅ ICE candidate handling
- ✅ Data channel creation and opening
- ✅ Bidirectional message exchange
- ✅ Event-driven communication (rtc polling vs webrtc async)

---

## Test 2: Data Channels Create Interop (Offer Mode)

**File:** `data_channels_create_interop.rs`

**Purpose:** Verifies that the `rtc` library can create a data channel as the offerer, establish a connection with
`webrtc` as the answerer, and send messages proactively.

### Test Flow

1. **RTC Peer (Offerer)**:
    - Creates an RTC peer connection using the sansio/polling API
    - **Creates a data channel** with label "test-channel"
    - Binds a UDP socket and adds local ICE candidate
    - Generates an offer

2. **WebRTC Peer (Answerer)**:
    - Creates a WebRTC peer connection using the async API
    - Sets up `on_data_channel` handler to receive the data channel
    - Receives the offer from RTC peer
    - Generates an answer with ICE candidates

3. **Connection Establishment**:
    - Both peers exchange SDP descriptions
    - The test runs both event loops in a single async context

4. **Data Exchange**:
    - Once connected and data channel is open, RTC sends: "Hello from RTC!"
    - WebRTC receives the message and echoes it back
    - RTC receives the echoed message
    - Test succeeds if both sides receive the correct messages within timeout

### Running the Test

```bash
RUST_LOG=info cargo test --test data_channels_create_interop -- --nocapture
```

### Key Features Tested

- ✅ SDP offer/answer exchange (RTC as offerer)
- ✅ Data channel creation from RTC side
- ✅ Data channel negotiation and opening
- ✅ Message sending from RTC to WebRTC
- ✅ Event-driven communication with RTC as initiator

### Difference from Test 1

| Aspect                   | Test 1 (data_channels_interop) | Test 2 (data_channels_create_interop) |
|--------------------------|--------------------------------|---------------------------------------|
| **Offerer**              | WebRTC                         | RTC                                   |
| **Answerer**             | RTC                            | WebRTC                                |
| **Data Channel Creator** | WebRTC                         | RTC                                   |
| **Message Sender**       | WebRTC → RTC → WebRTC (echo)   | RTC → WebRTC → RTC (echo)             |
| **Message Flow**         | Bidirectional (with echo)      | Bidirectional (with echo)             |

---

## Test 3: Data Channels Close by RTC

**File:** `data_channels_close_by_rtc_interop.rs`

**Purpose:** Verifies that data channels can be properly closed and that close events are detected correctly when RTC
sends messages and closes the connection.

### Test Flow

1. **RTC Peer (Offerer)**:
    - Creates an RTC peer connection using the sansio/polling API
    - **Creates a data channel**
    - Generates an offer
    - Sets up close event handler (OnClose event)

2. **WebRTC Peer (Answerer)**:
    - Creates a WebRTC peer connection using the async API
    - Sets up `on_data_channel` handler to receive the channel
    - Receives the offer from RTC peer
    - Generates an answer with ICE candidates
    - Sets up close event handler

3. **Connection Establishment**:
    - Both peers exchange SDP descriptions
    - The test runs both event loops in a single async context

4. **Data Exchange and Close**:
    - Once connected, **RTC sends 3 periodic messages** (every 500ms) to WebRTC
    - WebRTC receives the messages
    - After sending all messages, **RTC exits the event loop** (which closes the peer connection and data channel)
    - WebRTC detects the close event via `on_close` handler
    - Test succeeds when WebRTC detects the close

### Running the Test

```bash
RUST_LOG=info cargo test --test data_channels_close_by_rtc_interop -- --nocapture
```

### Key Features Tested

- ✅ Data channel creation by RTC (offerer)
-**Periodic message sending from RTC** (every 500ms)
- ✅ Message counting before close (sends exactly 3 messages)
-**Data channel close initiated by RTC** (via peer connection close)
- ✅ Close event detection on WebRTC side
- ✅ Proper cleanup on both sides

### Important Note: Sansio Close Behavior

The RTC sansio API doesn't expose an explicit `close()` method on `RTCDataChannel`. Instead:

- When RTC finishes sending messages, it **exits the event loop**
- This triggers `rtc_pc.close()` which closes the peer connection
- The data channel is implicitly closed as part of the peer connection closure
- WebRTC detects this via its `on_close` handler

---

## Test 4: Data Channels Close by WebRTC

**File:** `data_channels_close_by_webrtc_interop.rs`

**Purpose:** Verifies that data channels can be properly closed and that close events are detected correctly when WebRTC
initiates the close.

### Test Flow

1. **WebRTC Peer (Offerer)**:
    - Creates a WebRTC peer connection using the async API
    - Creates a data channel
    - Generates an offer with ICE candidates
    - Sets up message handlers

2. **RTC Peer (Answerer)**:
    - Creates an RTC peer connection using the sansio/polling API
    - Receives the offer from WebRTC peer
    - Generates an answer
    - Handles data channel events

3. **Connection Establishment**:
    - Both peers exchange SDP descriptions
    - The test runs both event loops in a single async context

4. **Data Exchange and Close**:
    - Once connected, messages are exchanged
    - **WebRTC initiates the close** of the data channel
    - RTC detects the close event via `OnClose` event
    - Test succeeds when RTC detects the close

### Running the Test

```bash
RUST_LOG=info cargo test --test data_channels_close_by_webrtc_interop -- --nocapture
```

### Key Features Tested

- ✅ Data channel creation by WebRTC (offerer)
- ✅ Message exchange
-**Data channel close initiated by WebRTC**
- ✅ Close event detection on RTC side
- ✅ Proper cleanup on both sides

### Difference from Other Tests

| Aspect              | Test 1             | Test 2             | Test 3 (close_by_rtc) | Test 4 (close_by_webrtc) |
|---------------------|--------------------|--------------------|-----------------------|--------------------------|
| **Offerer**         | WebRTC             | RTC                | RTC                   | **WebRTC**               |
| **Focus**           | Bidirectional echo | Bidirectional echo | **Close by RTC**      | **Close by WebRTC**      |
| **Close Initiator** | N/A                | N/A                | **RTC**               | **WebRTC**               |
| **Close Detection** | N/A                | N/A                | **WebRTC detects**    | **RTC detects**          |

---

## Test 5: ICE Restart by WebRTC

**File:** `ice_restart_by_webrtc_interop.rs`

**Description:**
Tests ICE restart functionality when initiated by the WebRTC peer (offerer), with RTC as answerer using the sansio API.

### Test Flow

1. WebRTC peer creates offer and data channel
2. RTC peer receives offer and creates answer
3. Connection establishes and peers exchange messages before restart
4. WebRTC initiates ICE restart with new offer (ice_restart: true)
5. RTC processes restart offer and creates restart answer
6. Connection re-establishes
7. Peers can communicate again (RTC → WebRTC verified)

### Key Features Tested

- ✅ ICE restart initiated by WebRTC using `RTCOfferOptions { ice_restart: true }`
- ✅ RTC handles restart as answerer
- ✅ Connection successfully re-establishes
- ✅ Pre-restart bidirectional communication works
- ✅ RTC → WebRTC data channel works after restart
- ⚠️ WebRTC → RTC data channel after restart may have issues (known limitation)

### Running the Test

```bash
cargo test --test ice_restart_by_webrtc_interop -- --nocapture
```

---

## Test 6: ICE Restart by RTC

**File:** `ice_restart_by_rtc_interop.rs`

**Description:**
Tests ICE restart functionality when initiated by the RTC peer (offerer) using the sansio `restart_ice()` API, with
WebRTC as answerer.

### Test Flow

1. WebRTC peer creates offer and data channel
2. RTC peer receives offer and creates answer
3. Connection establishes and peers exchange messages before restart
4. RTC initiates ICE restart using `restart_ice()` method
5. RTC creates new offer with ICE restart
6. WebRTC processes restart offer and creates restart answer
7. RTC sets restart answer as remote description
8. Connection re-establishes via ICE
9. Data channel continues working after restart

### Key Features Tested

- ✅ ICE restart initiated by RTC using sansio `restart_ice()` API
- ✅ WebRTC handles restart as answerer
- ✅ Connection successfully re-establishes
- ✅ Pre-restart bidirectional communication works
- ✅ Data channel continues working after restart
- ✅ ICE connection state transitions properly (checking → connected/completed)

### Running the Test

```bash
cargo test --test ice_restart_by_rtc_interop -- --nocapture
```

---

## Test 7: Play from Disk VPX

**File:** `play_from_disk_vpx_interop.rs`

**Description:**
Tests media streaming from RTC to WebRTC by playing VP8/VP9 encoded video from disk.

### Key Features Tested

- ✅ RTC creates offer with video track
- ✅ WebRTC answers and receives video
- ✅ VP8/VP9 media streaming from rtc to webrtc

### Running the Test

```bash
cargo test --test play_from_disk_vpx_interop -- --nocapture
```

---

## Test 8: Play from Disk with Track Order Variation

**File:** `play_from_disk_rtc_set_remote_before_add_track_interop.rs`

**Description:**
Tests media streaming with a specific track order variation where RTC sets remote description before adding tracks.

### Key Features Tested

- ✅ Set remote description before add_track
- ✅ Track negotiation with non-standard order
- ✅ Media streaming works with alternate setup order

### Running the Test

```bash
cargo test --test play_from_disk_rtc_set_remote_before_add_track_interop -- --nocapture
```

---

## Test 9: Media Reflection (WebRTC to RTC)

**File:** `reflect_webrtc_to_rtc_interop.rs`

**Purpose:** Verifies that RTP packets can be sent from webrtc, received and reflected by rtc, and received back at
webrtc.

### Test Flow

1. **WebRTC Peer (Offerer)**:
    - Creates a video track using `TrackLocalStaticRTP`
    - Creates offer with video track
    - Sets up `on_track` handler to receive reflected packets

2. **RTC Peer (Answerer)**:
    - Receives offer from webrtc
    - Adds video track for reflecting packets
    - Creates answer

3. **Connection Establishment**:
    - Both peers exchange SDP and establish connection
    - Event loops run concurrently

4. **Packet Flow**:
    - WebRTC sends 10 RTP packets with VP8 codec
    - RTC receives packets via `poll_read()``RTCMessage::RtpPacket`
    - RTC reflects packets back via `write_rtp()`
    - WebRTC receives reflected packets
    - Test succeeds when ≥5 reflected packets received

### Running the Test

```bash
cargo test --test reflect_webrtc_to_rtc_interop -- --nocapture
```

### Key Features Tested

- ✅ WebRTC creates offer with video track
- ✅ RTC answers and adds video track
- ✅ RTP packet sending from webrtc
- ✅ RTP packet reception on rtc
- ✅ RTP packet reflection via `write_rtp()`
- ✅ Bidirectional media flow

---

## Test 10: Media Reflection (RTC to WebRTC)

**File:** `reflect_rtc_to_webrtc_interop.rs`

**Purpose:** Verifies that RTP packets can be sent from rtc, received and reflected by webrtc, and received back at rtc.

### Test Flow

1. **RTC Peer (Offerer)**:
    - Creates video track
    - Creates offer
    - Sends RTP packets to webrtc

2. **WebRTC Peer (Answerer)**:
    - Creates video track for reflecting
    - Receives offer and creates answer
    - Reflects packets back to rtc

3. **Expected Result**:
    - RTC sends → webrtc reflects → RTC receives

### Running the Test

```bash
cargo test --test reflect_rtc_to_webrtc_interop -- --nocapture
```

### Key Features Tested

- ✅ RTC creates offer with video track
- ✅ WebRTC answers and adds video track
- ✅ RTP packet sending from rtc
- ✅ RTP packet reflection by webrtc
- ✅ RTP packet reception on rtc

---

## Test 11: Save to Disk VPX

**File:** `save_to_disk_vpx_interop.rs`

**Description:**
Tests media capture from WebRTC to RTC, saving VP8/VP9 encoded video to disk.

### Key Features Tested

- ✅ WebRTC creates offer with video track
- ✅ RTC answers and receives video
- ✅ RTP packet capture from webrtc
- ✅ Media saving to disk

### Running the Test

```bash
cargo test --test save_to_disk_vpx_interop -- --nocapture
```

---

## Test 12: Simulcast (WebRTC to RTC)

**File:** `simulcast_webrtc_to_rtc_interop.rs`

**Status:** ⚠️ **IGNORED**

**Description:**
Tests simulcast functionality where WebRTC sends multiple quality layers to RTC.

### Running the Test

```bash
# Currently ignored, run with:
cargo test --test simulcast_webrtc_to_rtc_interop -- --ignored --nocapture
```

---

## Test 13: Simulcast (RTC to WebRTC)

**File:** `simulcast_rtc_to_webrtc_interop.rs`

**Status:** ⚠️ **IGNORED** - RID header extensions not implemented

**Description:**
Tests TRUE simulcast with RID (Restriction Identifier) support where rtc sends 3 layers and webrtc receives them.

### Current Issue

The RTC library does not automatically add RID (rtp-stream-id) header extensions to outgoing RTP packets. The
`write_rtp()` method has a TODO comment:

```rust
pub fn write_rtp(&mut self, mut packet: rtp::Packet) -> Result<()> {
    //TODO: handle rtp header extension, etc.
```

Without RID extensions in the RTP headers, webrtc cannot properly demultiplex the simulcast layers.

### Running the Test

```bash
# Currently ignored, run with:
cargo test --test simulcast_rtc_to_webrtc_interop -- --ignored --nocapture
```

---

## Test 14: Offer-Answer RTC-to-RTC

**File:** `offer_answer_rtc2rtc.rs`

**Purpose:** Verifies that two `rtc` peers using the sansio API can establish a complete offer/answer connection and
exchange data without requiring the `webrtc` library.

### Test Flow

1. **Offer Peer (RTC)**:
    - Creates an RTC peer connection using the sansio/polling API
    - Creates a data channel with label "test-channel"
    - Binds a UDP socket to 127.0.0.1 and adds local ICE candidate
    - Generates an offer
    - Sets local description
    - Sets DTLS role to Server

2. **Answer Peer (RTC)**:
    - Creates an RTC peer connection using the sansio/polling API
    - Binds a UDP socket to 127.0.0.1 and adds local ICE candidate
    - Receives the offer and sets it as remote description
    - Generates an answer
    - Sets local description
    - Sets DTLS role to Client

3. **ICE Candidate Exchange**:
    - Offer peer adds Answer peer's candidate
    - Answer peer adds Offer peer's candidate
    - Both peers know each other's socket addresses

4. **Connection Establishment**:
    - Both event loops run concurrently using `tokio::select!`
    - Polls write, events, and handles timeouts for both peers
    - Processes incoming UDP packets with `handle_read()`

5. **Data Exchange**:
    - Once connected, Offer sends: "Hello from offer!"
    - Answer receives the message and echoes: "Echo from answer!"
    - Offer receives the echo
    - Test succeeds when both messages are received

### Running the Test

```bash
cargo test --test offer_answer_rtc2rtc -- --nocapture
```

### Key Features Tested

- ✅ Pure RTC-to-RTC communication (no webrtc dependency)
- ✅ Complete offer/answer SDP exchange
- ✅ ICE candidate exchange
- ✅ DTLS role negotiation (Server/Client)
- ✅ Data channel creation and opening
- ✅ Bidirectional message exchange
- ✅ Event loop coordination for both peers
- ✅ Proper connection state transitions

### Architecture Highlights

This test demonstrates the pure sansio architecture:

- **Both peers use polling-based API**
- **Single test manages two event loops**
- **Manual timeout and I/O handling**
- **No async/await in peer connection code**
- **Direct UDP socket management**

---

## Test 15: RTCP Report Interceptor Integration

**File:** `interceptor_rtcp_reports_interop.rs`

**Purpose:** Verifies that the `rtc-interceptor` crate's RTCP report interceptors work correctly when integrated at the
peer connection level with `Registry` and `RTCConfigurationBuilder.with_interceptor_registry()`.

### Overview

This test file contains 3 integration tests that verify:

1. Custom interceptor registry configuration with configurable report intervals
2. RTCP Sender Report generation when sending RTP packets
3. The `register_default_interceptors()` helper function

### Test 15a: Custom Interceptor Registry

**Function:** `test_custom_interceptor_registry_with_rtcp_reports`

Creates an rtc peer with a custom interceptor registry using `SenderReportBuilder` and `ReceiverReportBuilder` with
100ms intervals:

```rust
let registry = Registry::new()
.with(
ReceiverReportBuilder::new()
.with_interval(Duration::from_millis(100))
.build(),
)
.with(
SenderReportBuilder::new()
.with_interval(Duration::from_millis(100))
.build(),
);

let config = RTCConfigurationBuilder::new()
.with_interceptor_registry(registry)
.build();
```

**Test Flow:**

1. RTC peer creates offer with video track and custom interceptor registry
2. WebRTC peer creates answer with reflect track
3. Peers exchange SDP and establish connection
4. RTC sends RTP packets, webrtc reflects them back
5. Test verifies RTC receives reflected packets (proving interceptor chain works)

### Test 15b: Sender Report Generation

**Function:** `test_sender_report_generation_on_rtp_send`

Uses shorter report intervals (50ms) and monitors outgoing packets to detect RTCP Sender Report generation.

**Key Points:**

- Monitors `poll_write()` output for RTCP packets
- Detects Sender Reports by checking payload type (PT=200)
- Verifies that sending RTP triggers periodic Sender Report generation

### Test 15c: Default Interceptors Helper

**Function:** `test_register_default_interceptors_helper`

Tests the `register_default_interceptors()` helper function:

```rust
let registry = Registry::new();
let registry = rtc::peer_connection::configuration::interceptor_registry::register_default_interceptors(
registry,
& mut media_engine,
) ?;
```

This verifies the convenience function correctly configures RTCP report interceptors.

### Running the Tests

```bash
cargo test --test interceptor_rtcp_reports_interop -- --nocapture
```

### Key Features Tested

- ✅ Custom interceptor registry with `Registry::new().with(...)`
-`SenderReportBuilder` with configurable intervals
-`ReceiverReportBuilder` with configurable intervals
-`RTCConfigurationBuilder.with_interceptor_registry()`
-`register_default_interceptors()` helper function
- ✅ RTCP Sender Report generation on RTP send
- ✅ Full peer connection with interceptor chain

### Related: rtc-interceptor Unit Tests

The `rtc-interceptor` crate also has its own integration tests at `rtc-interceptor/tests/rtcp_report_integration.rs`
which test the interceptor chain in isolation (without a full peer connection):

| Test                                                       | Description              |
|------------------------------------------------------------|--------------------------|
| `test_sender_report_interceptor_generates_sr_on_timeout`   | SR generation on timeout |
| `test_sender_report_tracks_packet_statistics`              | Packet/octet counting    |
| `test_sender_report_multiple_streams`                      | Multiple SSRCs           |
| `test_receiver_report_interceptor_generates_rr_on_timeout` | RR generation on timeout |
| `test_receiver_report_tracks_sequence_numbers`             | Sequence number tracking |
| `test_receiver_report_detects_packet_loss`                 | Loss detection           |
| `test_combined_sender_and_receiver_interceptors`           | Chained SR+RR            |
| `test_interceptor_chain_unbind_streams`                    | Stream unbinding         |
| `test_receiver_processes_sender_report`                    | SR→RR LSR/DLSR           |
| `test_report_interval_is_respected`                        | Interval timing          |
| `test_poll_timeout_returns_earliest`                       | Timeout scheduling       |

Run these with:

```bash
cargo test --package rtc-interceptor --test rtcp_report_integration
```