Confirmed Service Request APDUs carry service invocations that require a reply.
They are the most frequently used APDU type for client/server interactions (ReadProperty, WriteProperty, SubscribeCOV, ReinitializeDevice, etc.).
APDU Description (ASHRAE 135)
The BACnet-Confirmed-Request-PDU is used to convey the information contained in a confirmed service request primitive. A confirmed service request always requires a reply from the remote peer (a SimpleACK, ComplexACK, Error, Reject, or Abort PDU). (Clause 21)
A Confirmed Service Request always contains:
- A 1-byte invoke ID used to correlate the future reply (ACK, ComplexACK, Error, ...).
- Segmentation control flags and negotiation parameters (
max_apdu,max_segments). - The concrete service choice (see
BACnet.Protocol.Constants.confirmed_service_choice/0). - Service-specific parameters encoded as Application Tags.
Segmentation
Confirmed requests may be segmented when the payload is larger than the negotiated
APDU size. Set sequence_number and proposed_window_size (both non-nil).
In normal use the BACnet.Stack.Segmentator takes care of this.
Reply Expectation
Every ConfirmedServiceRequest must be answered by the remote peer (within the APDU timeout) with one of: SimpleACK, ComplexACK, Error, Reject or Abort. Failure to reply results in a TSM (Transaction State Machine) timeout on the client side.
This module implements the BACnet.Stack.EncoderProtocol.
Decoding is performed by BACnet.Protocol.APDU.decode/1 (and
BACnet.Protocol.APDU.decode_confirmed_request/1).
Examples
Creating and encoding a Confirmed Service Request (see BACnet.Protocol.APDU for
a more complete walkthrough):
iex> req = %ConfirmedServiceRequest{
...> segmented_response_accepted: true, max_apdu: 1476, max_segments: :unspecified,
...> invoke_id: 35, sequence_number: nil, proposed_window_size: nil,
...> service: :read_property, parameters: [tagged: {0, <<0,0,0,1>>,4}, tagged: {1, "P", 1}]
...> }
iex> ConfirmedServiceRequest.encode(req)
{:ok, <<2, 5, 35, 12, 12, 0, 0, 0, 1, 25, 80>>}Decoding a raw Confirmed Request and converting it to a high-level service:
iex> raw = <<2, 3, 35, 15, 12, 0, 128, 0, 0, 25, 85, 62, 68, 66, 200, 0, 0, 63, 73, 10>>
iex> {:ok, apdu} = BACnet.Protocol.APDU.decode(raw)
{:ok, %ConfirmedServiceRequest{
invoke_id: 35,
max_apdu: 480,
max_segments: :unspecified,
parameters: [{:tagged, {0, <<0, 128, 0, 0>>, 4}}, {:tagged, {1, "U", 1}}, {:constructed, {3, {:real, 100.0}, 0}}, {:tagged, {4, "\n", 1}}],
proposed_window_size: nil,
segmented_response_accepted: true,
sequence_number: nil,
service: :write_property
}}
iex> ConfirmedServiceRequest.to_service(apdu)
{:ok, %BACnet.Protocol.Services.WriteProperty{
object_identifier: %BACnet.Protocol.ObjectIdentifier{type: :analog_value, instance: 0},
priority: 10,
property_array_index: nil,
property_identifier: :present_value,
property_value: %BACnet.Protocol.ApplicationTags.Encoding{type: :real, value: 100.0, encoding: :primitive, extras: []}
}}
Summary
Types
BACnet Confirmed Service Request service structs.
Represents the Application Data Unit (APDU) Confirmed Service Request.
Functions
Encodes the Confirmed Service Request APDU into binary data.
Converts the APDU into a service, if supported and possible.
Types
@type service() :: BACnet.Protocol.Services.AcknowledgeAlarm.t() | BACnet.Protocol.Services.AddListElement.t() | BACnet.Protocol.Services.AtomicReadFile.t() | BACnet.Protocol.Services.AtomicWriteFile.t() | BACnet.Protocol.Services.ConfirmedCovNotification.t() | BACnet.Protocol.Services.ConfirmedEventNotification.t() | BACnet.Protocol.Services.ConfirmedPrivateTransfer.t() | BACnet.Protocol.Services.ConfirmedTextMessage.t() | BACnet.Protocol.Services.CreateObject.t() | BACnet.Protocol.Services.DeleteObject.t() | BACnet.Protocol.Services.DeviceCommunicationControl.t() | BACnet.Protocol.Services.GetAlarmSummary.t() | BACnet.Protocol.Services.GetEnrollmentSummary.t() | BACnet.Protocol.Services.GetEventInformation.t() | BACnet.Protocol.Services.LifeSafetyOperation.t() | BACnet.Protocol.Services.ReadProperty.t() | BACnet.Protocol.Services.ReadPropertyMultiple.t() | BACnet.Protocol.Services.ReadRange.t() | BACnet.Protocol.Services.ReinitializeDevice.t() | BACnet.Protocol.Services.RemoveListElement.t() | BACnet.Protocol.Services.SubscribeCov.t() | BACnet.Protocol.Services.SubscribeCovProperty.t() | BACnet.Protocol.Services.WriteProperty.t() | BACnet.Protocol.Services.WritePropertyMultiple.t()
BACnet Confirmed Service Request service structs.
@type t() :: %BACnet.Protocol.APDU.ConfirmedServiceRequest{ invoke_id: 0..255, max_apdu: BACnet.Protocol.Constants.max_apdu(), max_segments: BACnet.Protocol.Constants.max_segments(), parameters: BACnet.Protocol.ApplicationTags.encoding_list(), proposed_window_size: 1..127 | nil, segmented_response_accepted: boolean(), sequence_number: 0..255 | nil, service: BACnet.Protocol.Constants.confirmed_service_choice() | non_neg_integer() }
Represents the Application Data Unit (APDU) Confirmed Service Request.
To allow forward compatibility, service is allowed to be an integer.
Functions
@spec encode(t()) :: {:ok, iodata()} | {:error, Exception.t()}
Encodes the Confirmed Service Request APDU into binary data.
Note that segmentation is ignored.
Converts the APDU into a service, if supported and possible.