Current section
Files
Jump to
Current section
Files
lib/mavlink/serial_connection.ex
defmodule XMAVLink.SerialConnection do
@moduledoc false
@behaviour XMAVLink.Transport
require Logger
alias XMAVLink.Connection.Inbound
alias XMAVLink.ConnectionWorker
alias XMAVLink.Frame
alias Circuits.UART
defstruct port: nil,
baud: nil,
uart: nil,
buffer: <<>>,
worker: nil,
signing: nil
@type t :: %XMAVLink.SerialConnection{
port: binary,
baud: non_neg_integer,
uart: pid,
buffer: binary,
worker: pid | nil,
signing: XMAVLink.Signing.t() | nil
}
def handle_info(
{:circuits_uart, port, raw},
receiving_connection = %XMAVLink.SerialConnection{buffer: buffer},
dialect
) do
Inbound.stream(
raw,
receiving_connection,
buffer,
port,
dialect,
"SerialConnection.handle_info"
)
end
def open(["serial", port, baud], controlling_process) do
if Map.has_key?(UART.enumerate(), port) do
uart = :poolboy.checkout(XMAVLink.UARTPool)
case UART.open(uart, port, speed: baud, active: true) do
:ok ->
:ok = Logger.info("Opened serial port #{port} at #{baud} baud")
:ok = UART.controlling_process(uart, controlling_process)
{:ok, port,
struct(
XMAVLink.SerialConnection,
port: port,
baud: baud,
uart: uart,
worker: controlling_process
)}
{:error, reason} ->
:poolboy.checkin(XMAVLink.UARTPool, uart)
{:error, {:open_failed, reason}}
end
else
{:error, :not_attached}
end
end
def close(%XMAVLink.SerialConnection{uart: uart}) do
_ = UART.close(uart)
:poolboy.checkin(XMAVLink.UARTPool, uart)
end
def forward(
connection = %XMAVLink.SerialConnection{worker: worker},
frame
)
when is_pid(worker) do
ConnectionWorker.forward(worker, connection, frame)
end
def forward(
%XMAVLink.SerialConnection{uart: uart},
%Frame{version: 1, mavlink_1_raw: packet}
) do
UART.write(uart, packet)
end
def forward(
%XMAVLink.SerialConnection{uart: uart},
%Frame{version: 2, mavlink_2_raw: packet}
) do
UART.write(uart, packet)
end
end