@@ -26,6 +26,11 @@ defmodule ExWebRTC.PeerConnection do
2626 Utils
2727 }
2828
29+ if not Code . ensure_loaded? ( ExSCTP ) do
30+ @ sctp_error_text "DataChannel support is turned off"
31+ @ sctp_tip "Install Rust and add `ex_sctp` dependency to your project in order to enable DataChannels."
32+ end
33+
2934 @ twcc_interval 100
3035 @ twcc_uri "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
3136
@@ -1060,46 +1065,63 @@ defmodule ExWebRTC.PeerConnection do
10601065 end
10611066 end
10621067
1063- @ impl true
1064- def handle_call ( { :create_data_channel , label , opts } , _from , state ) do
1065- ordered = Keyword . get ( opts , :ordered , true )
1066- lifetime = Keyword . get ( opts , :max_packet_life_time )
1067- max_rtx = Keyword . get ( opts , :max_retransmits )
1068- protocol = Keyword . get ( opts , :protocol , "" )
1069-
1070- with true <- byte_size ( label ) < 65_535 ,
1071- true <- lifetime == nil or max_rtx == nil do
1072- { events , channel , sctp_transport } =
1073- SCTPTransport . add_channel (
1074- state . sctp_transport ,
1075- label ,
1076- ordered ,
1077- protocol ,
1078- lifetime ,
1079- max_rtx
1080- )
1081-
1082- state = update_negotiation_needed ( % { state | sctp_transport: sctp_transport } )
1068+ if Code . ensure_loaded? ( ExSCTP ) do
1069+ @ impl true
1070+ def handle_call ( { :create_data_channel , label , opts } , _from , state ) do
1071+ ordered = Keyword . get ( opts , :ordered , true )
1072+ lifetime = Keyword . get ( opts , :max_packet_life_time )
1073+ max_rtx = Keyword . get ( opts , :max_retransmits )
1074+ protocol = Keyword . get ( opts , :protocol , "" )
1075+
1076+ with true <- byte_size ( label ) < 65_535 ,
1077+ true <- lifetime == nil or max_rtx == nil do
1078+ { events , channel , sctp_transport } =
1079+ SCTPTransport . add_channel (
1080+ state . sctp_transport ,
1081+ label ,
1082+ ordered ,
1083+ protocol ,
1084+ lifetime ,
1085+ max_rtx
1086+ )
1087+
1088+ state = update_negotiation_needed ( % { state | sctp_transport: sctp_transport } )
1089+
1090+ handle_sctp_events ( events , state )
1091+ { :reply , { :ok , channel } , state }
1092+ else
1093+ _other -> { :reply , { :error , :invalid_option } , state }
1094+ end
1095+ end
10831096
1097+ @ impl true
1098+ def handle_call ( { :close_data_channel , channel_ref } , _from , state ) do
1099+ { events , sctp_transport } = SCTPTransport . close_channel ( state . sctp_transport , channel_ref )
10841100 handle_sctp_events ( events , state )
1085- { :reply , { :ok , channel } , state }
1086- else
1087- _other -> { :reply , { :error , :invalid_option } , state }
1101+
1102+ { :reply , :ok , % { state | sctp_transport: sctp_transport } }
10881103 end
1089- end
10901104
1091- @ impl true
1092- def handle_call ( { :close_data_channel , channel_ref } , _from , state ) do
1093- { events , sctp_transport } = SCTPTransport . close_channel ( state . sctp_transport , channel_ref )
1094- handle_sctp_events ( events , state )
1105+ @ impl true
1106+ def handle_call ( { :get_data_channel , channel_ref } , _from , state ) do
1107+ channel = SCTPTransport . get_channel ( state . sctp_transport , channel_ref )
1108+ { :reply , channel , state }
1109+ end
1110+ else
1111+ @ impl true
1112+ def handle_call ( { :create_data_channel , _label , _opts } , _from , _state ) do
1113+ raise ( "#{ @ sctp_error_text } #{ @ sctp_tip } " )
1114+ end
10951115
1096- { :reply , :ok , % { state | sctp_transport: sctp_transport } }
1097- end
1116+ @ impl true
1117+ def handle_call ( { :close_data_channel , _channel_ref } , _from , _state ) do
1118+ raise ( "#{ @ sctp_error_text } #{ @ sctp_tip } " )
1119+ end
10981120
1099- @ impl true
1100- def handle_call ( { :get_data_channel , channel_ref } , _from , state ) do
1101- channel = SCTPTransport . get_channel ( state . sctp_transport , channel_ref )
1102- { :reply , channel , state }
1121+ @ impl true
1122+ def handle_call ( { :get_data_channel , _channel_ref } , _from , _state ) do
1123+ raise ( " #{ @ sctp_error_text } #{ @ sctp_tip } " )
1124+ end
11031125 end
11041126
11051127 @ impl true
@@ -1340,20 +1362,27 @@ defmodule ExWebRTC.PeerConnection do
13401362 { :noreply , state }
13411363 end
13421364
1343- @ impl true
1344- def handle_cast ( { :send_data , channel_ref , data_type , data } , % { conn_state: conn_state } = state )
1345- when conn_state != :failed do
1346- { events , sctp_transport } =
1347- SCTPTransport . send ( state . sctp_transport , channel_ref , data_type , data )
1365+ if Code . ensure_loaded? ( ExSCTP ) do
1366+ @ impl true
1367+ def handle_cast ( { :send_data , channel_ref , data_type , data } , % { conn_state: conn_state } = state )
1368+ when conn_state != :failed do
1369+ { events , sctp_transport } =
1370+ SCTPTransport . send ( state . sctp_transport , channel_ref , data_type , data )
13481371
1349- handle_sctp_events ( events , state )
1372+ handle_sctp_events ( events , state )
13501373
1351- { :noreply , % { state | sctp_transport: sctp_transport } }
1352- end
1374+ { :noreply , % { state | sctp_transport: sctp_transport } }
1375+ end
13531376
1354- @ impl true
1355- def handle_cast ( { :send_data , _channel_ref , _data_type , _data } , state ) do
1356- { :noreply , state }
1377+ @ impl true
1378+ def handle_cast ( { :send_data , _channel_ref , _data_type , _data } , state ) do
1379+ { :noreply , state }
1380+ end
1381+ else
1382+ @ impl true
1383+ def handle_cast ( { :send_data , _channel_ref , _data_type , _data } , _state ) do
1384+ raise ( "#{ @ sctp_error_text } #{ @ sctp_tip } " )
1385+ end
13571386 end
13581387
13591388 @ impl true
@@ -1567,12 +1596,14 @@ defmodule ExWebRTC.PeerConnection do
15671596 { :noreply , % { state | transceivers: transceivers } }
15681597 end
15691598
1570- @ impl true
1571- def handle_info ( :sctp_timeout , state ) do
1572- { events , sctp_transport } = SCTPTransport . handle_timeout ( state . sctp_transport )
1573- handle_sctp_events ( events , state )
1599+ if Code . ensure_loaded? ( ExSCTP ) do
1600+ @ impl true
1601+ def handle_info ( :sctp_timeout , state ) do
1602+ { events , sctp_transport } = SCTPTransport . handle_timeout ( state . sctp_transport )
1603+ handle_sctp_events ( events , state )
15741604
1575- { :noreply , % { state | sctp_transport: sctp_transport } }
1605+ { :noreply , % { state | sctp_transport: sctp_transport } }
1606+ end
15761607 end
15771608
15781609 @ impl true
@@ -1677,10 +1708,15 @@ defmodule ExWebRTC.PeerConnection do
16771708
16781709 final_mlines = final_mlines ++ rem_mlines
16791710
1711+ # This double if is to make compiler happy about data_channels? always returning false
1712+ # when ExSCTP is not loaded. Tbh, I don't know why it works.
16801713 data_mline =
1681- if SCTPTransport . data_channels? ( state . sctp_transport ) and
1682- not Enum . any? ( final_mlines , & SDPUtils . data_channel? ( & 1 ) ) do
1683- [ generate_data_mline ( next_mid , opts ) ]
1714+ if SCTPTransport . data_channels? ( state . sctp_transport ) do
1715+ if Enum . any? ( final_mlines , & SDPUtils . data_channel? ( & 1 ) ) do
1716+ [ ]
1717+ else
1718+ [ generate_data_mline ( next_mid , opts ) ]
1719+ end
16841720 else
16851721 [ ]
16861722 end
0 commit comments