@@ -129,6 +129,43 @@ pldm_completion_code! {
129129
130130#[ derive( Debug , Clone , PartialEq ) ]
131131#[ repr( C ) ]
132+ /// The total structure for QueryDownstreamIdentifiersResponse looks as follows:
133+ /// ```text
134+ /// QueryDownstreamIdentifiersResponse
135+ /// completion_code (u8)
136+ /// next_data_transfer_handle (u32)
137+ /// transfer_flag (u8)
138+ /// --- portion (variable-length)
139+ /// downstream_devices_length_i (u32)
140+ /// number_of_downstream_devices_i (u16)
141+ /// downstream_devices_index_i (u16)
142+ /// ---
143+ /// downstream_device_index_ij (u16)
144+ /// downstream_descriptor_count_ij (u8)
145+ /// ---
146+ /// descriptor_type_ijk (u16)
147+ /// descriptor_length_ijk (u16)
148+ /// descriptor_data_ijk (variable-length L_ijk)
149+ /// ...
150+ /// descriptor_type_ij(k+1) (u16)
151+ /// descriptor_length_ij(k+1) (u16)
152+ /// descriptor_data_ij(k+1) (variable-length L_ij(k+1))
153+ /// ...
154+ /// ...
155+ /// downstream_devices_index_i(j+1) (u16)
156+ /// downstream_device_count_i(j+1) (u8)
157+ /// ---
158+ /// descriptor_type_(i(j+1)k) (u16)
159+ /// descriptor_length_(i(j+1)k) (u16)
160+ /// descriptor_data_(i(j+1)k) (variable-length L_(i(j+1)k))
161+ /// ...
162+ /// ...
163+ /// downstream_devices_length_(i+1) (u32)
164+ /// number_of_downstream_devices_(i+1) (u16)
165+ /// downstream_devices_index_(i+1) (u16)
166+ /// ...
167+ /// ...
168+ /// ```
132169pub struct QueryDownstreamIdentifiersResponse < ' a > {
133170 pub hdr : PldmMsgHeader < [ u8 ; PLDM_MSG_HEADER_LEN ] > ,
134171
@@ -227,10 +264,10 @@ impl QueryDownstreamIdentifiersResponse<'_> {
227264 }
228265}
229266
230- /// Iterate over all available [DownstreamDevice] in the response portion.
231267impl < ' a > Iterator for QueryDownstreamIdentifiersResponse < ' a > {
232268 type Item = DownstreamDevice < ' a > ;
233269
270+ /// Iterate over all available [DownstreamDevice] in the response portion.
234271 fn next ( & mut self ) -> Option < Self :: Item > {
235272 let portion_hdr = self . try_get_portion_header ( ) . ok ( ) ?;
236273 if self . portion_iter_current >= portion_hdr. number_of_downstream_devices as usize {
@@ -249,14 +286,18 @@ impl<'a> Iterator for QueryDownstreamIdentifiersResponse<'a> {
249286 return None ;
250287 }
251288
252- let hdr = self
289+ let hdr: DownstreamDevicesHeader = self
253290 . try_get_downstream_device_header ( & self . portion [ offset..] )
254291 . ok ( ) ?;
255292 let device_header_size = size_of :: < DownstreamDevicesHeader > ( ) ;
256- let descriptors_size = hdr. downstream_descriptor_count as usize * size_of :: < Descriptor > ( ) ;
257- let total_device_size = device_header_size + descriptors_size;
258293
259- let next_offset = offset + total_device_size;
294+ let desc_size = Descriptor :: try_get_descriptor_length_from_blob (
295+ & self . portion [ offset + device_header_size..] ,
296+ hdr. downstream_descriptor_count as usize ,
297+ )
298+ . ok ( ) ?;
299+
300+ let next_offset = offset + device_header_size + desc_size;
260301 if next_offset > self . portion . len ( ) {
261302 self . portion_iter_current = 0 ;
262303 self . portion_offset_next = 0 ;
@@ -423,19 +464,27 @@ impl Iterator for DownstreamDevice<'_> {
423464 return None ;
424465 }
425466
426- let descriptor_size = size_of :: < Descriptor > ( ) ;
427- if self . downstream_descriptors . len ( ) < descriptor_size {
428- self . _iter_dev_count = 0 ;
429- self . _iter_offset = 0 ;
467+ // Read the descriptor length while skipping the type field
468+ let descriptor_length = u16:: read_from_bytes (
469+ & self . downstream_descriptors
470+ [ self . _iter_offset + size_of :: < u16 > ( ) ..self . _iter_offset + size_of :: < u16 > ( ) * 2 ] ,
471+ )
472+ . ok ( ) ? as usize ;
473+
474+ // check bounds
475+ if self . _iter_offset + size_of :: < u16 > ( ) * 2 + descriptor_length
476+ > self . downstream_descriptors . len ( )
477+ {
430478 return None ;
431479 }
432480
433- let descriptor = Descriptor :: try_read_from_prefix (
434- & self . downstream_descriptors [ self . _iter_offset ..self . _iter_offset + descriptor_size] ,
481+ let descriptor = Descriptor :: decode (
482+ & self . downstream_descriptors
483+ [ self . _iter_offset ..self . _iter_offset + 2 * size_of :: < u16 > ( ) + descriptor_length] ,
435484 )
436- . ok ( ) ?
437- . 0 ;
438- self . _iter_offset += descriptor_size ;
485+ . ok ( ) ?;
486+
487+ self . _iter_offset += size_of :: < u16 > ( ) * 2 + descriptor_length ;
439488 self . _iter_dev_count += 1 ;
440489
441490 Some ( descriptor)
@@ -1141,7 +1190,7 @@ impl RequestDownstreamDeviceUpdateResponse {
11411190#[ cfg( test) ]
11421191mod tests {
11431192 use super :: * ;
1144- use crate :: codec:: PldmCodec ;
1193+ use crate :: { codec:: PldmCodec , protocol :: firmware_update :: DescriptorType } ;
11451194
11461195 #[ test]
11471196 fn test_query_downstream_devices_request_codec ( ) {
@@ -1389,15 +1438,18 @@ mod tests {
13891438 let descriptors: [ Descriptor ; 3 ] = [ descriptor. clone ( ) , descriptor. clone ( ) , descriptor] ;
13901439
13911440 const DESC_LEN : usize = size_of :: < Descriptor > ( ) ;
1392- let mut descriptor_bytes : [ u8 ; DESC_LEN * 3 ] = [ 0u8 ; DESC_LEN * 3 ] ;
1441+ let mut descriptor_bytes_max : [ u8 ; DESC_LEN * 3 ] = [ 0u8 ; DESC_LEN * 3 ] ;
13931442 let mut offset = 0 ;
1443+
1444+ // encoding
13941445 for desc in descriptors. iter ( ) {
1395- descriptor_bytes [ offset..offset + DESC_LEN ] . copy_from_slice ( & desc . as_bytes ( ) ) ;
1396- offset += DESC_LEN ;
1446+ let encoded = desc . encode ( & mut descriptor_bytes_max [ offset.. ] ) . unwrap ( ) ;
1447+ offset += encoded ;
13971448 }
13981449
13991450 let downstream_device_index = DownstreamDeviceIndex :: try_from ( 1 ) . unwrap ( ) ;
1400- let downstream_device = DownstreamDevice :: new ( downstream_device_index, & descriptor_bytes) ;
1451+ let downstream_device =
1452+ DownstreamDevice :: new ( downstream_device_index, & descriptor_bytes_max) ;
14011453
14021454 let mut buffer = [ 0u8 ; 256 ] ;
14031455 let bytes_written = downstream_device. encode ( & mut buffer) . unwrap ( ) ;
@@ -1407,6 +1459,7 @@ mod tests {
14071459
14081460 #[ test]
14091461 fn test_iterator_query_downstream_identifiers_response ( ) {
1462+ const DSC_DATA_LEN : usize = 16 ;
14101463 let instance_id: InstanceId = 0x01 ;
14111464 let ph: PortionHeader = PortionHeader {
14121465 downstream_devices_length : 1 ,
@@ -1417,22 +1470,21 @@ mod tests {
14171470 downstream_descriptor_count : 3 ,
14181471 } ;
14191472 let dsc_0: Descriptor = Descriptor {
1420- descriptor_type : 0xff ,
1421- descriptor_length : 0x02 ,
1473+ descriptor_type : DescriptorType :: VendorDefined as u16 ,
1474+ descriptor_length : DSC_DATA_LEN as u16 ,
14221475 descriptor_data : [ 0u8 ; 64 ] ,
14231476 } ;
14241477
14251478 let mut dsc_1 = dsc_0. clone ( ) ;
1426- dsc_1. descriptor_type = 0xfe ;
1427- dsc_1. descriptor_data = [ 1u8 ; 64 ] ;
1479+ dsc_1. descriptor_data [ 0 ..16 ] . clone_from_slice ( & [ 1u8 ; 16 ] ) ;
14281480
14291481 let mut dsc_2 = dsc_0. clone ( ) ;
1430- dsc_2. descriptor_type = 0xfd ;
1431- dsc_2. descriptor_data = [ 2u8 ; 64 ] ;
1482+ dsc_2. descriptor_data [ 0 ..16 ] . clone_from_slice ( & [ 2u8 ; 16 ] ) ;
14321483
14331484 const LEN : usize = size_of :: < PortionHeader > ( )
14341485 + size_of :: < DownstreamDevicesHeader > ( )
1435- + 3 * size_of :: < Descriptor > ( ) ;
1486+ + 3 * ( 2 * size_of :: < u16 > ( ) + DSC_DATA_LEN ) ; // type + length + data
1487+
14361488 let mut offset = 0 ;
14371489 let mut portion: [ u8 ; LEN ] = [ 0u8 ; LEN ] ;
14381490
@@ -1443,13 +1495,10 @@ mod tests {
14431495 . copy_from_slice ( & dsdh. as_bytes ( ) ) ;
14441496 offset += size_of :: < DownstreamDevicesHeader > ( ) ;
14451497
1446- portion[ offset..offset + size_of :: < Descriptor > ( ) ] . copy_from_slice ( & dsc_0. as_bytes ( ) ) ;
1447- offset += size_of :: < Descriptor > ( ) ;
1448-
1449- portion[ offset..offset + size_of :: < Descriptor > ( ) ] . copy_from_slice ( & dsc_1. as_bytes ( ) ) ;
1450- offset += size_of :: < Descriptor > ( ) ;
1451-
1452- portion[ offset..offset + size_of :: < Descriptor > ( ) ] . copy_from_slice ( & dsc_2. as_bytes ( ) ) ;
1498+ for desc in [ dsc_0. clone ( ) , dsc_1. clone ( ) , dsc_2. clone ( ) ] . iter ( ) {
1499+ let size = & desc. encode ( & mut portion[ offset..] ) . unwrap ( ) ;
1500+ offset += size;
1501+ }
14531502
14541503 let mut qdir = QueryDownstreamIdentifiersResponse :: new (
14551504 instance_id,
0 commit comments