NervesGate.Buses (nerves_gate v0.1.0)

Copy Markdown

CAN and RS485 ownership, SDK access and bounded diagnostics on allowlisted ports.

SDK serial claims exclude diagnostics and are released on owner exit. CAN receive sockets are shared by process-owned subscriptions. SDK sends never configure an interface or leave listen-only mode.

Commands

configure/3, capture/2 and modbus_read/3 return :ok when accepted, or {:error, reason}. CAN configuration and diagnostics complete asynchronously; RS485 configuration changes its in-memory opt-in immediately. Only one worker runs at a time. Read status/1 for completion, errors and results.

Queries and notifications

status/1 returns detected ports, the current operation and the last result. observe/1 subscribes the caller to changes. Idle observations never open UARTs or transmit traffic. Serial opt-in and results reset on restart. The optional server argument defaults to this module.

:bus_port_unavailable reports a missing, known enabled port. CAN enablement comes from observations; RS485 from explicit opt-in. Missing observations never erase known enablement. An observed return or removal of opt-in clears the condition. After restart, unknown CAN state preserves the previous alarm.

Summary

Functions

Start receive-only capture on an enabled port: up to five seconds, 200 frames or 4096 bytes.

Returns a specification to start this module under a supervisor.

Configure can0/can1 or opt ttyS3/ttyS4 in or out of diagnostics.

Request one authorized Modbus RTU read on ttyS3/ttyS4, without retry.

Subscribe the caller to bus status/result hints; reread status on notification.

Read ports, operation, result and error. An accepted operation finishes when operation is nil.

Functions

capture(port, server \\ __MODULE__)

@spec capture(String.t(), GenServer.server()) :: :ok | {:error, term()}

Start receive-only capture on an enabled port: up to five seconds, 200 frames or 4096 bytes.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

configure(port, params, server \\ __MODULE__)

@spec configure(String.t(), map(), GenServer.server()) :: :ok | {:error, term()}

Configure can0/can1 or opt ttyS3/ttyS4 in or out of diagnostics.

Params use string keys: "enabled" is required; CAN also requires a supported "bitrate" and defaults to listen-only mode. Administrators can explicitly set "listen_only" => false to permit SDK transmission; passive diagnostics still require listen-only mode. RS485 uses fixed 9600 8N1.

modbus_read(port, params, server \\ __MODULE__)

@spec modbus_read(String.t(), map(), GenServer.server()) :: :ok | {:error, term()}

Request one authorized Modbus RTU read on ttyS3/ttyS4, without retry.

String-keyed params: "authorized" must be true, "unit" 1–247, "function" 3 or 4, "address" zero-based 0–65535, and "count" 1–32 without crossing address 65535. The operator must ensure no other master is active.

observe(server \\ __MODULE__)

@spec observe(GenServer.server()) :: :ok | {:error, :unavailable}

Subscribe the caller to bus status/result hints; reread status on notification.

status(server \\ __MODULE__)

@spec status(GenServer.server()) :: map()

Read ports, operation, result and error. An accepted operation finishes when operation is nil.