@@ -26,6 +26,11 @@ defmodule ExWebRTC.PeerConnection do
26
26
Utils
27
27
}
28
28
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
+
29
34
@ twcc_interval 100
30
35
@ twcc_uri "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"
31
36
@@ -1060,46 +1065,63 @@ defmodule ExWebRTC.PeerConnection do
1060
1065
end
1061
1066
end
1062
1067
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
1083
1096
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 )
1084
1100
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 } }
1088
1103
end
1089
- end
1090
1104
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
1095
1115
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
1098
1120
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
1103
1125
end
1104
1126
1105
1127
@ impl true
@@ -1340,20 +1362,27 @@ defmodule ExWebRTC.PeerConnection do
1340
1362
{ :noreply , state }
1341
1363
end
1342
1364
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 )
1348
1371
1349
- handle_sctp_events ( events , state )
1372
+ handle_sctp_events ( events , state )
1350
1373
1351
- { :noreply , % { state | sctp_transport: sctp_transport } }
1352
- end
1374
+ { :noreply , % { state | sctp_transport: sctp_transport } }
1375
+ end
1353
1376
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
1357
1386
end
1358
1387
1359
1388
@ impl true
@@ -1567,12 +1596,14 @@ defmodule ExWebRTC.PeerConnection do
1567
1596
{ :noreply , % { state | transceivers: transceivers } }
1568
1597
end
1569
1598
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 )
1574
1604
1575
- { :noreply , % { state | sctp_transport: sctp_transport } }
1605
+ { :noreply , % { state | sctp_transport: sctp_transport } }
1606
+ end
1576
1607
end
1577
1608
1578
1609
@ impl true
@@ -1677,10 +1708,15 @@ defmodule ExWebRTC.PeerConnection do
1677
1708
1678
1709
final_mlines = final_mlines ++ rem_mlines
1679
1710
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.
1680
1713
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 not Enum . any? ( final_mlines , & SDPUtils . data_channel? ( & 1 ) ) do
1716
+ [ generate_data_mline ( next_mid , opts ) ]
1717
+ else
1718
+ [ ]
1719
+ end
1684
1720
else
1685
1721
[ ]
1686
1722
end
0 commit comments