balena/elixir-sippet

Support for TCP transport

anildigital opened this issue · 6 comments

We will be using a sippet library, but noticed there is no tcp transport. Is adding tcp transport something hard to current implementation?

Noticed there is this branch — https://github.com/balena/elixir-sippet/compare/add-tcp-support It's not yet merged, so not sure if anything is not working yet.

hi @balena

we considering using sippet in production on TCP too

what are the issues with this branch? what help do you need?

hello @balena

I was able to listen to the SIP messages over TCP, but unable to send them. Can you please check real quick, maybe some configuration is missing? Or point a hint so we could fix it and contribute maybe

defmodule SipServer.Application do
  @moduledoc false

  use Application

  @impl true
  def start(_type, _args) do
    children = [
      {Sippet, [name: :sip_server, core: SipServer.SippetCore]},
      {Sippet.Transports.TCP.Server, [[port: 5567, name: :sip_server]]}
    ]

    opts = [strategy: :one_for_one, name: SipServer.Supervisor]
    sup = Supervisor.start_link(children, opts)

    Sippet.register_transport(:sip_server, :tcp, true)

    sup
  end
end
defmodule SipServer.SippetCore do
  use Sippet.Core

  def receive_request(incoming_request, _server_key) do
    response = Sippet.Message.to_response(incoming_request, 202)

    # DEBUG
    IO.inspect(incoming_request, label: "[incoming_request]")
    IO.inspect(response, label: "[possible response]")

    # All is Ok till this point
    Sippet.send(:sip_server, response)
  end
end

There is an error in the console after Sippet.send

[error] GenStateMachine {:sip_server, {:transaction, ~K[z9hG4bKPj4zvINHB7f4mB-nM1Z1N8risSzArtHeMb|:register|192.168.0.146:5060]}} terminating
** (exit) exited in: GenServer.call({:via, Registry, {:sip_server, {:transport, :tcp}}}, {:send_message, %Sippet.Message{ ... }, "127.0.0.1", 51559, ~K[z9hG4bKPj4zvINHB7f4mB-nM1Z1N8risSzArtHeMb|:register|192.168.0.146:5060]}, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir 1.11.3) lib/gen_server.ex:1017: GenServer.call/3
    (sippet 1.0.7) lib/sippet/transactions/server.ex:38: Sippet.Transactions.Server.NonInvite.send_response/2
    (sippet 1.0.7) lib/sippet/transactions/server/non_invite.ex:20: Sippet.Transactions.Server.NonInvite.trying/3
    (stdlib 3.13.2) gen_statem.erl:1166: :gen_statem.loop_state_callback/11
    (stdlib 3.13.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
State: {:trying, %Sippet.Transactions.Server.State{extras: %{}, key: ~K[z9hG4bKPj4zvINHB7f4mB-nM1Z1N8risSzArtHeMb|:register|192.168.0.146:5060], request: %Sippet.Message{ ... }, sippet: :sip_server}}
Callback mode: :state_functions
Postponed events: []
Last event: {:cast, {:outgoing_response, %Sippet.Message{ ... }}}
Queued events: []
State: {:trying, %Sippet.Transactions.Server.State{extras: %{}, key: ~K[z9hG4bKPj4zvINHB7f4mB-nM1Z1N8risSzArtHeMb|:register|192.168.0.146:5060], request: %Sippet.Message{ ... }, sippet: :sip_server}}

did I miss starting something?

Dear @mpugach,

You cannot call Sippet.register_transport/3 from the application process. Instead, it should be done from the TCP transport process (the one that will receive messages like {:send_message, message, to_host, to_port, key} and dispatch through TCP sockets).

Sippet.register_transport/3 is just a thin wrapper around Registry.register/3.

@balena as I understand, we should implement our own TCP transport to make it work, right? I mean, I do not see any TCP transport provided in the branch

One of our use cases was sending the messages to a specific socket PID. We have a device ID in the message headers and map it to a socket through Registry. Extending the StreanHandler and the Router with some overrideable Core callback that selects the additional params for socket registration on the add-tcp-support seemed not straightforward enough for us.

We ended up rolling out our own Ranch-based solution and using the latest stable Sippet as a message parser.