Packages
sippet
0.1.2
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
An Elixir Session Initiation Protocol (SIP) stack.
Current section
Files
Jump to
Current section
Files
lib/sippet/transport/udp/plug.ex
defmodule Sippet.Transport.UDP.Plug do
use GenServer
use Sippet.Transport.Plug
alias Sippet.Transport.UDP.Pool, as: Pool
import Supervisor.Spec
require Logger
@doc """
Starts the UDP plug.
"""
def start_link() do
port =
Application.get_env(:sippet, __MODULE__)
|> Keyword.fetch!(:port)
if port <= 0 do
raise ArgumentError, "invalid port #{inspect port}"
end
address =
Application.get_env(:sippet, __MODULE__)
|> Keyword.get(:address)
opts =
case address do
nil -> []
ip -> [address: ip]
end
children = [
worker(GenServer, [__MODULE__, [port, opts], [name: __MODULE__]]),
Pool.spec()
]
Supervisor.start_link(children, [strategy: :one_for_one])
end
def send_message(message, host, port, transaction) do
conn = Pool.check_out()
GenServer.cast(conn, {:send_message, message, host, port, transaction})
end
def reliable?(), do: false
def get_socket(),
do: GenServer.call(__MODULE__, :get_socket, :infinity)
def init([port, opts]) do
sock_opts =
[as: :binary, mode: :active] ++
if Keyword.has_key?(opts, :address) do
[local: [address: opts[:address]]]
else
[]
end
socket = Socket.UDP.open!(port, sock_opts)
{:ok, {address, _port}} = :inet.sockname(socket)
Logger.info("#{inspect self()} started plug " <>
"#{:inet.ntoa(address)}:#{port}/udp")
{:ok, {socket, address, port}}
end
def handle_info({:udp, _socket, ip, from_port, packet}, state) do
Sippet.Transport.Queue.incoming_datagram(packet, {:udp, ip, from_port})
{:noreply, state}
end
def handle_info(request, state),
do: super(request, state)
def handle_call(:get_socket, _from, {socket, _address, _port} = state),
do: {:reply, socket, state}
def handle_call(request, from, state),
do: super(request, from, state)
def terminate(reason, {socket, address, port}) do
Logger.info("#{inspect self()} stopped plug " <>
"#{:inet.ntoa(address)}:#{port}/udp, " <>
"reason: #{inspect reason}")
:ok = :gen_udp.close(socket)
end
def terminate(reason, state),
do: super(reason, state)
end