diff --git a/lib/ex_webrtc/rtp_sender.ex b/lib/ex_webrtc/rtp_sender.ex index f61063e4..6acd3ace 100644 --- a/lib/ex_webrtc/rtp_sender.ex +++ b/lib/ex_webrtc/rtp_sender.ex @@ -134,12 +134,6 @@ defmodule ExWebRTC.RTPSender do @doc false @spec send_packet(sender(), ExRTP.Packet.t(), boolean()) :: {binary(), sender()} def send_packet(sender, packet, rtx?) do - %Extmap{} = mid_extmap = Map.fetch!(sender.rtp_hdr_exts, @mid_uri) - - mid_ext = - %ExRTP.Packet.Extension.SourceDescription{text: sender.mid} - |> ExRTP.Packet.Extension.SourceDescription.to_raw(mid_extmap.id) - {pt, ssrc} = if rtx? do {sender.rtx_pt, sender.rtx_ssrc} @@ -147,10 +141,25 @@ defmodule ExWebRTC.RTPSender do {sender.pt, sender.ssrc} end + packet = %{packet | payload_type: pt, ssrc: ssrc} + + # Add mid header extension only if it was negotiated. + # The receiver can still demux packets based + # on ssrc (if it was included in sdp) or payload type packet = - %{packet | payload_type: pt, ssrc: ssrc} - |> ExRTP.Packet.remove_extension(mid_extmap.id) - |> ExRTP.Packet.add_extension(mid_ext) + case Map.get(sender.rtp_hdr_exts, @mid_uri) do + %Extmap{} = mid_extmap -> + mid_ext = + %ExRTP.Packet.Extension.SourceDescription{text: sender.mid} + |> ExRTP.Packet.Extension.SourceDescription.to_raw(mid_extmap.id) + + packet + |> ExRTP.Packet.remove_extension(mid_extmap.id) + |> ExRTP.Packet.add_extension(mid_ext) + + nil -> + packet + end report_recorder = if sender.reports? do diff --git a/test/ex_webrtc/dtls_transport_test.exs b/test/ex_webrtc/dtls_transport_test.exs index 5d473f2d..69d90732 100644 --- a/test/ex_webrtc/dtls_transport_test.exs +++ b/test/ex_webrtc/dtls_transport_test.exs @@ -9,6 +9,10 @@ defmodule ExWebRTC.DTLSTransportTest do |> ExDTLS.get_cert_fingerprint() |> Utils.hex_dump() + @rtp_header <<1::1, 0::1, 0::1, 0::1, 0::4, 0::1, 96::7, 1::16, 1::32, 1::32>> + @rtp_payload <<0>> + @rtp_packet <<@rtp_header::binary, @rtp_payload::binary>> + defmodule MockICETransport do @behaviour ExWebRTC.ICETransport @@ -175,6 +179,10 @@ defmodule ExWebRTC.DTLSTransportTest do assert :ok = check_handshake(dtls, ice_transport, ice_pid, remote_dtls) assert_receive {:dtls_transport, ^dtls, {:state_change, :connecting}} assert_receive {:dtls_transport, ^dtls, {:state_change, :connected}} + + # assert we can send rtp packets + assert :ok = DTLSTransport.send_rtp(dtls, @rtp_packet) + assert_receive {:mock_ice, <<@rtp_header::binary, _payload::binary>>} end test "finishes handshake in passive mode", %{ @@ -200,6 +208,39 @@ defmodule ExWebRTC.DTLSTransportTest do assert :ok == check_handshake(dtls, ice_transport, ice_pid, remote_dtls) assert_receive {:dtls_transport, ^dtls, {:state_change, :connecting}} assert_receive {:dtls_transport, ^dtls, {:state_change, :connected}} + + # assert we can send rtp packets + assert :ok = DTLSTransport.send_rtp(dtls, @rtp_packet) + assert_receive {:mock_ice, <<@rtp_header::binary, _payload::binary>>} + end + + test "drops packets when packet loss is set", %{ + dtls: dtls, + ice_transport: ice_transport, + ice_pid: ice_pid + } do + :ok = DTLSTransport.start_dtls(dtls, :active, @fingerprint) + remote_dtls = ExDTLS.init(mode: :server, dtls_srtp: true) + + :ok = DTLSTransport.set_ice_connected(dtls) + + assert :ok = check_handshake(dtls, ice_transport, ice_pid, remote_dtls) + assert_receive {:dtls_transport, ^dtls, {:state_change, :connecting}} + assert_receive {:dtls_transport, ^dtls, {:state_change, :connected}} + + # assert we can send data + DTLSTransport.send_rtp(dtls, @rtp_packet) + assert_receive {:mock_ice, <<@rtp_header::binary, _payload::binary>>} + + # now set packet-loss + DTLSTransport.set_packet_loss(dtls, 100) + DTLSTransport.send_rtp(dtls, @rtp_packet) + refute_receive {:mock_ice, _rtp_packet} + end + + test "stop/1", %{dtls: dtls} do + assert :ok == DTLSTransport.stop(dtls) + assert false == Process.alive?(dtls) end defp check_handshake(dtls, ice_transport, ice_pid, remote_dtls) do @@ -218,9 +259,4 @@ defmodule ExWebRTC.DTLSTransportTest do :ok end end - - test "stop/1", %{dtls: dtls} do - assert :ok == DTLSTransport.stop(dtls) - assert false == Process.alive?(dtls) - end end