@@ -4,6 +4,9 @@ use crate::commands::measurements_rsp::MeasurementsResponse;
44
55#[ derive( Debug , PartialEq ) ]
66pub enum ChunkError {
7+ /// Super hacky way to signal back the client application via [CommandError::Chunk(ChunkError::None)]
8+ /// that the chunking process has started and that it now has to retrieve the chunked data.
9+ None ,
710 LargeResponseInitError ,
811 NoLargeResponseInProgress ,
912 InvalidChunkHandle ,
@@ -22,6 +25,11 @@ struct ChunkInfo {
2225}
2326
2427impl ChunkInfo {
28+ /// Reset the chunk info.
29+ ///
30+ /// # Arguments
31+ /// - `reset_handle`: If `reset_handle` is set, the handle of the chunk info
32+ /// is set to `0`. If not, it is incremented to be ready for the next chunk operation.
2533 pub fn reset ( & mut self , reset_handle : bool ) {
2634 self . chunk_in_use = false ;
2735 if reset_handle {
@@ -52,7 +60,18 @@ pub(crate) enum LargeResponse {
5260 Measurements ( MeasurementsResponse ) ,
5361}
5462
55- /// Manages the context for ongoing large message responses
63+ /// Manages the context for ongoing large message responses.
64+ /// The naming might be confusion, but we re-use this struct for both requester and responder.
65+ ///
66+ /// # Requester
67+ ///
68+ /// For the requester, this [LargeResponseCtx] is used to track the state
69+ /// of `CHUNK_SEND` commands.
70+ ///
71+ /// # Responder
72+ ///
73+ /// For the responder, this [LargeResponseCtx] is used to track the state
74+ /// of `CHUNK_RESPONSE` commands.
5675#[ derive( Default ) ]
5776pub ( crate ) struct LargeResponseCtx {
5877 chunk_info : ChunkInfo ,
@@ -115,4 +134,82 @@ impl LargeResponseCtx {
115134 pub fn bytes_transferred ( & self ) -> usize {
116135 self . chunk_info . bytes_transferred
117136 }
137+
138+ pub fn seq_no ( & self ) -> u16 {
139+ self . chunk_info . chunk_seq_num
140+ }
141+
142+ pub fn handle ( & self ) -> u8 {
143+ self . chunk_info . chunk_handle
144+ }
145+ }
146+
147+ /// Manages the context for ongoing large message retrievals on the **requester** side.
148+ ///
149+ /// Initialized when the requester receives `ERROR(LargeResponse)` and tracks
150+ /// progress across successive `CHUNK_GET` / `CHUNK_RESPONSE` exchanges until
151+ /// the last chunk has been received.
152+ #[ derive( Default ) ]
153+ pub ( crate ) struct LargeRequestCtx {
154+ chunk_info : ChunkInfo ,
155+ }
156+
157+ impl LargeRequestCtx {
158+ /// Initialize context for a new large response retrieval.
159+ ///
160+ /// Call this when `ERROR(LargeResponse)` is received.
161+ ///
162+ /// # Arguments
163+ /// * `handle` - The handle value carried in `Param2` of the `ERROR` message.
164+ pub ( crate ) fn init ( & mut self , handle : u8 ) {
165+ // Total size is unknown until the first CHUNK_RESPONSE arrives.
166+ self . chunk_info . init ( 0 , Some ( handle) ) ;
167+ }
168+
169+ /// Discard any in-progress retrieval and reset to the initial state.
170+ pub ( crate ) fn reset ( & mut self ) {
171+ self . chunk_info . reset ( true ) ;
172+ }
173+
174+ /// Returns `true` if a large response retrieval is currently in progress.
175+ pub ( crate ) fn in_progress ( & self ) -> bool {
176+ self . chunk_info . chunk_in_use
177+ }
178+
179+ /// Returns the handle identifying the current large response transfer.
180+ pub ( crate ) fn handle ( & self ) -> u8 {
181+ self . chunk_info . chunk_handle
182+ }
183+
184+ /// Returns the `ChunkSeqNo` that shall appear in the next `CHUNK_GET`.
185+ pub ( crate ) fn current_seq_num ( & self ) -> u16 {
186+ self . chunk_info . chunk_seq_num
187+ }
188+
189+ /// Returns the number of bytes successfully received so far.
190+ pub ( crate ) fn bytes_received ( & self ) -> usize {
191+ self . chunk_info . bytes_transferred
192+ }
193+
194+ /// Returns the total size of the large response.
195+ ///
196+ /// Only meaningful after the first `CHUNK_RESPONSE` (`ChunkSeqNo == 0`)
197+ /// has been processed and [`set_total_size`] has been called.
198+ pub ( crate ) fn total_size ( & self ) -> usize {
199+ self . chunk_info . large_msg_size
200+ }
201+
202+ /// Record the total response size decoded from the first `CHUNK_RESPONSE`.
203+ pub ( crate ) fn set_total_size ( & mut self , size : usize ) {
204+ self . chunk_info . large_msg_size = size;
205+ }
206+
207+ /// Advance tracking state after a chunk has been successfully received.
208+ ///
209+ /// Adds `chunk_size` to `bytes_received` and bumps the sequence number so
210+ /// that the next `CHUNK_GET` requests the following chunk.
211+ pub ( crate ) fn advance ( & mut self , chunk_size : usize ) {
212+ self . chunk_info . bytes_transferred += chunk_size;
213+ self . chunk_info . chunk_seq_num = self . chunk_info . chunk_seq_num . wrapping_add ( 1 ) ;
214+ }
118215}
0 commit comments