AVModbus.Server behaviour (avmodbus v0.1.0)

Copy Markdown View Source

transport-independent な Modbus server request processor です。

handler は 2-argument function または {module, argument} tuple で指定します。 module handler は handle_request/3 を実装し、unit id と decoded request を受け取ります。

start_link/1 は統一 startup facade として transport-specific managed server に委譲します。 request processor 自身は UART / socket を所有せず、serial / TCP server loop が framing と lifecycle を担当して complete request PDU を respond/3 に渡します。

AtomVM の SSL API で mutual-authenticated server を構築できるようになるまでは、TLS option を {:error, :tls_not_supported} で fail closed します。

Summary

Functions

transport 自身が処理する request に対して authorization を確認します。

wire response を encode せず server handler を呼び出します。

handler を isolated process で timeout 付き実行します。

TCP server が listen している port を返します。

request PDU を decode し、handler を呼び出して response PDU を encode します。

respond/3 に handler execution timeout を追加した variant です。

respond/4 に authorization、peer role、device identification policy を追加した variant です。

managed Modbus server を起動し、raw PID を返します。

managed server の現在の transport state を返します。

managed server を停止し、所有する listener または UART を閉じます。

Types

authorize()

@type authorize() :: (term(), unit_id(), AVModbus.PDU.request() -> boolean())

handler()

@type handler() ::
  (unit_id(), AVModbus.PDU.request() -> AVModbus.PDU.result())
  | {module(), term()}

policy()

@type policy() :: %{
  optional(:authorize) => authorize() | nil,
  optional(:identification) => AVModbus.Server.Identification.objects() | nil,
  optional(:role) => term()
}

unit_id()

@type unit_id() :: 0..255

Callbacks

handle_request(unit_id, request, term)

@callback handle_request(unit_id(), AVModbus.PDU.request(), term()) ::
  AVModbus.PDU.result()

Functions

allowed?(authorize, role, unit_id, request, handler_timeout)

@spec allowed?(
  authorize() | nil,
  term(),
  unit_id(),
  AVModbus.PDU.request(),
  pos_integer() | :infinity
) ::
  boolean()

transport 自身が処理する request に対して authorization を確認します。

callback がない場合は許可します。callback crash、falsey result、timeout は拒否として扱います。

handle_request(handler, unit_id, request)

@spec handle_request(handler(), unit_id(), AVModbus.PDU.request()) ::
  AVModbus.PDU.result()

wire response を encode せず server handler を呼び出します。

handle_request(handler, unit_id, request, handler_timeout)

@spec handle_request(
  handler(),
  unit_id(),
  AVModbus.PDU.request(),
  pos_integer() | :infinity
) ::
  AVModbus.PDU.result()

handler を isolated process で timeout 付き実行します。

port(server)

@spec port(pid() | atom()) :: 0..65535 | {:error, term()}

TCP server が listen している port を返します。

respond(handler, unit_id, pdu)

@spec respond(handler(), unit_id(), binary()) :: {:ok, binary()} | :ignore

request PDU を decode し、handler を呼び出して response PDU を encode します。

malformed request は Modbus exception response に変換します。empty PDU や public request range 外の function byte は valid response function を導けないため無視します。

respond(handler, unit_id, pdu, handler_timeout)

@spec respond(handler(), unit_id(), binary(), pos_integer() | :infinity) ::
  {:ok, binary()} | :ignore

respond/3 に handler execution timeout を追加した variant です。

handler は monitored process で実行され、crash / timeout は transport process を落とさず server_device_failure response に変換されます。

respond(handler, unit_id, pdu, handler_timeout, policy)

@spec respond(handler(), unit_id(), binary(), pos_integer() | :infinity, policy()) ::
  {:ok, binary()} | :ignore

respond/4 に authorization、peer role、device identification policy を追加した variant です。

policy key は :authorize、:role、:identification です。authorization と response generation は 同じ handler timeout の中で 1 つの isolated process として実行します。

start_link(options)

@spec start_link(keyword()) :: {:ok, pid()} | {:error, term()}

managed Modbus server を起動し、raw PID を返します。

:transport は必須で、:tcp、:rtu、:ascii のいずれかを指定します。 :handler と選択した transport module の options を同じ list に指定します。 transport: :tls、tls:、ssl: は現在 {:error, :tls_not_supported} を返します。

status(server)

@spec status(pid() | atom()) :: term()

managed server の現在の transport state を返します。

stop(server)

@spec stop(pid() | atom()) :: :ok

managed server を停止し、所有する listener または UART を閉じます。