README.md

# Exagon Zeroconf

**Exagon Zerconf module**

Exagon Zeronconf provides utilites for interfacing Exagon with Zeronconf devices:
 - MDNS server
 - DNS-SD service discrovery
## Installation

This package can be installed by adding `exagon_zeroconf` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:exagon_zeroconf, "~> 0.1.0"}
  ]
end
```

## Integration

`Exagon.Zeronconf` can be used transparently by adding `Exagon.Zeroconf.Application` to your application
modules lists in `miex.exs`.

```
def application do
    [
      extra_applications: [:logger],
      mod: {Exagon.Zeroconf.Application, []}
    ]
  end
```

## Multicast DNS server

```Exagon.Zeroconf.Mdns.Server``` manage [Multicast DNS](https://www.rfc-editor.org/rfc/rfc6762.html) server request/answer. 
It is configured to listen on port `5353` on both IPv4 (`224.0.0.251`) and/or IPv6 (`ff02::fb`). 

DNS records found my ```Exagon.Zeroconf.Mdns.Server``` can be requested through `Exagon.Zeroconf.Mdns.Server.dump/0` :

```
Exagon.Zeroconf.Mdns.Server.dump
[
  %DNS.Resource{
    domain: 'My iPhone._rdlink._tcp.local',
    type: 47,
    class: :in,
    cnt: 0,
    ttl: 4500,
    data: <<192, 12, 0, 5, 0, 0, 128, 0, 64>>,
    tm: :undefined,
    bm: [],
    func: true
  },
  %DNS.Resource{
    domain: 'My iPhone.local',
    type: 47,
    class: :in,
    cnt: 0,
    ttl: 120,
    data: <<192, 236, 0, 4, 64, 0, 0, 8>>,
    tm: :undefined,
    bm: [],
    func: true
  },
  %DNS.Resource{
    domain: 'My iPhone.local',
    type: :a,
    class: :in,
    cnt: 0,
    ttl: 120,
    data: {192, 168, 1, 5},
    tm: :undefined,
    bm: [],
    func: true
  },
  %DNS.Resource{
    domain: 'My iPhone.local',
    type: :aaaa,
    class: :in,
    cnt: 0,
    ttl: 120,
    data: {8193, 2145, 13574, 1056, 58674, 15752, 37663, 62405},
    tm: :undefined,
    bm: [],
    func: true
  },
```
`Exagon.Zeroconf.Mdns.Server.subscribe/0` provides a way to subscribe for notifications about added, changed or removed records. 
Notifications use [Phoenix PubSub](https://hexdocs.pm/phoenix_pubsub/Phoenix.PubSub.html). 


### Configuration

```
config :exagon_zeroconf, :mdns,
  port: 5353,
  use_ipv4: true,
  use_ipv6: false,
  hostname: "exagon",
  domain_name: ".local"
```

## DNS-SD service Discovery

`Exagon.Zeroconf.Mdns.Dnssd` provides [DNS service discrovery](https://www.rfc-editor.org/rfc/rfc6763) over multicast DNS. 
It uses `Exagon.Zeroconf.Mdns.Dnssd.Server` to listen for DNS-SD relevand records and build a list of discovred services.

At anytime, a list of found services is available by calling `Exagon.Zeroconf.Mdns.Dnssd.query/1` which accepts an optional domain
parameter:

```
[
  },
  %Exagon.Zeroconf.Mdns.Dnssd.Service{
    domain: "_smb._tcp.local",
    instance_name: "Windows._smb._tcp.local",
    ip: nil,
    priority: 0,
    weight: 0,
    port: 445,
    target: "Windows.local",
    additional_info: nil,
    records: [:srv, :txt, :ptr]
  },
  %Exagon.Zeroconf.Mdns.Dnssd.Service{
    domain: "_spotify-connect._tcp.local",
    instance_name: "75c62f4dfb4ab9e7._spotify-connect._tcp.local",
    ip: {192, 168, 1, 12},
    priority: 0,
    weight: 0,
    port: 39753,
    target: "75c62f4dfb4ab9e7.local",
    additional_info: %{"cpath" => "/zc/0", "stack" => "SP", "version" => "1.0"},
    records: [:txt, :srv, :ptr]
  }
]
```


`Exagon.Zeronconf` can also be started manually by adding and starting `Exagon.Zeroconf.Supervisor` in your
supervision tree.

Documentation is generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published at <https://hexdocs.pm/exagon_zeroconf>.