From 9089ab3fd3b89ba107a24177aa6629ae720f5324 Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Wed, 1 Mar 2023 07:42:12 +0530 Subject: [PATCH] Tests: Test subscribe with multi-leg reads --- matter/src/interaction_model/messages.rs | 18 ++++++++-- matter/tests/data_model/long_reads.rs | 44 ++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/matter/src/interaction_model/messages.rs b/matter/src/interaction_model/messages.rs index 3c164ae..d1de33f 100644 --- a/matter/src/interaction_model/messages.rs +++ b/matter/src/interaction_model/messages.rs @@ -76,7 +76,7 @@ pub mod msg { EventPath, }; - #[derive(FromTLV)] + #[derive(Default, FromTLV, ToTLV)] #[tlvargs(lifetime = "'a")] pub struct SubscribeReq<'a> { pub keep_subs: bool, @@ -92,6 +92,20 @@ pub mod msg { } impl<'a> SubscribeReq<'a> { + pub fn new(fabric_filtered: bool, min_int_floor: u16, max_int_ceil: u16) -> Self { + Self { + fabric_filtered, + min_int_floor, + max_int_ceil, + ..Default::default() + } + } + + pub fn set_attr_requests(mut self, requests: &'a [AttrPath]) -> Self { + self.attr_requests = Some(TLVArray::new(requests)); + self + } + pub fn to_read_req(&self) -> ReadReq<'a> { ReadReq { attr_requests: self.attr_requests, @@ -103,7 +117,7 @@ pub mod msg { } } - #[derive(ToTLV)] + #[derive(Debug, FromTLV, ToTLV)] pub struct SubscribeResp { pub subs_id: u32, // The Context Tags are discontiguous for some reason diff --git a/matter/tests/data_model/long_reads.rs b/matter/tests/data_model/long_reads.rs index a82d7b1..9f7957a 100644 --- a/matter/tests/data_model/long_reads.rs +++ b/matter/tests/data_model/long_reads.rs @@ -24,11 +24,11 @@ use matter::{ }, interaction_model::{ core::{IMStatusCode, OpCode}, - messages::GenericPath, messages::{ ib::{AttrData, AttrPath, AttrResp}, - msg::{ReadReq, ReportDataMsg, StatusResp}, + msg::{ReadReq, ReportDataMsg, StatusResp, SubscribeResp}, }, + messages::{msg::SubscribeReq, GenericPath}, }, tlv::{self, ElementType, FromTLV, TLVElement, TagType, ToTLV}, transport::{ @@ -182,3 +182,43 @@ fn test_long_read_success() { assert_eq!(report_data.more_chunks, None); assert_eq!(out_code, OpCode::ReportData as u8); } + +#[test] +fn test_long_read_subscription_success() { + // Subscribe to the entire attribute database, which requires 2 reads to complete + let _ = env_logger::try_init(); + let mut lr = LongRead::new(); + let mut output = [0_u8; MAX_RX_BUF_SIZE + 100]; + + let wc_path = GenericPath::new(None, None, None); + + let read_all = [AttrPath::new(&wc_path)]; + let subs_req = SubscribeReq::new(true, 1, 20).set_attr_requests(&read_all); + let expected_part1 = wildcard_read_resp(1); + let (out_code, out_data) = lr.process(OpCode::SubscribeRequest, &subs_req, &mut output); + let root = tlv::get_root_node_struct(out_data).unwrap(); + let report_data = ReportDataMsg::from_tlv(&root).unwrap(); + assert_attr_report_skip_data(&report_data, &expected_part1); + assert_eq!(report_data.more_chunks, Some(true)); + assert_eq!(out_code, OpCode::ReportData as u8); + + // Ask for the next read by sending a status report + let status_report = StatusResp { + status: IMStatusCode::Success, + }; + let expected_part2 = wildcard_read_resp(2); + let (out_code, out_data) = lr.process(OpCode::StatusResponse, &status_report, &mut output); + let root = tlv::get_root_node_struct(out_data).unwrap(); + let report_data = ReportDataMsg::from_tlv(&root).unwrap(); + assert_attr_report_skip_data(&report_data, &expected_part2); + assert_eq!(report_data.more_chunks, None); + assert_eq!(out_code, OpCode::ReportData as u8); + + // Finally confirm subscription + let (out_code, out_data) = lr.process(OpCode::StatusResponse, &status_report, &mut output); + tlv::print_tlv_list(out_data); + let root = tlv::get_root_node_struct(out_data).unwrap(); + let subs_resp = SubscribeResp::from_tlv(&root).unwrap(); + assert_eq!(out_code, OpCode::SubscriptResponse as u8); + assert_eq!(subs_resp.subs_id, 1); +}