@@ -53,6 +53,13 @@ defmodule ExWebRTC.PeerConnection do
53
53
@ type ice_connection_state ( ) ::
54
54
:new | :checking | :connected | :completed | :failed | :disconnected | :closed
55
55
56
+ @ typedoc """
57
+ Possible DTLS transport states.
58
+
59
+ For the exact meaning, refer to the [RTCDtlsTransport: state property](https://developer.mozilla.org/en-US/docs/Web/API/RTCDtlsTransport/state)
60
+ """
61
+ @ type dtls_transport_state ( ) :: :new | :connecting | :connected | :failed
62
+
56
63
@ typedoc """
57
64
Possible signaling states.
58
65
@@ -65,6 +72,11 @@ defmodule ExWebRTC.PeerConnection do
65
72
66
73
Most of the messages match the [RTCPeerConnection events](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection#events),
67
74
except for:
75
+ * `:dtls_transport_state_change` - traditional WebRTC implementation does not emit such event.
76
+ Instead, developer can read DTLS transport state by iterating over RTP receivers/senders, and checking their
77
+ DTLS transports states. See https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpSender/transport.
78
+ However, because Elixir WebRTC creates a single DTLS transport for all receivers and senders, there is one generic
79
+ notification for convenience and parity with other events informing about ice/signaling/connection state changes.
68
80
* `:track_muted`, `:track_ended` - these match the [MediaStreamTrack events](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack#events).
69
81
* `:data` - data received from DataChannel identified by its `ref`.
70
82
* `:rtp` and `:rtcp` - these contain packets received by the PeerConnection. The third element of `:rtp` tuple is a simulcast RID and is set to `nil` if simulcast
@@ -79,6 +91,7 @@ defmodule ExWebRTC.PeerConnection do
79
91
| { :ice_candidate , ICECandidate . t ( ) }
80
92
| { :ice_connection_state_change , ice_connection_state ( ) }
81
93
| { :ice_gathering_state_change , ice_gathering_state ( ) }
94
+ | { :dtls_transport_state_change , dtls_transport_state ( ) }
82
95
| :negotiation_needed
83
96
| { :signaling_state_change , signaling_state ( ) }
84
97
| { :data_channel_state_change , DataChannel . ref ( ) , DataChannel . ready_state ( ) }
@@ -292,6 +305,16 @@ defmodule ExWebRTC.PeerConnection do
292
305
GenServer . call ( peer_connection , :get_ice_gathering_state )
293
306
end
294
307
308
+ @ doc """
309
+ Returns the DTLS transport state.
310
+
311
+ For more information, refer to the [RTCDtlsTransport: state property](https://developer.mozilla.org/en-US/docs/Web/API/RTCDtlsTransport/state).
312
+ """
313
+ @ spec get_dtls_transport_state ( peer_connection ( ) ) :: dtls_transport_state ( )
314
+ def get_dtls_transport_state ( peer_connection ) do
315
+ GenServer . call ( peer_connection , :get_dtls_transport_state )
316
+ end
317
+
295
318
@ doc """
296
319
Returns the signaling state.
297
320
@@ -577,7 +600,7 @@ defmodule ExWebRTC.PeerConnection do
577
600
on_data: nil
578
601
]
579
602
580
- { :ok , ice_pid } = DefaultICETransport . start_link ( :controlled , ice_config )
603
+ { :ok , ice_pid } = DefaultICETransport . start_link ( ice_config )
581
604
{ :ok , dtls_transport } = DTLSTransport . start_link ( DefaultICETransport , ice_pid )
582
605
# route data to the DTLSTransport
583
606
:ok = DefaultICETransport . on_data ( ice_pid , dtls_transport )
@@ -675,6 +698,11 @@ defmodule ExWebRTC.PeerConnection do
675
698
{ :reply , state . ice_gathering_state , state }
676
699
end
677
700
701
+ @ impl true
702
+ def handle_call ( :get_dtls_transport_state , _from , state ) do
703
+ { :reply , state . dtls_state , state }
704
+ end
705
+
678
706
@ impl true
679
707
def handle_call ( :get_signaling_state , _from , state ) do
680
708
{ :reply , state . signaling_state , state }
@@ -1188,7 +1216,7 @@ defmodule ExWebRTC.PeerConnection do
1188
1216
timestamp: timestamp ,
1189
1217
ice_state: ice_stats . state ,
1190
1218
ice_gathering_state: state . ice_gathering_state ,
1191
- ice_role: ice_stats . role ,
1219
+ ice_role: ice_stats . role || :unknown ,
1192
1220
ice_local_ufrag: ice_stats . local_ufrag ,
1193
1221
dtls_state: state . dtls_state ,
1194
1222
bytes_sent: ice_stats . bytes_sent ,
@@ -1359,6 +1387,8 @@ defmodule ExWebRTC.PeerConnection do
1359
1387
1360
1388
@ impl true
1361
1389
def handle_info ( { :dtls_transport , _pid , { :state_change , new_dtls_state } } , state ) do
1390
+ notify ( state . owner , { :dtls_transport_state_change , new_dtls_state } )
1391
+
1362
1392
next_conn_state = next_conn_state ( state . ice_state , new_dtls_state )
1363
1393
1364
1394
state =
@@ -1716,7 +1746,13 @@ defmodule ExWebRTC.PeerConnection do
1716
1746
defp apply_local_description ( % SessionDescription { type: type , sdp: raw_sdp } , state ) do
1717
1747
with { :ok , next_sig_state } <- next_signaling_state ( state . signaling_state , :local , type ) ,
1718
1748
:ok <- check_altered ( type , raw_sdp , state ) ,
1719
- { :ok , sdp } <- parse_sdp ( raw_sdp ) do
1749
+ { :ok , sdp } <- parse_sdp ( raw_sdp ) ,
1750
+ ice_lite <- SDPUtils . get_ice_lite ( sdp ) do
1751
+ # This has to be called before gathering candidates.
1752
+ if state . ice_transport . get_role ( state . ice_pid ) == nil do
1753
+ set_ice_role ( state , :local , type , ice_lite )
1754
+ end
1755
+
1720
1756
if state . ice_gathering_state == :new do
1721
1757
state . ice_transport . gather_candidates ( state . ice_pid )
1722
1758
end
@@ -1755,10 +1791,15 @@ defmodule ExWebRTC.PeerConnection do
1755
1791
{ :ok , sdp } <- parse_sdp ( raw_sdp ) ,
1756
1792
:ok <- SDPUtils . ensure_valid ( sdp ) ,
1757
1793
{ :ok , ice_creds } <- SDPUtils . get_ice_credentials ( sdp ) ,
1794
+ ice_lite <- SDPUtils . get_ice_lite ( sdp ) ,
1758
1795
{ :ok , { :fingerprint , { :sha256 , peer_fingerprint } } } <- SDPUtils . get_cert_fingerprint ( sdp ) ,
1759
1796
{ :ok , dtls_role } <- SDPUtils . get_dtls_role ( sdp ) do
1760
1797
config = Configuration . update ( state . config , sdp )
1761
1798
1799
+ if state . ice_transport . get_role ( state . ice_pid ) == nil do
1800
+ set_ice_role ( state , :remote , type , ice_lite )
1801
+ end
1802
+
1762
1803
twcc_id =
1763
1804
( config . video_extensions ++ config . audio_extensions )
1764
1805
|> Enum . find ( & ( & 1 . uri == @ twcc_uri ) )
@@ -1922,6 +1963,23 @@ defmodule ExWebRTC.PeerConnection do
1922
1963
% { state | pending_remote_desc: { type , sdp } }
1923
1964
end
1924
1965
1966
+ # See: https://www.w3.org/TR/webrtc/#ref-for-dfn-icerole-1
1967
+ defp set_ice_role ( state , :local , :offer , false ) do
1968
+ :ok = state . ice_transport . set_role ( state . ice_pid , :controlling )
1969
+ end
1970
+
1971
+ defp set_ice_role ( state , :local , :offer , true ) do
1972
+ :ok = state . ice_transport . set_role ( state . ice_pid , :controlled )
1973
+ end
1974
+
1975
+ defp set_ice_role ( state , :remote , :offer , true ) do
1976
+ :ok = state . ice_transport . set_role ( state . ice_pid , :controlling )
1977
+ end
1978
+
1979
+ defp set_ice_role ( state , :remote , :offer , false ) do
1980
+ :ok = state . ice_transport . set_role ( state . ice_pid , :controlled )
1981
+ end
1982
+
1925
1983
defp parse_sdp ( raw_sdp ) do
1926
1984
case ExSDP . parse ( raw_sdp ) do
1927
1985
{ :ok , _sdp } = res -> res
0 commit comments