Skip to content

Commit 97641db

Browse files
authored
Add support for remote mdns candidates (#13)
1 parent ec9cebb commit 97641db

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

lib/ex_libnice.ex

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,28 @@ defmodule ExLibnice do
66
"""
77

88
use GenServer
9+
use Bunch
910

1011
require Logger
1112
require Unifex.CNode
1213

1314
defmodule State do
1415
@moduledoc false
16+
use Bunch.Access
1517

1618
@type t :: %__MODULE__{
1719
parent: pid,
1820
cnode: Unifex.CNode.t(),
19-
stream_components: %{stream_id: integer(), n_components: integer()}
21+
stream_components: %{stream_id: integer(), n_components: integer()},
22+
mdns_queries: %{
23+
query: String.t(),
24+
candidate: {sdp :: String.t(), stream_id :: integer(), component_id :: integer()}
25+
}
2026
}
2127
defstruct parent: nil,
2228
cnode: nil,
23-
stream_components: %{}
29+
stream_components: %{},
30+
mdns_queries: %{}
2431
end
2532

2633
@typedoc """
@@ -258,6 +265,11 @@ defmodule ExLibnice do
258265

259266
state = %State{parent: opts[:parent], cnode: cnode}
260267

268+
Logger.debug("Initializing mDNS lookup process")
269+
Mdns.Client.start()
270+
Logger.debug("Registering for mDNS events")
271+
Mdns.EventManager.register()
272+
261273
{:ok, state}
262274
end
263275

@@ -390,18 +402,28 @@ defmodule ExLibnice do
390402

391403
@impl true
392404
def handle_call(
393-
{:set_remote_candidate, candidate, stream_id, component_id},
405+
{:set_remote_candidate, "a=", _stream_id, _component_id},
394406
_from,
395-
%{cnode: cnode} = state
407+
state
396408
) do
397-
case Unifex.CNode.call(cnode, :set_remote_candidate, [candidate, stream_id, component_id]) do
398-
:ok ->
399-
Logger.debug("Set remote candidate: #{inspect(candidate)}")
400-
{:reply, :ok, state}
409+
Logger.debug("Empty candidate \"a=\". Should we do something with it?")
410+
{:reply, :ok, state}
411+
end
401412

402-
{:error, cause} ->
403-
Logger.warn("Couldn't set remote candidate: #{inspect(cause)}")
404-
{:reply, {:error, cause}, state}
413+
@impl true
414+
def handle_call({:set_remote_candidate, candidate, stream_id, component_id}, _from, state) do
415+
candidate_sp = String.split(candidate, " ", parts: 6)
416+
417+
withl candidate_check: 6 <- length(candidate_sp),
418+
do: address = Enum.at(candidate_sp, 4),
419+
mdns_check: true <- String.ends_with?(address, ".local") do
420+
Logger.debug("Sending query to resolve mDNS address #{inspect(address)}")
421+
Mdns.Client.query(address)
422+
state = put_in(state, [:mdns_queries, address], {candidate, stream_id, component_id})
423+
{:reply, :ok, state}
424+
else
425+
candidate_check: _ -> {:reply, {:error, :failed_to_parse_sdp_string}, state}
426+
mdns_check: _ -> do_set_remote_candidate(candidate, stream_id, component_id, state)
405427
end
406428
end
407429

@@ -515,6 +537,31 @@ defmodule ExLibnice do
515537
{:noreply, state}
516538
end
517539

540+
@impl true
541+
def handle_info({_namespace, %Mdns.Client.Device{} = dev} = msg, state) do
542+
Logger.debug("mDNS address resolved #{inspect(msg)}")
543+
544+
{query, state} = pop_in(state, [:mdns_queries, dev.domain])
545+
546+
case query do
547+
nil ->
548+
Logger.debug("""
549+
mDNS response for non existing candidate.
550+
We have probably already resolved address #{inspect(dev.domain)}
551+
""")
552+
553+
{candidate, stream_id, component_id} ->
554+
candidate_parts =
555+
String.split(candidate, " ", parts: 6)
556+
|> List.replace_at(4, :inet.ntoa(dev.ip))
557+
558+
candidate = Enum.join(candidate_parts, " ")
559+
do_set_remote_candidate(candidate, stream_id, component_id, state)
560+
end
561+
562+
{:noreply, state}
563+
end
564+
518565
@impl true
519566
def handle_info(msg, state) do
520567
Logger.warn("Unknown message #{inspect(msg)}")
@@ -606,4 +653,16 @@ defmodule ExLibnice do
606653
[h | _t] -> {:ok, h}
607654
end
608655
end
656+
657+
defp do_set_remote_candidate(candidate, stream_id, component_id, %{cnode: cnode} = state) do
658+
case Unifex.CNode.call(cnode, :set_remote_candidate, [candidate, stream_id, component_id]) do
659+
:ok ->
660+
Logger.debug("Set remote candidate: #{inspect(candidate)}")
661+
{:reply, :ok, state}
662+
663+
{:error, cause} ->
664+
Logger.warn("Couldn't set remote candidate: #{inspect(cause)}")
665+
{:reply, {:error, cause}, state}
666+
end
667+
end
609668
end

mix.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ defmodule ExLibnice.MixProject do
3838
defp deps do
3939
[
4040
{:unifex, "~> 0.3.3"},
41+
{:bunch, "~> 1.3.0"},
42+
{:mdns, "~> 1.0.12"},
4143
{:ex_doc, "~> 0.23", only: :dev, runtime: false},
4244
{:dialyxir, "~> 1.0", only: :dev, runtime: false},
4345
{:credo, "~> 1.5", only: :dev, runtime: false}

mix.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,23 @@
66
"coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"},
77
"credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"},
88
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
9+
"dns": {:hex, :dns, "2.2.0", "4721a79c2bccc25481930dffbfd06f40851321c3d679986af307111214bf124c", [:mix], [{:socket, "~> 0.3.13", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm", "13ed1ef36ce896211ec6ce5e02709dbfb12aa61d6255bda8d531577a0a5a56e0"},
910
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
1011
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
1112
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
1213
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
1314
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
1415
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
1516
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
17+
"mdns": {:hex, :mdns, "1.0.12", "b5437fb940dea64c867832dd99255da981a4b98404e586e53cc332a973c209f1", [:mix], [{:dns, "~> 2.2", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm", "643c9d1ca6f408a7eb13cf693719814c93d18f4ec96f97bc23d25aa28f4d95fa"},
1618
"membrane_core": {:hex, :membrane_core, "0.6.0", "7f8bef262c9f68c174f6e95acd9c445f4289a2a0fed56801d573f821f96e47f3", [:mix], [{:bunch, "~> 1.3", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 2.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "46163606a3183c4ea46b14c1c199374822388cbb567f54a8a3e66a098b2432a5"},
1719
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
1820
"numbers": {:hex, :numbers, "5.2.1", "8a6e9eeacfb19f4ac30a52c304f565dc53f8e0813b7193812a5b15b93210780c", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "1fd66efe26b67456ad0b80a038f553b89702d073a6942ecd34ce1a3e10af4c92"},
1921
"qex": {:hex, :qex, "0.5.0", "5a3a9becf67d4006377c4c247ffdaaa8ae5b3634a0caadb788dc24d6125068f4", [:mix], [], "hexpm", "4ad6f6421163cd8204509a119a5c9813cbb969cfb8d802a9dc49b968bffbac2a"},
2022
"ratio": {:hex, :ratio, "2.4.1", "ecf989f3a1483cf892b867ab00ffe8e0784cbe748cd32a610a4ac4c4fd11f46d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "3988235b59285b8fef9a55867c0b82125b59915ac80808de064b33ff57b0d54c"},
2123
"secure_random": {:hex, :secure_random, "0.5.1", "c5532b37c89d175c328f5196a0c2a5680b15ebce3e654da37129a9fe40ebf51b", [:mix], [], "hexpm", "1b9754f15e3940a143baafd19da12293f100044df69ea12db5d72878312ae6ab"},
2224
"shmex": {:hex, :shmex, "0.3.0", "5b995fa0bba3ff48fb9a93fdd116f5e6f7c0012da00775564a8d29d199618b8c", [:mix], [{:bunch_native, "~> 0.3.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.4.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "05b2cc456eb549bd40a53bf641c47008acba0185f25c1906b934b0b91c36f1c4"},
25+
"socket": {:hex, :socket, "0.3.13", "98a2ab20ce17f95fb512c5cadddba32b57273e0d2dba2d2e5f976c5969d0c632", [:mix], [], "hexpm", "f82ea9833ef49dde272e6568ab8aac657a636acb4cf44a7de8a935acb8957c2e"},
2326
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
2427
"unifex": {:hex, :unifex, "0.3.3", "d2b671426bd9951cb739c1fff9ce1993b6a07d10ef741f9ae76fd8ecb7e72427", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.4.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.3.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "4527805864f93543dd3665abb8b7a61820f1362845ab0c3663f92e418e616a84"},
2528
}

0 commit comments

Comments
 (0)