Documentation
¶
Overview ¶
Package bacnet decodes BACnet/IP (BACnet over UDP, ASHRAE 135 Annex J) frames — the dominant building-automation protocol used in HVAC controllers, lighting panels, energy meters, fire-alarm gateways, elevator dispatch, and BMS (Building Management Systems) front-ends.
Wrap-vs-native judgement ¶
Native. BACnet is defined by the public ASHRAE 135 standard. The BACnet/IP transport (Annex J) wraps a BACnet NPDU + APDU inside a 4-byte BVLC (BACnet Virtual Link Control) header, followed by an NPDU (network-layer header with optional source / destination addressing + hop count) and an APDU (application-layer PDU carrying the actual confirmed / unconfirmed service request or response). Every envelope field is a fixed-format byte stream; type/function dispatch is a series of small lookup tables. Pasting a hex blob from Wireshark / YABE (Yet Another BACnet Explorer) / a captured UDP/47808 frame is enough — no vendor SDK, no handshake.
What this package covers ¶
- BVLC envelope: Type byte (always 0x81 for BACnet/IP), Function byte (12 documented values, 0x00 BVLC-Result through 0x0C Secure-BVLL), Length field covering the full frame.
- NPDU envelope: Version (always 1 for current spec), Control byte with bit-field decode (Network Layer Message / Destination Specifier / Source Specifier / Reply Expected / Priority), optional Destination Network
- Destination Address (length-prefixed), optional Source Network + Source Address (length-prefixed), Hop Count (present when destination is specified), and optional network-layer Message Type.
- APDU envelope: 4-bit PDU Type (8 documented types, 0x0 Confirmed-Request through 0x7 Abort), per-type flag decode (SEG / MOR / SA / Server / Sent-By-Server / Negative-ACK), Invoke ID, Sequence Number / Window Size for segmented PDUs, Max Segments Accepted / Max APDU Length Accepted for Confirmed-Request, ServiceChoice with a 30+ entry confirmed-service table and a 10+ entry unconfirmed-service table.
- Network-layer message type lookup (~16 entries) when the NPDU Control byte's NLM bit is set.
- Error / Reject / Abort reason code lookup (~30 entries for Error, 10 for Reject, 8 for Abort).
What this package does NOT cover (deliberately out of scope) ¶
- BACnet-tagged data decoding (the APDU body): the ASN.1-style tagged encoding (context vs application tags, primitive vs constructed) requires a recursive walker that's a substantial separate iteration. The ServiceChoice + raw payload hex are surfaced so the operator can compare against the standard's service- specific layouts.
- BACnet MS/TP (RS-485 dialect), BACnet/Ethernet (Type 0x82), BACnet/PTP, BACnet/ARCnet — each has a different envelope. Only Annex J BACnet/IP is in scope for this Spec.
- BACnet-Secure / BACnet/SC (Secure Connect) — the 0x0C Secure-BVLL function is named but the encrypted payload is not decoded.
- Object-instance + property-identifier lookup beyond the ServiceChoice level. The standard defines ~50 object types and ~250 properties; that catalog will land as a separate Spec when needed.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APDU ¶
type APDU struct {
PDUType int `json:"pdu_type"`
PDUTypeName string `json:"pdu_type_name"`
Segmented bool `json:"segmented,omitempty"`
MoreFollows bool `json:"more_follows,omitempty"`
SegmentedRespAccepted bool `json:"segmented_response_accepted,omitempty"`
MaxSegmentsAccepted *int `json:"max_segments_accepted,omitempty"`
MaxAPDULenAccepted *int `json:"max_apdu_len_accepted,omitempty"`
InvokeID *int `json:"invoke_id,omitempty"`
SequenceNumber *int `json:"sequence_number,omitempty"`
WindowSize *int `json:"window_size,omitempty"`
ServiceChoice *int `json:"service_choice,omitempty"`
ServiceChoiceName string `json:"service_choice_name,omitempty"`
Server bool `json:"server,omitempty"`
NegativeACK bool `json:"negative_acknowledgement,omitempty"`
ErrorClass *int `json:"error_class,omitempty"`
ErrorCode *int `json:"error_code,omitempty"`
RejectReason *int `json:"reject_reason,omitempty"`
RejectReasonName string `json:"reject_reason_name,omitempty"`
AbortReason *int `json:"abort_reason,omitempty"`
AbortReasonName string `json:"abort_reason_name,omitempty"`
BodyHex string `json:"body_hex,omitempty"`
}
APDU is the BACnet Application Protocol Data Unit header.
type BVLC ¶
type BVLC struct {
Type int `json:"type"`
TypeName string `json:"type_name"`
Function int `json:"function"`
FunctionName string `json:"function_name"`
Length int `json:"length"`
}
BVLC is the 4-byte BACnet Virtual Link Control header.
type Frame ¶
type Frame struct {
HexInput string `json:"hex_input"`
BVLC *BVLC `json:"bvlc"`
NPDU *NPDU `json:"npdu,omitempty"`
APDU *APDU `json:"apdu,omitempty"`
}
Frame is the decoded view of a BACnet/IP frame.
func DecodeBytes ¶
DecodeBytes parses a raw BACnet/IP frame.
type NPDU ¶
type NPDU struct {
Version int `json:"version"`
ControlByte int `json:"control_byte"`
NetworkLayerMsg bool `json:"network_layer_message"`
DestSpecifier bool `json:"destination_specifier"`
SourceSpecifier bool `json:"source_specifier"`
ReplyExpected bool `json:"reply_expected"`
Priority int `json:"priority"`
PriorityName string `json:"priority_name"`
DestNetwork *int `json:"destination_network,omitempty"`
DestAddressHex string `json:"destination_address_hex,omitempty"`
SourceNetwork *int `json:"source_network,omitempty"`
SourceAddressHex string `json:"source_address_hex,omitempty"`
HopCount *int `json:"hop_count,omitempty"`
MessageType *int `json:"network_message_type,omitempty"`
MessageTypeName string `json:"network_message_type_name,omitempty"`
}
NPDU is the BACnet Network Protocol Data Unit header.