Packages

An Elixir application for using the Service Location Protocol. SLP is a commonly used service discovery protocol.

Current section

Files

Jump to
slp lib slp_server.ex
Raw

lib/slp_server.ex

defmodule SLP.Server do
use GenServer
require Logger
@commands [{:register, 1},{:deregister, 2},{:find_services, 3},{:find_attributes, 4}]
def start_link(options) do
GenServer.start_link(__MODULE__, :ok, options)
end
def init(:ok) do
Logger.info "Starting SLP Port"
Process.flag(:trap_exit, true)
port = Port.open({:spawn, "#{:code.priv_dir(:slp)}/slp_port"}, [{:packet, 2}, :binary])
{:ok, port}
end
# Passes arguments through to the C program as null separated strings.
def handle_call {command, arguments}, _from, port do
data = Enum.reduce arguments, <<>>, fn(arg, acc) -> acc <> <<0::8, arg::binary>> end
Port.command(port, <<@commands[command]::8>> <> data <> <<0::8>>)
receive do
{port, {:data, response}} -> {:reply, handle_response(response), port}
{port, :closed} -> {:stop, :port_closed, port}
{:EXIT,port,reason} -> {:stop, {:port_exited, reason}, port}
end
end
defp handle_response "ok" do
:ok
end
defp handle_response <<"ok: ", response::binary>> do
{:ok, String.rstrip(response) |> String.split(["\n"])}
end
defp handle_response <<"error: ", errcode::binary>> do
errstring = error_string[String.to_integer(errcode)]
Logger.info("Error response from SLP: #{errcode} #{errstring}")
{:error, errstring}
end
defp error_string do
[{ 0, "Ok"},
{-1, "Language not supported."},
{-2, "Parse error."},
{-3, "Invalid Registration"},
{-4, "Scope not supported"},
{-6, "Authentication absent"},
{-7, "Authentication failed"},
{-13, "Invalid update"},
{-15, "Refresh rejected"},
{-17, "Not implemented"},
{-18, "Buffer overflow"},
{-19, "Network timed out: Is slpd running?"},
{-20, "Network init failed"},
{-21, "Out of memory error"},
{-22, "Parameter bad"},
{-23, "Network error"},
{-24, "Internal system error"},
{-25, "Handle in use"},
{-26, "Type error"}]
end
end