Skip to content

Commit

Permalink
chore: migrate to new bindata syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
stakach committed Feb 1, 2024
1 parent 59e1654 commit 2c5030b
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 158 deletions.
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: knx
version: 1.0.2
version: 1.0.3
crystal: ">= 0.36.1"

dependencies:
Expand Down
5 changes: 3 additions & 2 deletions src/knx/address.cr
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class KNX
bits 4, :main_group
bits 3, :middle_group
end
uint8 :sub_group

field sub_group : UInt8

def to_s : String
"#{main_group}/#{middle_group}/#{sub_group}"
Expand Down Expand Up @@ -129,7 +130,7 @@ class KNX
bits 4, :area_address
bits 4, :line_address
end
uint8 :device_address
field device_address : UInt8

def to_s : String
"#{area_address}.#{line_address}.#{device_address}"
Expand Down
18 changes: 9 additions & 9 deletions src/knx/cemi.cr
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class KNX
NumberedControl = 0b11
end

enum MsgCode
enum MsgCode : UInt8
RawRequest = 0x10
DataRequest = 0x11
PollDataRequest = 0x13
Expand Down Expand Up @@ -195,9 +195,9 @@ class KNX
class CEMI < BinData
endian :big

enum_field UInt8, msg_code : MsgCode = MsgCode::RawRequest
uint8 :info_length, value: ->{ additional_info.size }
bytes :additional_info, length: ->{ info_length }
field msg_code : MsgCode = MsgCode::RawRequest
field info_length : UInt8, value: ->{ additional_info.size }
field additional_info : Bytes, length: ->{ info_length }

# ---------------------
# Control Fields
Expand Down Expand Up @@ -241,7 +241,7 @@ class KNX
bits 1, :_reserved_ # default: 0_u8
bool no_repeat
bool broadcast
enum_bits 2, priority : Priority = Priority::LOW
bits 2, priority : Priority = Priority::LOW
bool ack_requested
bool is_error

Expand All @@ -262,10 +262,10 @@ class KNX
end

# When sending, setting the source address to 0 allows the router to configure
bytes :source_address, length: ->{ 2 }
bytes :destination_address, length: ->{ 2 }
field source_address : Bytes, length: ->{ 2 }
field destination_address : Bytes, length: ->{ 2 }

uint8 :data_length
field data_length : UInt8

# In the Common EMI frame, the APDU payload is defined as follows:

Expand Down Expand Up @@ -304,7 +304,7 @@ class KNX
# +-----------------------------------------------------------------------++-------------....
bit_field do
# transport protocol control information
enum_bits 2, tpci : TpciType = TpciType::UnnumberedData
bits 2, tpci : TpciType = TpciType::UnnumberedData
bits 4, :tpci_seq_num # Sequence number when tpci is sequenced
bits 4, :apci # application protocol control information (What we trying to do: Read, write, respond etc)
bits 6, :data # Or the tail end of APCI depending on the message type
Expand Down
16 changes: 8 additions & 8 deletions src/knx/connection/connect_request.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ class KNX
class ConnectRequest < BinData
endian big

custom header : Header = Header.new
custom control_endpoint : HPAI = HPAI.new
custom data_endpoint : HPAI = HPAI.new
custom cri : CRI = CRI.new
field header : Header = Header.new
field control_endpoint : HPAI = HPAI.new
field data_endpoint : HPAI = HPAI.new
field cri : CRI = CRI.new

