Documentation
¶
Overview ¶
Package protocol implements the Matter message framing, session management, exchange tracking, and encrypted message codec.
Index ¶
- Constants
- Variables
- func EncodeMessageHeader(h *MessageHeader) ([]byte, error)
- func EncodeProtocolHeader(p *ProtocolHeader) ([]byte, error)
- type Codec
- type Exchange
- type ExchangeManager
- func (em *ExchangeManager) CloseAll()
- func (em *ExchangeManager) CloseExchange(e *Exchange)
- func (em *ExchangeManager) Count() int
- func (em *ExchangeManager) HandleMessage(ctx context.Context, msg *Message) error
- func (em *ExchangeManager) NewExchange(ctx context.Context, session *Session) (*Exchange, error)
- type Message
- type MessageHeader
- type ProtocolHeader
- type Session
- type SessionTable
- type SessionType
Constants ¶
const ( // FlagSourceNodeID indicates the Source Node ID field is present (bit 2). FlagSourceNodeID byte = 1 << 2 // FlagDSIZMask is the mask for the Destination ID Size bits (bits 0-1). FlagDSIZMask byte = 0x03 // FlagVersionMask is the mask for the message version bits (bits 4-7). FlagVersionMask byte = 0xF0 )
Message flag bits (byte 0 of the message header).
const ( DSIZNone byte = 0x00 // No destination node ID present DSIZNodeID byte = 0x01 // 64-bit destination node ID DSIZGroup byte = 0x02 // 16-bit group ID )
DSIZ values for destination node ID encoding.
const ( // SecFlagSessionTypeMask is the mask for session type bits (bits 0-1). SecFlagSessionTypeMask byte = 0x03 // SecFlagMX indicates a message extension is present (bit 3). SecFlagMX byte = 1 << 3 // SecFlagC indicates the message is encrypted with a privacy key (bit 5). SecFlagC byte = 1 << 5 // SecFlagP indicates the message header is privacy-encrypted (bit 7). SecFlagP byte = 1 << 7 )
Security flag bits (byte 3 of the message header).
const ( SessionTypeUnicast byte = 0x00 SessionTypeGroup byte = 0x01 )
Session type values.
const ( // ExFlagInitiator indicates the sender is the exchange initiator (bit 0). ExFlagInitiator byte = 1 << 0 // ExFlagACK indicates an acknowledgment counter is present (bit 1). ExFlagACK byte = 1 << 1 // ExFlagReliable indicates the message requires reliable delivery (bit 2). ExFlagReliable byte = 1 << 2 // ExFlagSecuredExt indicates a secured extension is present (bit 3). ExFlagSecuredExt byte = 1 << 3 // ExFlagVendor indicates a vendor ID is present in the protocol header (bit 4). ExFlagVendor byte = 1 << 4 )
Protocol header exchange flag bits.
Variables ¶
var ErrExchangeClosed = errors.New("exchange closed")
ErrExchangeClosed is returned by Exchange.Receive when the exchange has been closed (e.g. because the underlying transport connection was lost). Callers can use errors.Is(err, ErrExchangeClosed) to distinguish a connection-loss closure from other receive failures.
Functions ¶
func EncodeMessageHeader ¶
func EncodeMessageHeader(h *MessageHeader) ([]byte, error)
EncodeMessageHeader serializes a MessageHeader into binary form.
func EncodeProtocolHeader ¶
func EncodeProtocolHeader(p *ProtocolHeader) ([]byte, error)
EncodeProtocolHeader serializes a ProtocolHeader into binary form.
Types ¶
type Codec ¶
type Codec struct{}
Codec handles encoding and decoding of complete Matter messages, including encryption and decryption of the payload using AES-CCM.
type Exchange ¶
type Exchange struct {
// ID is the exchange identifier.
ID uint16
// Session is the session this exchange belongs to.
Session *Session
// IsInitiator indicates whether the local node initiated this exchange.
IsInitiator bool
// SendFunc is the function used to send messages over the transport.
// If nil, Send is a no-op (for backward compatibility with tests).
SendFunc func(ctx context.Context, msg *Message) error
// contains filtered or unexported fields
}
Exchange represents a single Matter exchange — a sequence of messages between two nodes within a session.
func (*Exchange) Close ¶
func (e *Exchange) Close()
Close closes the exchange and its incoming message channel.
func (*Exchange) Receive ¶
Receive waits for the next message in this exchange, or returns an error if the context is cancelled or the exchange is closed.
type ExchangeManager ¶
type ExchangeManager struct {
// DefaultSendFunc is assigned to every new exchange created by NewExchange.
// It provides the transport-level send capability.
DefaultSendFunc func(ctx context.Context, msg *Message) error
// OnUnhandled is called when a message arrives for an unknown exchange
// and the sender is the initiator (i.e., this is a new incoming exchange).
// If nil, such messages are silently dropped.
OnUnhandled func(ctx context.Context, exchange *Exchange, msg *Message) error
// contains filtered or unexported fields
}
ExchangeManager tracks active exchanges and routes incoming messages to the correct exchange. It is safe for concurrent use.
func NewExchangeManager ¶
func NewExchangeManager() *ExchangeManager
NewExchangeManager creates a new ExchangeManager.
func (*ExchangeManager) CloseAll ¶
func (em *ExchangeManager) CloseAll()
CloseAll closes every active exchange and removes it from the manager. This is called when the underlying transport connection is lost so that any goroutine blocked in Exchange.Receive unblocks immediately instead of waiting for a context timeout.
func (*ExchangeManager) CloseExchange ¶
func (em *ExchangeManager) CloseExchange(e *Exchange)
CloseExchange removes an exchange from the manager and closes it.
func (*ExchangeManager) Count ¶
func (em *ExchangeManager) Count() int
Count returns the number of active exchanges.
func (*ExchangeManager) HandleMessage ¶
func (em *ExchangeManager) HandleMessage(ctx context.Context, msg *Message) error
HandleMessage routes an incoming decoded message to the appropriate exchange. If no matching exchange exists and the message is from an initiator, a new exchange is created and the OnUnhandled callback is invoked.
func (*ExchangeManager) NewExchange ¶
NewExchange creates a new locally-initiated exchange on the given session.
type Message ¶
type Message struct {
// Header is the unencrypted message header.
Header MessageHeader
// Protocol is the protocol header from within the decrypted payload.
Protocol ProtocolHeader
// Payload is the application payload (after the protocol header).
Payload []byte
}
Message represents a fully decoded Matter message with both headers and payload.
type MessageHeader ¶
type MessageHeader struct {
// Flags is the message flags byte.
Flags byte
// SessionID is the session identifier.
SessionID uint16
// SecurityFlags is the security flags byte.
SecurityFlags byte
// MessageCounter is the monotonically increasing message counter.
MessageCounter uint32
// SourceNodeID is the optional source node ID (present if FlagSourceNodeID is set).
SourceNodeID uint64
// HasSourceNodeID indicates whether SourceNodeID is present.
HasSourceNodeID bool
// DestinationNodeID is the optional 64-bit destination node ID.
DestinationNodeID uint64
// HasDestinationNodeID indicates whether DestinationNodeID is present.
HasDestinationNodeID bool
// DestinationGroupID is the optional 16-bit destination group ID.
DestinationGroupID uint16
// HasDestinationGroupID indicates whether DestinationGroupID is present.
HasDestinationGroupID bool
}
MessageHeader represents the unencrypted portion of a Matter message.
func DecodeMessageHeader ¶
func DecodeMessageHeader(data []byte) (*MessageHeader, int, error)
DecodeMessageHeader deserializes a MessageHeader from binary data. It returns the header and the number of bytes consumed.
func (*MessageHeader) SessionType ¶
func (h *MessageHeader) SessionType() byte
SessionType returns the session type from the security flags.
func (*MessageHeader) Version ¶
func (h *MessageHeader) Version() byte
Version returns the message version from the flags byte.
type ProtocolHeader ¶
type ProtocolHeader struct {
// ExchangeFlags contains the exchange-level flags.
ExchangeFlags byte
// ProtocolOpcode is the protocol-specific opcode.
ProtocolOpcode byte
// ExchangeID is the exchange identifier.
ExchangeID uint16
// ProtocolID identifies the protocol (e.g., 0x0000 for Secure Channel).
ProtocolID uint16
// VendorID is the optional vendor ID (present if ExFlagVendor is set).
VendorID uint16
// HasVendorID indicates whether VendorID is present.
HasVendorID bool
// AckMessageCounter is the optional acknowledgment counter (present if ExFlagACK is set).
AckMessageCounter uint32
// HasAckCounter indicates whether AckMessageCounter is present.
HasAckCounter bool
}
ProtocolHeader represents the protocol header within the decrypted payload.
func DecodeProtocolHeader ¶
func DecodeProtocolHeader(data []byte) (*ProtocolHeader, int, error)
DecodeProtocolHeader deserializes a ProtocolHeader from binary data. It returns the header and the number of bytes consumed.
func (*ProtocolHeader) IsInitiator ¶
func (p *ProtocolHeader) IsInitiator() bool
IsInitiator returns true if the sender is the exchange initiator.
func (*ProtocolHeader) NeedsACK ¶
func (p *ProtocolHeader) NeedsACK() bool
NeedsACK returns true if the message requires reliable delivery acknowledgment.
type Session ¶
type Session struct {
// ID is the local session identifier.
ID uint16
// PeerSessionID is the peer's session identifier.
PeerSessionID uint16
// Type is the session type (Unsecured, PASE, CASE).
Type SessionType
// LocalNodeID is the local (our) operational node ID for this session.
// Used in nonce construction when sending messages.
LocalNodeID uint64
// PeerNodeID is the peer's node ID.
// Used in nonce construction when receiving messages (if source node ID not in header).
PeerNodeID uint64
// EncryptKey is the session encryption key (16 bytes for AES-128-CCM).
EncryptKey []byte
// DecryptKey is the session decryption key (16 bytes for AES-128-CCM).
DecryptKey []byte
// AttestationChallenge is the attestation challenge for this session.
AttestationChallenge []byte
// contains filtered or unexported fields
}
Session represents a Matter communication session with its security context.
func (*Session) NextMessageCounter ¶
NextMessageCounter returns the next outgoing message counter and increments it.
func (*Session) ValidatePeerCounter ¶
ValidatePeerCounter checks whether a received message counter is valid (not a replay). It updates the tracking state if valid. Thread-safe.
type SessionTable ¶
type SessionTable struct {
// contains filtered or unexported fields
}
SessionTable manages active Matter sessions. It is safe for concurrent use.
func NewSessionTable ¶
func NewSessionTable() *SessionTable
NewSessionTable creates a new SessionTable. Session IDs start from 1 (ID 0 is reserved for unsecured sessions).
func (*SessionTable) Count ¶
func (st *SessionTable) Count() int
Count returns the number of active sessions (including the unsecured session if present).
func (*SessionTable) CreateSession ¶
func (st *SessionTable) CreateSession(sessionType SessionType) (*Session, error)
CreateSession allocates a new session with the given type and returns it.
func (*SessionTable) GetSession ¶
func (st *SessionTable) GetSession(id uint16) *Session
GetSession looks up a session by its local ID. Returns nil if not found.
func (*SessionTable) RemoveSession ¶
func (st *SessionTable) RemoveSession(id uint16)
RemoveSession removes a session by its local ID.
func (*SessionTable) UnsecuredSession ¶
func (st *SessionTable) UnsecuredSession() *Session
UnsecuredSession returns the shared unsecured session (ID 0). The message counter is initialized to a random value as required by the Matter spec.
type SessionType ¶
type SessionType int
SessionType distinguishes between the different Matter session types.
const ( // SessionUnsecured represents an unauthenticated session (session ID 0). SessionUnsecured SessionType = iota // SessionPASE represents a session established via PASE (Passcode-Authenticated Session Establishment). SessionPASE // SessionCASE represents a session established via CASE (Certificate-Authenticated Session Establishment). SessionCASE )
func (SessionType) String ¶
func (st SessionType) String() string
String returns a human-readable name for the session type.