use crate::ast::*;
use crate::builders::WireContext;
use alloc::vec::Vec;
pub fn build_bacnet_payload(
_ctx: &WireContext,
spec: &BacnetSpec,
payload_bytes: &[u8],
) -> Vec<u8> {
let mut apdu = Vec::new();
let is_broadcast = spec.is_who_is || (!spec.is_i_am && !spec.is_read_property && !spec.is_write_property);
if spec.is_read_property {
apdu.push(0x00); apdu.push(0x05); apdu.push(spec.invoke_id.unwrap_or(1)); apdu.push(0x0C);
let obj_type = spec.object_type.unwrap_or(8); let obj_inst = spec.object_instance.unwrap_or(1234);
let obj_id = ((obj_type as u32) << 22) | (obj_inst & 0x3FFFFF);
apdu.extend_from_slice(&[0x0C]); apdu.extend_from_slice(&obj_id.to_be_bytes());
apdu.extend_from_slice(&[0x19]); apdu.push(spec.property_id.unwrap_or(85) as u8); } else if spec.is_i_am {
apdu.push(0x10);
apdu.push(0x00);
let obj_inst = spec.object_instance.unwrap_or(1234);
let obj_id = (8u32 << 22) | (obj_inst & 0x3FFFFF);
apdu.extend_from_slice(&[0xC4]); apdu.extend_from_slice(&obj_id.to_be_bytes());
apdu.extend_from_slice(&[0x22, 0x04, 0x00]); apdu.extend_from_slice(&[0x91, 0x00]); apdu.extend_from_slice(&[0x21, 0x01]); } else {
apdu.push(0x10); apdu.push(0x08); }
if !payload_bytes.is_empty() {
apdu.extend_from_slice(payload_bytes);
}
let npdu = [0x01, 0x00]; let total_len = (4 + npdu.len() + apdu.len()) as u16;
let bvlc_func = if is_broadcast {
0x0B } else {
0x0A };
let mut pkt = Vec::with_capacity(total_len as usize);
pkt.push(0x81); pkt.push(bvlc_func);
pkt.extend_from_slice(&total_len.to_be_bytes());
pkt.extend_from_slice(&npdu);
pkt.extend_from_slice(&apdu);
pkt
}