def self.new(
control : Socket::IPAddress,
Expand All @@ -36,9 +36,9 @@ class KNX
class ConnectResponse < BinData
endian big

custom header : Header = Header.new
custom error : ErrorStatus = ErrorStatus.new
custom control_endpoint : HPAI = HPAI.new
custom crd : CRD = CRD.new
field header : Header = Header.new
field error : ErrorStatus = ErrorStatus.new
field control_endpoint : HPAI = HPAI.new
field crd : CRD = CRD.new
end
end
14 changes: 7 additions & 7 deletions src/knx/connection/connect_state_request.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ class KNX
class ConnectStateRequest < BinData
endian big

custom header : Header = Header.new
uint8 channel_id
enum_field UInt8, status : ConnectionError = ConnectionError::NoError
custom control_endpoint : HPAI = HPAI.new
field header : Header = Header.new
field channel_id : UInt8
field status : ConnectionError = ConnectionError::NoError
field control_endpoint : HPAI = HPAI.new

def self.new(
channel_id : Int,
Expand All @@ -33,8 +33,8 @@ class KNX
class ConnectStateResponse < BinData
endian big

custom header : Header = Header.new
uint8 channel_id
enum_field UInt8, status : ConnectionError = ConnectionError::NoError
field header : Header = Header.new
field channel_id : UInt8
field status : ConnectionError = ConnectionError::NoError
end
end
6 changes: 3 additions & 3 deletions src/knx/connection/crd.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ class KNX

LENGTH = 4

uint8 length, value: ->{ 4 }
enum_field UInt8, connect_type : ConnectType = ConnectType::Tunnel
uint16 identifier
field length : UInt8, value: ->{ 4 }
field connect_type : ConnectType = ConnectType::Tunnel
field identifier : UInt16
end
end
8 changes: 4 additions & 4 deletions src/knx/connection/cri.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class KNX
enum ConnectType
enum ConnectType : UInt8
# Data connection used to configure a KNXnet/IP device
DeviceManagement = 0x03

Expand All @@ -26,15 +26,15 @@ class KNX

LENGTH = 4

uint8 length, value: ->{ 4 }
enum_field UInt8, connect_type : ConnectType = ConnectType::Tunnel
field length : UInt8, value: ->{ 4 }
field connect_type : ConnectType = ConnectType::Tunnel
bit_field do
bool bus_monitor_tunnel
bits 4, :_reserved_
bool raw_tunnel
bool data_link_tunnel
bits 1, :_reserved2_
end
uint8 reserved
field reserved : UInt8
end
end
6 changes: 3 additions & 3 deletions src/knx/connection/error_status.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class KNX
enum ConnectionError
enum ConnectionError : UInt8
# The connection state is normal.
NoError = 0

Expand Down Expand Up @@ -40,7 +40,7 @@ class KNX
class ErrorStatus < BinData
LENGTH = 2

uint8 length, value: ->{ 1 }
enum_field UInt8, status : ConnectionError = ConnectionError::NoError
field length : UInt8, value: ->{ 1 }
field status : ConnectionError = ConnectionError::NoError
end
end
22 changes: 11 additions & 11 deletions src/knx/connection/tunnel_request.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ class KNX
class TunnelRequest < BinData
endian big

custom header : Header = Header.new
uint8 length, value: ->{ 4 }
uint8 channel_id
uint8 sequence
enum_field UInt8, status : ConnectionError = ConnectionError::NoError
field header : Header = Header.new
field length : UInt8, value: ->{ 4 }
field channel_id : UInt8
field sequence : UInt8
field status : ConnectionError = ConnectionError::NoError

custom cemi : CEMI = CEMI.new
field cemi : CEMI = CEMI.new

def self.new(
channel_id : Int,
Expand Down Expand Up @@ -44,10 +44,10 @@ class KNX
class TunnelResponse < BinData
endian big

custom header : Header = Header.new
uint8 length, value: ->{ 4 }
uint8 channel_id
uint8 sequence
enum_field UInt8, status : ConnectionError = ConnectionError::NoError
field header : Header = Header.new
field length : UInt8, value: ->{ 4 }
field channel_id : UInt8
field sequence : UInt8
field status : ConnectionError = ConnectionError::NoError
end
end
130 changes: 65 additions & 65 deletions src/knx/discovery/dib.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class KNX
enum DescriptionType
enum DescriptionType : UInt8
DeviceInformation = 1
SupportedServiceFamilies
IPConfig
Expand All @@ -8,52 +8,8 @@ class KNX
ManufacturerData = 0xFE
end

# Generic block
class InformationBlock < BinData
endian :big

uint8 length
enum_field UInt8, description_type : DescriptionType = DescriptionType::DeviceInformation

custom device_info : DIB = DIB.new, onlyif: ->{ description_type == DescriptionType::DeviceInformation }
array supported_services : ServiceFamily, length: ->{ (length - 2) // 2 }, onlyif: ->{ description_type == DescriptionType::SupportedServiceFamilies }

# Ignore data for information we can't parse
bytes raw_data, length: ->{ length - 2 }, onlyif: ->{
!{
DescriptionType::DeviceInformation,
DescriptionType::SupportedServiceFamilies,
}.includes?(description_type)
}
end

# Specific info blocks
class DeviceInfo < BinData
endian :big

LENGTH = 54

uint8 length, value: ->{ 54 }
enum_field UInt8, description_type : DescriptionType = DescriptionType::DeviceInformation
custom info : DIB = DIB.new

{% for func in [:name, :mac_address, :multicast_address, :serial] %}
def {{func.id}}
@info.{{func.id}}
end
{% end %}
end

class SupportedServices < BinData
endian :big

uint8 length, value: ->{ families.size * 2 + 2 }
enum_field UInt8, description_type : DescriptionType = DescriptionType::SupportedServiceFamilies
array families : ServiceFamily, length: ->{ (length - 2) // 2 }
end

@[Flags]
enum MediumType
enum MediumType : UInt8
Reserved
TP1
PL110
Expand All @@ -62,19 +18,36 @@ class KNX
IP
end

enum FamilyType : UInt8
Core = 2
DeviceManagement
Tunnelling
Routing
RemoteLogging
RemoteConfiguration
ObjectServer
end

class ServiceFamily < BinData
endian :big

field family_type : FamilyType = FamilyType::Core
field version : UInt8
end

# Device Information Block
class DIB < BinData
endian :big

enum_field UInt8, medium : MediumType = MediumType::IP
field medium : MediumType = MediumType::IP
# Device status just used to indicate if in programming mode
uint8 device_status
custom source : IndividualAddress = IndividualAddress.new
uint16 project_installation_id
bytes device_serial, length: ->{ 6 }
bytes device_multicast_address, length: ->{ 4 }
bytes device_mac_address, length: ->{ 6 }
string friendly_name, length: ->{ 30 }
field device_status : UInt8
field source : IndividualAddress = IndividualAddress.new
field project_installation_id : UInt16
field device_serial : Bytes, length: ->{ 6 }
field device_multicast_address : Bytes, length: ->{ 4 }
field device_mac_address : Bytes, length: ->{ 6 }
field friendly_name : String, length: ->{ 30 }

def programming_mode?
@device_status > 0
Expand All @@ -97,20 +70,47 @@ class KNX
end
end

enum FamilyType
Core = 2
DeviceManagement
Tunnelling
Routing
RemoteLogging
RemoteConfiguration
ObjectServer
# Generic block
class InformationBlock < BinData
endian :big

field length : UInt8
field description_type : DescriptionType = DescriptionType::DeviceInformation

field device_info : DIB = DIB.new, onlyif: ->{ description_type == DescriptionType::DeviceInformation }
field supported_services : Array(ServiceFamily), length: ->{ (length - 2) // 2 }, onlyif: ->{ description_type == DescriptionType::SupportedServiceFamilies }

# Ignore data for information we can't parse
field raw_data : Bytes, length: ->{ length - 2 }, onlyif: ->{
!{
DescriptionType::DeviceInformation,
DescriptionType::SupportedServiceFamilies,
}.includes?(description_type)
}
end

class ServiceFamily < BinData
# Specific info blocks
class DeviceInfo < BinData
endian :big

LENGTH = 54

field length : UInt8, value: ->{ 54 }
field description_type : DescriptionType = DescriptionType::DeviceInformation
field info : DIB = DIB.new

{% for func in [:name, :mac_address, :multicast_address, :serial] %}
def {{func.id}}
@info.{{func.id}}
end
{% end %}
end

class SupportedServices < BinData
endian :big

enum_field UInt8, family_type : FamilyType = FamilyType::Core
uint8 version
field length : UInt8, value: ->{ families.size * 2 + 2 }
field description_type : DescriptionType = DescriptionType::SupportedServiceFamilies
field families : Array(ServiceFamily), length: ->{ (length - 2) // 2 }
end
end
Loading

0 comments on commit 2c5030b

Please sign in to comment.