BACnet.Stack.Segmentator (bacstack v0.0.1)

View Source

The Segmentator module is responsible for sending segmented requests or responses. Incoming segments need to be handled manually or through the BACnet.Stack.SegmentsStore module.

The Segmentator segments the given APDU (ComplexACK or ConfirmedServiceRequest) into segments of maximum APDU size and checks if the remote device supports the amount of segments. Both parameters need to be discovered by the user and given to this module, when creating a segmented sequence.

The Segmentator will automatically send segments in the window size given by the remote device and wait for their acknowledgement. Timeouts and retransmissions are handled automatically. Responses and retransmissions to the destination of a segmented request or response are automatically sent.

When the remote device is outside of the local network (packets are routed through a router), this module will automatically overwrite the "Proposed Window Size" with 1, to ensure segments ordering. Due to the nature of the UDP protocol (which BACnet/IP is based on), UDP re-ordering can occur and thus segments may arrive out-of-order. Re-ordering through the network may not occurr on other transport mediums. Whether a destination is outside of the local network is determined through the BACnet.Stack.TransportBehaviour module.

The Segmentator module is transport layer agnostic due to the nature of using the TransportBehaviour.

Users of this module need to route incoming Abort, Error, Reject and SegmentACK APDUs to this module, so the Segmentator can function properly. See the handle_apdu/3 documentation.

This module is written to not require one instance per destination or transport layer protocol, as such when creating a new sequence, the transport module, transport, portal, and destination parameters need to be given.

When wanting to send a new segmented request or response, first a new sequence must be created. As soon as the sequence is created, transmitting the segments, retransmissions and timeouts are handled automatically.

Summary

Types

Represents a server process of the Segmentator module.

Valid start options. For a description of each, see start_link/1.

List of start options.

Functions

Returns a specification to start this module under a supervisor.

Handles incoming Abort, Error, Reject and SegmentACK APDUs.

Starts and links the Segmentator.

Types

server()

@type server() :: GenServer.server()

Represents a server process of the Segmentator module.

start_option()

@type start_option() ::
  {:apdu_retries, pos_integer()}
  | {:apdu_timeout, pos_integer()}
  | GenServer.option()

Valid start options. For a description of each, see start_link/1.

start_options()

@type start_options() :: [start_option()]

List of start options.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

create_sequence(server, transport, destination, apdu, max_apdu_size, max_segments, opts \\ [])

Creates a new Sequence for an APDU.

This module will automatically send the segments or abort APDUs. Received Abort and SegmentACK APDUs need to be piped into this module through handle_apdu/3.

The opts argument will be passed on to the transport module's send function without modification.

handle_apdu(server, destination, apdu)

Handles incoming Abort, Error, Reject and SegmentACK APDUs.

Received Abort, Error, Reject and SegmentACK APDUs need to be piped into this module using this function. Only then this module can automatically function correctly and transmit or retransmit the segments.

Unknown destination-invoke ID mappings are silently ignored. As such the user can simply call this function with all matching APDUs. Although if there is a lot of traffic, the user should consider filtering and only call this function with interesting APDUs (APDUs for segmented requests/responses).

start_link(opts)

@spec start_link(start_options()) :: GenServer.on_start()

Starts and links the Segmentator.

The following options need to be given, in addition to GenServer.options/0:

  • apdu_retries: pos_integer() - Optional. The amount of APDU sending retries (defaults to 3).
  • apdu_timeout: pos_integer() - Optional. The APDU timeout to be waiting for a response, in ms (defaults to 3000ms).