Packages
sippet
1.0.10
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/transactions/server.ex
defmodule Sippet.Transactions.Server do
@moduledoc false
alias Sippet.Message
alias Sippet.Message.{RequestLine, StatusLine}
alias Sippet.Transactions.Server.State, as: State
def receive_request(server, %Message{start_line: %RequestLine{}} = request),
do: GenStateMachine.cast(server, {:incoming_request, request})
def send_response(server, %Message{start_line: %StatusLine{}} = response),
do: GenStateMachine.cast(server, {:outgoing_response, response})
def receive_error(server, reason),
do: GenStateMachine.cast(server, {:error, reason})
def terminate(server),
do: GenStateMachine.cast(server, :terminate)
defmacro __using__(opts) do
quote location: :keep do
use GenStateMachine, callback_mode: [:state_functions, :state_enter]
alias Sippet.Transactions.Server.State
require Logger
def init(%State{key: key} = data) do
Logger.debug("server transaction #{inspect(key)} started")
initial_state = unquote(opts)[:initial_state]
{:ok, initial_state, data}
end
defp send_response(response, %State{key: key, sippet: sippet} = data) do
extras = data.extras |> Map.put(:last_response, response)
data = %{data | extras: extras}
Sippet.Router.send_transport_message(sippet, response, key)
data
end
defp receive_request(request, %State{key: key, sippet: sippet}),
do: Sippet.Router.to_core(sippet, :receive_request, [request, key])
def shutdown(reason, %State{key: key, sippet: sippet} = data) do
Logger.warn("server transaction #{inspect(key)} shutdown: #{reason}")
Sippet.Router.to_core(sippet, :receive_error, [reason, key])
{:stop, :shutdown, data}
end
def timeout(data),
do: shutdown(:timeout, data)
def reliable?(request, %State{sippet: sippet}),
do: Sippet.reliable?(sippet, request)
def unhandled_event(:cast, :terminate, %State{key: key} = data) do
Logger.debug("server transaction #{inspect(key)} terminated")
{:stop, :normal, data}
end
def unhandled_event(event_type, event_content, %State{key: key} = data) do
Logger.error([
"server transaction #{inspect(key)} got unhandled_event/3:",
" #{inspect(event_type)}, #{inspect(event_content)}, #{inspect(data)}"
])
{:stop, :shutdown, data}
end
def child_spec([%{key: server_key}, _] = args) do
%{
id: {__MODULE__, server_key},
start: {__MODULE__, :start_link, [args]},
restart: :transient
}
end
def start_link([initial_data, opts]),
do: GenStateMachine.start_link(__MODULE__, initial_data, opts)
defoverridable init: 1,
send_response: 2,
receive_request: 2,
shutdown: 2,
timeout: 1,
unhandled_event: 3
end
end
end