///|
/// Block type for AR block request.
pub let block_type_ar_req : Int = 257
///|
/// Block type for AR block response.
pub let block_type_ar_res : Int = 33025
///|
/// Block type for IOCR block request.
pub let block_type_iocr_req : Int = 258
///|
/// Block type for IOCR block response.
pub let block_type_iocr_res : Int = 33026
///|
/// Block type for AlarmCR block request.
pub let block_type_alarm_cr_req : Int = 259
///|
/// Block type for AlarmCR block response.
pub let block_type_alarm_cr_res : Int = 33027
///|
/// Block type for ExpectedSubmodule block request.
pub let block_type_expected_submodule_req : Int = 260
///|
/// Block type for ModuleDiffBlock in Connect.rsp.
pub let block_type_module_diff : Int = 33028
///|
/// Block type for IOX Control request (ControlBlockConnect/ApplicationReady).
pub let block_type_iox_control_req : Int = 274
///|
/// Block type for IOX Control response.
pub let block_type_iox_control_res : Int = 33042
///|
/// Wrap a block body in the standard IO block header:
/// BlockType(2) + BlockLength(2) + HighVersion(1) + LowVersion(1) + body.
/// BlockLength counts the two version bytes plus the body (mirrors the C#
/// reference `IoBlock.SerialiseList`).
fn encode_io_block(block_type : Int, body : Bytes) -> Bytes {
let output : Array[Byte] = []
push_u16_be(output, block_type)
push_u16_be(output, body.length() + 2)
output.push(b'\x01') // HighVersion
output.push(b'\x00') // LowVersion
append_bytes(output, body)
Bytes::from_array(output)
}
///|
/// Wrap a block whose body contains trailing UserSpecifiedData bytes.
///
/// For IODWriteReqHeader, the bytes are transmitted after the fixed header but
/// are excluded from the block length field, matching `IoBlock.SerialiseList`.
fn encode_io_block_with_user_data(
block_type : Int,
body : Bytes,
user_data_length : Int,
) -> Bytes {
let output : Array[Byte] = []
push_u16_be(output, block_type)
push_u16_be(output, body.length() + 2 - user_data_length)
output.push(b'\x01') // HighVersion
output.push(b'\x00') // LowVersion
append_bytes(output, body)
Bytes::from_array(output)
}
///|
/// AR type: IO Controller.
pub let ar_type_io_controller : Int = 1
///|
/// IOCR type: Input.
pub let iocr_type_input : Int = 1
///|
/// IOCR type: Output.
pub let iocr_type_output : Int = 2
///|
pub fn iocr_type_label(iocr_type : Int) -> String {
match iocr_type {
1 => "Input"
2 => "Output"
_ => "Unknown(" + iocr_type.to_string() + ")"
}
}
///|
fn push_u16_be(output : Array[Byte], value : Int) -> Unit {
output.push(((value >> 8) & 0xFF).to_byte())
output.push((value & 0xFF).to_byte())
}
///|
fn push_u32_be(output : Array[Byte], value : Int) -> Unit {
output.push(((value >> 24) & 0xFF).to_byte())
output.push(((value >> 16) & 0xFF).to_byte())
output.push(((value >> 8) & 0xFF).to_byte())
output.push((value & 0xFF).to_byte())
}
///|
fn read_u16_be(data : Bytes, offset : Int) -> Int {
(data[offset].to_int() << 8) + data[offset + 1].to_int()
}
///|
fn append_bytes(output : Array[Byte], data : Bytes) -> Unit {
for byte in data {
output.push(byte)
}
}