Skip to main content

ri/protocol/
frames.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of Ri.
4//! The Ri project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18#![allow(non_snake_case)]
19
20//! # Protocol Frame Format Module
21//!
22//! This module implements the real protocol frame format with serialization,
23//! checksums, and frame integrity verification for the Ri private protocol.
24
25use std::convert::TryInto;
26use serde::{Deserialize, Serialize};
27use crc32fast::Hasher;
28
29use crate::core::{RiResult, RiError};
30
31/// Protocol frame type enumeration defining the categories of protocol frames.
32///
33/// This enumeration classifies all protocol frames used in the Ri protocol
34/// for network communication. Each frame type serves a specific purpose in
35/// the communication lifecycle, from initial connection establishment through
36/// data transmission, authentication, and connection maintenance. Frame type
37/// identification enables proper routing and processing of incoming frames
38/// by protocol handlers.
39///
40/// ## Frame Type Hierarchy
41///
42/// - **Control Frames (0x01)**: Protocol management and state transitions
43/// - **Data Frames (0x02)**: Application data payload transmission
44/// - **Auth Frames (0x03)**: Authentication and authorization exchanges
45/// - **Keep-Alive Frames (0x04)**: Connection liveness verification
46/// - **Error Frames (0x05)**: Error reporting and status communication
47/// - **Encrypted Frames (0x06)**: Pre-encrypted payload transmission
48///
49/// ## Frame Processing Guidelines
50///
51/// Protocol implementations should process frames in the following order:
52/// 1. First validate the frame header magic number and version
53/// 2. Extract and validate the frame type from the header
54/// 3. Route the frame to the appropriate handler based on frame type
55/// 4. Process the frame payload according to type-specific rules
56/// 5. Send appropriate response frames if required
57///
58/// ## Python Bindings
59///
60/// When compiled with the `pyo3` feature, this enum provides Python bindings
61/// for frame type identification:
62/// ```python
63/// from ri import RiFrameType
64///
65/// # Identify frame types for protocol handling
66/// control_type = RiFrameType.Control()
67/// data_type = RiFrameType.Data()
68/// auth_type = RiFrameType.Auth()
69///
70/// # Convert between types and byte values
71/// frame_type_value = RiFrameType.from_u8(0x01)
72/// byte_value = data_type.to_u8()  # Returns 0x02
73/// ```
74///
75/// ## Thread Safety
76///
77/// This enum is fully thread-safe and can be shared across concurrent contexts
78/// without additional synchronization. The Copy trait enables efficient passing
79/// of frame type values through function arguments and return types.
80///
81/// ## Storage and Transmission
82///
83/// Frame type values are stored as single bytes making them efficient for network
84/// transmission and compact storage. The Hash trait enables frame type usage as
85/// dictionary keys in collection types and provides efficient lookup performance.
86///
87/// # Examples
88///
89/// Basic frame type creation and conversion:
90/// ```rust,ignore
91/// use ri::protocol::frames::RiFrameType;
92///
93/// let control = RiFrameType::Control;
94/// let data = RiFrameType::Data;
95///
96/// assert_eq!(control as u8, 0x01);
97/// assert_eq!(data as u8, 0x02);
98/// assert_ne!(control, data);
99/// ```
100///
101/// Frame type matching in protocol handling:
102/// ```rust,ignore
103/// use ri::protocol::frames::RiFrameType;
104///
105/// fn handle_frame_type(frame_type: RiFrameType) -> &str {
106///     match frame_type {
107///         RiFrameType::Control => "Control frame - managing protocol state",
108///         RiFrameType::Data => "Data frame - processing payload",
109///         RiFrameType::Auth => "Auth frame - handling authentication",
110///         RiFrameType::KeepAlive => "Keep-alive frame - verifying connection",
111///         RiFrameType::Error => "Error frame - reporting error condition",
112///         RiFrameType::Encrypted => "Encrypted frame - processing secure payload",
113///     }
114/// }
115///
116/// assert_eq!(handle_frame_type(RiFrameType::Data), "Data frame - processing payload");
117/// ```
118///
119/// Converting between byte values and frame types:
120/// ```rust,ignore
121/// use ri::protocol::frames::RiFrameType;
122///
123/// // Convert byte to frame type
124/// let frame_type = RiFrameType::from_u8(0x03);
125/// assert_eq!(frame_type, Some(RiFrameType::Auth));
126///
127/// // Invalid byte value returns None
128/// let invalid = RiFrameType::from_u8(0xFF);
129/// assert_eq!(invalid, None);
130/// ```
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
132#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
133pub enum RiFrameType {
134    /// Control frame for protocol management operations.
135    ///
136    /// Control frames manage the protocol state machine and handle connection
137    /// lifecycle events. They are used for operations such as connection
138    /// initialization, version negotiation, feature flags exchange, and graceful
139    /// connection termination. Control frames must be processed before any data
140    /// frames to ensure proper protocol state establishment.
141    ///
142    /// ## Control Frame Payload Structure
143    ///
144    /// Control frame payloads contain a command identifier followed by
145    /// command-specific parameters encoded in a type-length-value (TLV) format.
146    ///
147    /// ## Common Control Commands
148    ///
149    /// - **Connection Request (0x01)**: Initiate new connection
150    /// - **Connection Ack (0x02)**: Confirm connection establishment
151    /// - **Disconnect Request (0x03)**: Initiate graceful disconnection
152    /// - **Ping (0x04)**: Request keep-alive response
153    /// - **Pong (0x05)**: Keep-alive response
154    /// - **Protocol Negotiation (0x10)**: Negotiate protocol features
155    Control = 0x01,
156
157    /// Data frame for application payload transmission.
158    ///
159    /// Data frames carry the primary application data through the protocol.
160    /// They are the most frequently used frame type in normal protocol operation
161    /// and support both streaming and message-based data transfer modes. Data
162    /// frames are sequenced and delivered in-order to ensure data integrity.
163    ///
164    /// ## Data Frame Characteristics
165    ///
166    /// - **Sequencing**: Each data frame has a unique sequence number
167    /// - **Ordering**: Frames are delivered in sequence number order
168    /// - **Flow Control**: Sliding window prevents buffer overflow
169    /// - **Aggregation**: Multiple small payloads can be aggregated
170    ///
171    /// ## Payload Considerations
172    ///
173    /// - Maximum payload size is defined by protocol configuration
174    /// - Large payloads may be fragmented across multiple frames
175    /// - Payload compression is available as an optional feature
176    Data = 0x02,
177
178    /// Authentication frame for credential exchange and verification.
179    ///
180    /// Authentication frames facilitate the authentication process between
181    /// communicating parties. They carry authentication tokens, certificates,
182    /// challenge-response pairs, and authentication results. All auth frames
183    /// are encrypted using the current session encryption keys.
184    ///
185    /// ## Authentication Flow
186    ///
187    /// 1. Client sends authentication request with credentials
188    /// 2. Server validates credentials and returns challenge
189    /// 3. Client responds to challenge with proof of possession
190    /// 4. Server confirms successful authentication
191    ///
192    /// ## Supported Authentication Methods
193    ///
194    /// - JWT token authentication
195    /// - Certificate-based mutual TLS
196    /// - Pre-shared key authentication
197    /// - OAuth 2.0 token exchange
198    Auth = 0x03,
199
200    /// Keep-alive frame for connection liveness verification.
201    ///
202    /// Keep-alive frames maintain connection vitality and detect unresponsive
203    /// peers. They are exchanged periodically between connected parties to
204    /// prevent connection timeout and detect connection failures. Keep-alive
205    /// frames have minimal overhead and contain no payload.
206    ///
207    KeepAlive = 0x04,
208
209    /// Error frame for error condition reporting.
210    ///
211    /// Error frames communicate error conditions from one protocol party to
212    /// another. They include an error code and human-readable error message
213    /// to facilitate debugging and error recovery. Error frames may be sent
214    /// in response to any invalid protocol message.
215    ///
216    Error = 0x05,
217
218    /// Encrypted frame for pre-encrypted payload transmission.
219    ///
220    /// Encrypted frames carry payloads that have been encrypted by the
221    /// application layer before being passed to the protocol. This allows
222    /// applications to use custom encryption schemes or to encrypt data
223    /// end-to-end between application endpoints. The protocol encrypts the
224    /// encrypted payload as normal data.
225    ///
226    /// ## Use Cases
227    ///
228    /// - End-to-end encrypted application data
229    /// - Custom encryption algorithm requirements
230    /// - Regulatory compliance requiring specific encryption
231    /// - Integration with external encryption systems
232    ///
233    /// ## Security Considerations
234    ///
235    /// When using encrypted frames, the outer protocol encryption provides
236    /// transport security while the inner encrypted payload provides
237    /// end-to-end security between application endpoints.
238    Encrypted = 0x06,
239}
240
241impl RiFrameType {
242    /// Convert from byte to frame type
243    pub fn from_u8(value: u8) -> Option<Self> {
244        match value {
245            0x01 => Some(RiFrameType::Control),
246            0x02 => Some(RiFrameType::Data),
247            0x03 => Some(RiFrameType::Auth),
248            0x04 => Some(RiFrameType::KeepAlive),
249            0x05 => Some(RiFrameType::Error),
250            0x06 => Some(RiFrameType::Encrypted),
251            _ => None,
252        }
253    }
254}
255
256/// Protocol frame header structure containing metadata for frame processing.
257///
258/// The frame header provides essential protocol metadata required for proper
259/// frame handling, transmission, and verification. It follows a fixed 32-byte
260/// format designed for efficient parsing and minimal overhead while maintaining
261/// comprehensive protocol information. All fields use big-endian byte ordering
262/// for consistent network transmission.
263///
264/// ## Header Field Layout
265///
266/// | Offset | Size | Field          | Description                              |
267/// |--------|------|----------------|------------------------------------------|
268/// | 0      | 4    | magic          | Protocol magic number (0x444D5350)       |
269/// | 4      | 1    | frame_type     | Frame type identifier (0x01-0x06)        |
270/// | 5      | 1    | version        | Protocol version (0x01)                  |
271/// | 6      | 2    | flags          | Protocol flags for special handling      |
272/// | 8      | 4    | payload_length | Length of frame payload in bytes         |
273/// | 12     | 4    | sequence_number| Frame sequence number for ordering       |
274/// | 16     | 8    | timestamp      | Unix timestamp of frame creation         |
275/// | 24     | 4    | checksum       | CRC32 checksum for integrity verification|
276///
277/// ## Byte Ordering
278///
279/// All multi-byte fields use big-endian (network byte order) encoding to ensure
280/// consistent interpretation across different architectures and platforms.
281/// When serializing or deserializing, use the provided `to_bytes()` and
282/// `from_bytes()` methods to ensure proper byte ordering.
283///
284/// ## Magic Number Validation
285///
286/// The magic number `0x444D5350` decodes to ASCII "DMSP" (Ri Protocol) and
287/// serves as a quick validation that incoming data represents a valid Ri
288/// frame. Receiving a frame with an invalid magic number indicates either
289/// protocol mismatch or data corruption.
290///
291/// ## Python Bindings
292///
293/// When compiled with the `pyo3` feature, this struct provides Python bindings:
294/// ```python
295/// from ri import RiFrameHeader
296///
297/// # Create new header for a data frame
298/// header = RiFrameHeader.new(
299///     frame_type=RiFrameHeader.FrameType.Data,
300///     payload_length=1024,
301///     sequence_number=42
302/// )
303///
304/// # Serialize to bytes for transmission
305/// header_bytes = header.to_bytes()
306///
307/// # Access header fields
308/// print(f"Frame type: {header.frame_type}")
309/// print(f"Payload length: {header.payload_length}")
310/// print(f"Sequence: {header.sequence_number}")
311/// print(f"Timestamp: {header.timestamp}")
312/// ```
313///
314/// # Examples
315///
316/// Creating a new frame header:
317/// ```rust,ignore
318/// use ri::protocol::frames::{RiFrameHeader, RiFrameType};
319///
320/// let header = RiFrameHeader::new(
321///     RiFrameType::Data,
322///     1024,           // payload length
323///     42              // sequence number
324/// ).expect("Failed to create frame header");
325///
326/// assert_eq!(header.magic, RiFrameHeader::MAGIC);
327/// assert_eq!(header.version, RiFrameHeader::VERSION);
328/// assert_eq!(header.frame_type, RiFrameType::Data as u8);
329/// ```
330///
331/// Serializing and deserializing headers:
332/// ```rust,ignore
333/// use ri::protocol::frames::{RiFrameHeader, RiFrameType};
334///
335/// let header = RiFrameHeader::new(
336///     RiFrameType::Control,
337///     256,
338///     100
339/// ).expect("Failed to create header");
340///
341/// let bytes = header.to_bytes();
342/// assert_eq!(bytes.len(), 32);
343///
344/// let reconstructed = RiFrameHeader::from_bytes(&bytes)
345///     .expect("Failed to parse header");
346///
347/// assert_eq!(header.magic, reconstructed.magic);
348/// assert_eq!(header.frame_type, reconstructed.frame_type);
349/// assert_eq!(header.sequence_number, reconstructed.sequence_number);
350/// ```
351///
352/// Verifying frame integrity:
353/// ```rust,ignore
354/// use ri::protocol::frames::{RiFrameHeader, RiFrameType};
355///
356/// let header = RiFrameHeader::new(
357///     RiFrameType::Data,
358///     512,
359///     200
360/// ).expect("Failed to create header");
361///
362/// let payload = b"This is the frame payload data";
363///
364/// let is_valid = header.verify_checksum(payload);
365/// assert!(is_valid);
366///
367/// // Modify payload and verify again
368/// let modified_payload = b"This payload has been modified!";
369/// let is_valid_modified = header.verify_checksum(modified_payload);
370/// assert!(!is_valid_modified);
371/// ```
372#[derive(Debug, Clone, Serialize, Deserialize)]
373#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
374pub struct RiFrameHeader {
375    /// Frame magic number identifying the Ri protocol (4 bytes).
376    ///
377    /// The magic number is a 32-bit constant that uniquely identifies Ri
378    /// protocol frames. It serves as a quick validation mechanism to detect
379    /// non-Ri data or protocol version mismatches. The value 0x444D5350
380    /// corresponds to the ASCII encoding of "DMSP" (Ri Protocol).
381    ///
382    /// ## Magic Number Details
383    ///
384    /// - **Value**: 0x444D5350
385    /// - **ASCII**: "DMSP"
386    /// - **Purpose**: Protocol identification
387    /// - **Validation**: Must match exactly on all received frames
388    ///
389    /// ## Usage
390    ///
391    /// The magic number is the first field in the frame header and should be
392    /// validated immediately upon receiving frame data. A mismatch indicates
393    /// either incorrect data or a protocol version incompatibility.
394    pub magic: u32,
395
396    /// Frame type identifier determining frame processing (1 byte).
397    ///
398    /// The frame type specifies how the frame payload should be interpreted
399    /// and processed. This 8-bit field identifies one of six possible frame
400    /// types defined in the RiFrameType enumeration.
401    pub frame_type: u8,
402
403    /// Protocol version for compatibility checking (1 byte).
404    ///
405    /// The version field enables protocol evolution while maintaining backward
406    /// compatibility. The current version is 0x01. Protocol implementations
407    /// should reject frames with unsupported versions.
408    pub version: u8,
409
410    /// Protocol flags for special frame handling (2 bytes).
411    ///
412    /// Flags provide additional processing instructions for frames. Common
413    /// flags include compression, priority, and streaming indicators.
414    ///
415    /// ## Flag Definitions
416    ///
417    /// - **Bit 0**: Compressed - Payload is compressed
418    /// - **Bit 1**: Priority - High priority frame
419    /// - **Bit 2**: Streaming - Part of streaming transfer
420    /// - **Bit 3**: Fragmented - Part of fragmented message
421    /// - **Bits 4-15**: Reserved for future use
422    pub flags: u16,
423
424    /// Length of the frame payload in bytes (4 bytes).
425    ///
426    /// This field specifies the exact number of bytes in the frame payload.
427    /// It enables proper memory allocation and bounds checking during frame
428    /// processing. The maximum payload length is 4GB.
429    pub payload_length: u32,
430
431    /// Frame sequence number for ordering and reliability (4 bytes).
432    ///
433    /// Sequence numbers enable in-order delivery, duplicate detection, and
434    /// loss detection for protocol frames. Each frame in a connection uses
435    /// a monotonically increasing sequence number with wraparound at 2^32.
436    ///
437    /// ## Sequence Number Semantics
438    ///
439    /// - **Initialization**: Sequence numbers start at 0 for new connections
440    /// - **Increment**: Each frame increments the sequence number by 1
441    /// - **Wraparound**: Sequence numbers wrap from 0xFFFFFFFF to 0
442    /// - **Ordering**: Receivers use sequence numbers to order frames
443    pub sequence_number: u32,
444
445    /// Unix timestamp of frame creation in seconds (8 bytes).
446    ///
447    /// The timestamp records when the frame was created, enabling temporal
448    /// validation, replay detection, and latency measurements. Timestamps
449    /// use seconds since Unix epoch (1970-01-01 00:00:00 UTC).
450    ///
451    /// ## Timestamp Considerations
452    ///
453    /// - **Precision**: Second-level precision (not milliseconds)
454    /// - **Clock Sync**: Requires loosely synchronized clocks
455    /// - **Replay Protection**: Used in conjunction with nonces
456    /// - **Age Limits**: Frames older than timeout are rejected
457    pub timestamp: u64,
458
459    /// CRC32 checksum for frame integrity verification (4 bytes).
460    ///
461    /// The checksum covers all header fields (except checksum itself) and
462    /// the complete frame payload. It enables detection of transmission
463    /// errors and data corruption. Uses the CRC32 algorithm with polynomial
464    /// 0x04C11DB7 (IEEE 802.3).
465    ///
466    /// ## Checksum Calculation
467    ///
468    /// The checksum is computed over the concatenation of all header fields
469    /// (excluding the checksum field) followed by the frame payload. This
470    /// provides comprehensive protection against single-bit errors and
471    /// many burst errors.
472    ///
473    /// ## Limitations
474    ///
475    /// CRC32 provides error detection but not error correction. It can detect
476    /// all single-bit errors, most double-bit errors, and many burst errors
477    /// up to 32 bits in length. It does not provide cryptographic integrity.
478    pub checksum: u32,
479}
480
481impl RiFrameHeader {
482    /// Frame magic number constant for protocol identification.
483    ///
484    /// This 32-bit constant uniquely identifies Ri protocol frames. The value
485    /// 0x444D5350 corresponds to the ASCII encoding of "DMSP" (Ri Protocol).
486    /// This magic number is placed at the beginning of every frame header and
487    /// is validated upon frame receipt to confirm protocol compatibility.
488    ///
489    /// ## Magic Number Details
490    ///
491    /// - **Hex Value**: 0x444D5350
492    /// - **ASCII Representation**: "DMSP"
493    /// - **Purpose**: Quick protocol identification
494    /// - **Validation**: Must match on all received frames
495    ///
496    /// ## Usage in Frame Processing
497    ///
498    /// When receiving frame data, the magic number should be validated first
499    /// before attempting to parse other header fields. A mismatch indicates:
500    
501    /// Maximum payload length (10 MB) to prevent memory exhaustion attacks.
502    /// This limit prevents attackers from sending frames with extremely large
503    /// payload_length values that could exhaust server memory.
504    pub const MAX_PAYLOAD_LENGTH: u32 = 10 * 1024 * 1024;
505    ///
506    /// 1. The received data is not a Ri frame
507    /// 2. Data corruption may have occurred
508    /// 3. The remote endpoint may be using a different protocol
509    pub const MAGIC: u32 = 0x444D5350; // "RiP" in ASCII
510    
511    /// Current protocol version identifier.
512    ///
513    /// This version number enables protocol evolution while maintaining backward
514    /// compatibility. The current version is 0x01. Future protocol enhancements
515    /// may increment this version while maintaining support for earlier versions.
516    ///
517    /// ## Version Semantics
518    ///
519    /// - **Major Version Changes**: May introduce incompatible changes
520    /// - **Minor Version Changes**: Backward-compatible enhancements
521    /// - **Current Value**: 0x01 (initial protocol version)
522    ///
523    /// ## Version Negotiation
524    ///
525    /// During connection establishment, endpoints should negotiate a compatible
526    /// protocol version. Frames with unsupported versions should be rejected
527    /// with an appropriate error response.
528    pub const VERSION: u8 = 0x01;
529    
530    /// Create a new frame header
531    pub fn new(frame_type: RiFrameType, payload_length: u32, sequence_number: u32) -> RiResult<Self> {
532        let timestamp = std::time::SystemTime::now()
533            .duration_since(std::time::UNIX_EPOCH)
534            .map_err(|e| RiError::InvalidState(format!("System time error: {}", e)))?
535            .as_secs();
536            
537        Ok(Self {
538            magic: Self::MAGIC,
539            frame_type: frame_type as u8,
540            version: Self::VERSION,
541            flags: 0,
542            payload_length,
543            sequence_number,
544            timestamp,
545            checksum: 0, // Will be calculated later
546        })
547    }
548    
549    /// Calculate CRC32 checksum for the header and payload
550    pub fn calculate_checksum(&self, payload: &[u8]) -> u32 {
551        let mut hasher = Hasher::new();
552        
553        // Add header fields (excluding checksum)
554        hasher.update(&self.magic.to_be_bytes());
555        hasher.update(&self.frame_type.to_be_bytes());
556        hasher.update(&self.version.to_be_bytes());
557        hasher.update(&self.flags.to_be_bytes());
558        hasher.update(&self.payload_length.to_be_bytes());
559        hasher.update(&self.sequence_number.to_be_bytes());
560        hasher.update(&self.timestamp.to_be_bytes());
561        
562        // Add payload
563        hasher.update(payload);
564        
565        hasher.finalize()
566    }
567    
568    /// Verify the checksum
569    pub fn verify_checksum(&self, payload: &[u8]) -> bool {
570        self.checksum == self.calculate_checksum(payload)
571    }
572    
573    /// Serialize header to bytes
574    pub fn to_bytes(&self) -> Vec<u8> {
575        let mut bytes = Vec::with_capacity(32);
576        
577        bytes.extend_from_slice(&self.magic.to_be_bytes());
578        bytes.extend_from_slice(&self.frame_type.to_be_bytes());
579        bytes.extend_from_slice(&self.version.to_be_bytes());
580        bytes.extend_from_slice(&self.flags.to_be_bytes());
581        bytes.extend_from_slice(&self.payload_length.to_be_bytes());
582        bytes.extend_from_slice(&self.sequence_number.to_be_bytes());
583        bytes.extend_from_slice(&self.timestamp.to_be_bytes());
584        bytes.extend_from_slice(&self.checksum.to_be_bytes());
585        
586        bytes
587    }
588    
589    /// Deserialize header from bytes
590    pub fn from_bytes(bytes: &[u8]) -> RiResult<Self> {
591        if bytes.len() < 32 {
592            return Err(RiError::FrameError("Invalid header length".to_string()));
593        }
594        
595        let magic = u32::from_be_bytes(bytes[0..4].try_into()
596            .map_err(|_| RiError::FrameError("Invalid magic number bytes".to_string()))?);
597        let frame_type = bytes[4];
598        let version = bytes[5];
599        let flags = u16::from_be_bytes(bytes[6..8].try_into()
600            .map_err(|_| RiError::FrameError("Invalid flags bytes".to_string()))?);
601        let payload_length = u32::from_be_bytes(bytes[8..12].try_into()
602            .map_err(|_| RiError::FrameError("Invalid payload length bytes".to_string()))?);
603        let sequence_number = u32::from_be_bytes(bytes[12..16].try_into()
604            .map_err(|_| RiError::FrameError("Invalid sequence number bytes".to_string()))?);
605        let timestamp = u64::from_be_bytes(bytes[16..24].try_into()
606            .map_err(|_| RiError::FrameError("Invalid timestamp bytes".to_string()))?);
607        let checksum = u32::from_be_bytes(bytes[24..28].try_into()
608            .map_err(|_| RiError::FrameError("Invalid checksum bytes".to_string()))?);
609        
610        Ok(Self {
611            magic,
612            frame_type,
613            version,
614            flags,
615            payload_length,
616            sequence_number,
617            timestamp,
618            checksum,
619        })
620    }
621}
622
623/// Complete protocol frame combining header and payload data.
624///
625/// A RiFrame represents the fundamental unit of data transmission in the
626/// Ri protocol. Each frame consists of a fixed 32-byte header containing
627/// protocol metadata and a variable-length payload containing the actual
628/// application data. Frames are serialized for network transmission and
629/// deserialized upon receipt using CRC32 checksums for integrity verification.
630///
631/// ## Frame Structure
632///
633/// ```
634/// +------------------+-------------------+
635/// |   Header (32B)   |  Payload (VAR)    |
636/// +------------------+-------------------+
637/// | magic | type | v | flags | len | seq |
638/// |      timestamp     |    checksum     |
639/// +------------------+-------------------+
640/// ```
641///
642/// ## Frame Lifecycle
643///
644/// 1. **Creation**: Construct a frame using `new()` or one of the convenience
645///    constructors (`data_frame()`, `control_frame()`, etc.)
646/// 2. **Serialization**: Convert to bytes using `to_bytes()` for transmission
647/// 3. **Transmission**: Send bytes over the network connection
648/// 4. **Reception**: Receive bytes and add to frame parser buffer
649/// 5. **Deserialization**: Parse bytes back to frame using `from_bytes()`
650/// 6. **Processing**: Handle the frame based on its type
651///
652/// ## Frame Validity
653///
654/// A frame is considered valid when:
655/// - The magic number matches the Ri protocol identifier
656/// - The protocol version is supported
657/// - The CRC32 checksum matches the computed checksum
658/// - The payload length matches the actual payload size
659///
660/// Use the `is_valid()` method for quick validation checking.
661///
662/// ## Python Bindings
663///
664/// When compiled with the `pyo3` feature, this struct provides Python bindings:
665/// ```python
666/// from ri import RiFrame, RiFrameType
667///
668/// # Create a data frame
669/// frame = RiFrame.data_frame(
670///     data=b"Hello, Ri Protocol!",
671///     sequence_number=1
672/// )
673///
674/// # Serialize for transmission
675/// frame_bytes = frame.to_bytes()
676/// print(f"Frame size: {len(frame_bytes)} bytes")
677///
678/// # Access frame properties
679/// print(f"Frame type: {frame.frame_type()}")
680/// print(f"Sequence: {frame.sequence_number()}")
681/// print(f"Timestamp: {frame.timestamp()}")
682/// print(f"Valid: {frame.is_valid()}")
683///
684/// # Deserialize received frame
685/// received = RiFrame.from_bytes(frame_bytes)
686/// assert received.payload == b"Hello, Ri Protocol!"
687/// ```
688///
689/// # Examples
690///
691/// Creating and serializing a data frame:
692/// ```rust,ignore
693/// use ri::protocol::frames::{RiFrame, RiFrameType};
694///
695/// let frame = RiFrame::data_frame(
696///     b"Hello, World!".to_vec(),
697///     42
698/// ).expect("Failed to create frame");
699///
700/// let bytes = frame.to_bytes().expect("Failed to serialize frame");
701/// println!("Frame serialized to {} bytes", bytes.len());
702///
703/// assert!(frame.is_valid());
704/// assert_eq!(frame.sequence_number(), 42);
705/// ```
706///
707/// Creating different frame types:
708/// ```rust,ignore
709/// use ri::protocol::frames::{RiFrame, RiFrameType};
710///
711/// // Control frame with command data
712/// let control = RiFrame::control_frame(
713///     vec![0x01, 0x02, 0x03],
714///     1
715/// ).expect("Failed to create control frame");
716///
717/// // Authentication frame with credentials
718/// let auth = RiFrame::auth_frame(
719///     b"token=abc123".to_vec(),
720///     2
721/// ).expect("Failed to create auth frame");
722///
723/// // Keep-alive frame (no payload)
724/// let keepalive = RiFrame::keepalive_frame(3)
725///     .expect("Failed to create keepalive frame");
726///
727/// // Error frame with code and message
728/// let error = RiFrame::error_frame(
729///     0x0401,
730///     "Connection timeout".to_string(),
731///     4
732/// ).expect("Failed to create error frame");
733/// ```
734///
735/// Receiving and deserializing frames:
736/// ```rust,ignore
737/// use ri::protocol::frames::{RiFrame, RiFrameType};
738///
739/// let original = RiFrame::data_frame(
740///     b"Received data".to_vec(),
741///     100
742/// ).expect("Failed to create frame");
743///
744/// let bytes = original.to_bytes().expect("Failed to serialize");
745///
746/// // Simulate network transmission
747/// let received = RiFrame::from_bytes(&bytes)
748///     .expect("Failed to deserialize frame");
749///
750/// assert_eq!(received.sequence_number(), 100);
751/// assert_eq!(received.payload, b"Received data");
752/// assert!(received.is_valid());
753/// ```
754#[derive(Debug, Clone)]
755#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
756pub struct RiFrame {
757    /// Frame header containing protocol metadata.
758    ///
759    /// The header provides essential information for frame processing including
760    /// the frame type, sequence number, timestamp, and integrity checksum.
761    /// It is always exactly 32 bytes in size and uses big-endian byte ordering.
762    pub header: RiFrameHeader,
763
764    /// Frame payload containing application data.
765    ///
766    /// The payload contains the actual data being transmitted. Its meaning
767    /// depends on the frame type:
768    /// - **Control**: Protocol management commands
769    /// - **Data**: Application-level message data
770    /// - **Auth**: Authentication credentials or tokens
771    /// - **KeepAlive**: Empty (no payload)
772    /// - **Error**: Error code + error message
773    /// - **Encrypted**: Pre-encrypted application data
774    pub payload: Vec<u8>,
775}
776
777impl RiFrame {
778    /// Create a new frame
779    pub fn new(frame_type: RiFrameType, payload: Vec<u8>, sequence_number: u32) -> RiResult<Self> {
780        let header = RiFrameHeader::new(frame_type, payload.len() as u32, sequence_number)?;
781        Ok(Self { header, payload })
782    }
783    
784    /// Create a control frame
785    pub fn control_frame(control_data: Vec<u8>, sequence_number: u32) -> RiResult<Self> {
786        Self::new(RiFrameType::Control, control_data, sequence_number)
787    }
788    
789    /// Create a data frame
790    pub fn data_frame(data: Vec<u8>, sequence_number: u32) -> RiResult<Self> {
791        Self::new(RiFrameType::Data, data, sequence_number)
792    }
793    
794    /// Create an authentication frame
795    pub fn auth_frame(auth_data: Vec<u8>, sequence_number: u32) -> RiResult<Self> {
796        Self::new(RiFrameType::Auth, auth_data, sequence_number)
797    }
798    
799    /// Create a keep-alive frame
800    pub fn keepalive_frame(sequence_number: u32) -> RiResult<Self> {
801        Self::new(RiFrameType::KeepAlive, vec![], sequence_number)
802    }
803    
804    /// Create an error frame
805    pub fn error_frame(error_code: u32, error_message: String, sequence_number: u32) -> RiResult<Self> {
806        let mut payload = Vec::with_capacity(4 + error_message.len());
807        payload.extend_from_slice(&error_code.to_be_bytes());
808        payload.extend_from_slice(error_message.as_bytes());
809        Self::new(RiFrameType::Error, payload, sequence_number)
810    }
811    
812    /// Serialize frame to bytes
813    pub fn to_bytes(&self) -> RiResult<Vec<u8>> {
814        let mut header = self.header.clone();
815        
816        // Calculate and set checksum
817        header.checksum = header.calculate_checksum(&self.payload);
818        
819        let mut result = Vec::with_capacity(32 + self.payload.len());
820        result.extend_from_slice(&header.to_bytes());
821        result.extend_from_slice(&self.payload);
822        
823        Ok(result)
824    }
825    
826    /// Deserialize frame from bytes
827    pub fn from_bytes(bytes: &[u8]) -> RiResult<Self> {
828        if bytes.len() < 32 {
829            return Err(RiError::FrameError("Frame too short".to_string()));
830        }
831        
832        let header = RiFrameHeader::from_bytes(&bytes[0..32])?;
833        
834        // Verify magic number
835        if header.magic != RiFrameHeader::MAGIC {
836            return Err(RiError::FrameError(format!("Invalid magic number: 0x{:08X}", header.magic)));
837        }
838        
839        // Verify version
840        if header.version != RiFrameHeader::VERSION {
841            return Err(RiError::FrameError(format!("Unsupported version: {}", header.version)));
842        }
843        
844        // Security: Check payload length limit to prevent memory exhaustion
845        if header.payload_length > RiFrameHeader::MAX_PAYLOAD_LENGTH {
846            return Err(RiError::FrameError(format!(
847                "Payload length {} exceeds maximum allowed {}",
848                header.payload_length, RiFrameHeader::MAX_PAYLOAD_LENGTH
849            )));
850        }
851        
852        // Check payload length
853        if bytes.len() < 32 + header.payload_length as usize {
854            return Err(RiError::FrameError("Incomplete frame".to_string()));
855        }
856        
857        let payload = bytes[32..32 + header.payload_length as usize].to_vec();
858        
859        // Verify checksum
860        if !header.verify_checksum(&payload) {
861            return Err(RiError::FrameError("Checksum verification failed".to_string()));
862        }
863        
864        Ok(Self { header, payload })
865    }
866    
867    /// Get frame type
868    pub fn frame_type(&self) -> Option<RiFrameType> {
869        RiFrameType::from_u8(self.header.frame_type)
870    }
871    
872    /// Get sequence number
873    pub fn sequence_number(&self) -> u32 {
874        self.header.sequence_number
875    }
876    
877    /// Get timestamp
878    pub fn timestamp(&self) -> u64 {
879        self.header.timestamp
880    }
881    
882    /// Check if frame is valid
883    pub fn is_valid(&self) -> bool {
884        self.header.magic == RiFrameHeader::MAGIC &&
885        self.header.version == RiFrameHeader::VERSION &&
886        self.header.verify_checksum(&self.payload)
887    }
888}
889
890/// Frame parser for reading and assembling protocol frames from stream data.
891///
892/// The RiFrameParser handles the incremental parsing of frame data from network
893/// streams or byte sources. Network protocols often deliver data in chunks that
894/// may not align with protocol frame boundaries. This parser accumulates incoming
895/// data in an internal buffer and extracts complete frames when sufficient data
896/// is available. It also manages sequence number validation to ensure frame
897/// ordering integrity.
898///
899/// ## Parser Operation Model
900///
901/// ```
902/// Incoming Data:  [partial][complete][partial][complete][partial]
903///                      |         |        |         |
904///                      v         v        v         v
905/// Parser Buffer:  [======][==========][=========][=======]
906///                      |         |        |
907///                      v         v        v
908/// Extracted:      [Frame1] [Frame2] [Frame3]
909/// ```
910///
911/// ## Sequence Number Validation
912///
913/// The parser maintains an expected sequence number counter. Each extracted frame
914/// must have a sequence number matching the expected value. This detects missing
915/// frames (gaps in sequence numbers) which may indicate packet loss. Use
916/// `reset_sequence()` to set a new expected sequence number, such as after
917/// reconnection.
918///
919/// ## Buffer Management
920///
921/// The parser maintains an internal buffer that grows as data is added. For
922/// long-running connections, periodically check `buffer_len()` and consider
923/// calling `clear_buffer()` if buffer accumulation indicates parsing issues.
924/// The parser automatically removes parsed data from the buffer.
925///
926/// ## Python Bindings
927///
928/// When compiled with the `pyo3` feature, this struct provides Python bindings:
929/// ```python
930/// from ri import RiFrameParser
931///
932/// # Create parser for incoming stream data
933/// parser = RiFrameParser.new()
934///
935/// # Simulate receiving data chunks
936/// chunks = [
937///     frame1_bytes[:20],
938///     frame1_bytes[20:] + frame2_bytes[:30],
939///     frame2_bytes[30:] + frame3_bytes
940/// ]
941///
942/// for chunk in chunks:
943///     parser.add_data(chunk)
944///     while True:
945///         frame = parser.parse_frame()
946///         if frame is None:
947///             break
948///         print(f"Received frame: {frame.sequence_number()}")
949///
950/// print(f"Buffer contains {parser.buffer_len()} bytes")
951/// ```
952///
953/// # Examples
954///
955/// Basic frame parsing from stream data:
956/// ```rust,ignore
957/// use ri::protocol::frames::{RiFrameParser, RiFrame};
958///
959/// let mut parser = RiFrameParser::new();
960///
961/// // Simulate receiving frame data in chunks
962/// let frame1 = RiFrame::data_frame(b"First message".to_vec(), 0)
963///     .expect("Failed to create frame");
964/// let frame2 = RiFrame::data_frame(b"Second message".to_vec(), 1)
965///     .expect("Failed to create frame");
966///
967/// let bytes1 = frame1.to_bytes().expect("Failed to serialize");
968/// let bytes2 = frame2.to_bytes().expect("Failed to serialize");
969///
970/// // Add first chunk (partial frame)
971/// parser.add_data(&bytes1[..20]);
972/// assert!(parser.parse_frame().unwrap().is_none());
973///
974/// // Add second chunk (completes frame1, starts frame2)
975/// parser.add_data(&bytes1[20..]);
976/// let parsed = parser.parse_frame().unwrap().expect("Should have complete frame");
977/// assert_eq!(parsed.sequence_number(), 0);
978///
979/// // Add remaining data
980/// parser.add_data(&bytes2);
981/// let parsed = parser.parse_frame().unwrap().expect("Should have complete frame");
982/// assert_eq!(parsed.sequence_number(), 1);
983/// ```
984///
985/// Handling sequence number reset:
986/// ```rust,ignore
987/// use ri::protocol::frames::RiFrameParser;
988///
989/// let mut parser = RiFrameParser::new();
990///
991/// // Parse some frames
992/// parser.add_data(&some_data);
993/// while let Ok(Some(frame)) = parser.parse_frame() {
994///     // Process frames
995/// }
996///
997/// // Reset sequence number for new session
998/// parser.reset_sequence();
999/// parser.clear_buffer();
1000///
1001/// // Now expecting sequence 0 again
1002/// assert_eq!(parser.next_sequence, 0);
1003/// ```
1004///
1005/// # Thread Safety
1006///
1007/// This struct is not thread-safe. Multiple threads should not concurrently
1008/// access the same parser instance without external synchronization. For
1009/// concurrent parsing, either use separate parser instances per thread or
1010/// wrap access with a Mutex or RwLock.
1011///
1012/// # Performance Considerations
1013///
1014/// - The parser uses `Vec::extend_from_slice` for efficient buffer appending
1015/// - Frame extraction uses slice operations to avoid unnecessary copying
1016/// - Buffer memory is only reclaimed when frames are successfully parsed
1017/// - Large frames may cause temporary buffer growth; configure appropriate limits
1018#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
1019pub struct RiFrameParser {
1020    /// Internal buffer for accumulating incoming data.
1021    ///
1022    /// The buffer holds bytes that have been received but not yet assembled
1023    /// into complete frames. It grows dynamically as more data arrives.
1024    /// Data is automatically removed from the buffer once successfully parsed.
1025    buffer: Vec<u8>,
1026
1027    /// Next expected sequence number for validation.
1028    ///
1029    /// This counter tracks the sequence number of the next frame expected
1030    /// from the stream. Frames with mismatching sequence numbers indicate
1031    /// potential packet loss or protocol errors.
1032    next_sequence: u32,
1033}
1034
1035impl RiFrameParser {
1036    /// Maximum buffer size (20 MB) to prevent memory exhaustion attacks.
1037    /// This limit prevents attackers from sending endless streams of data
1038    /// that would cause unbounded buffer growth.
1039    const MAX_BUFFER_SIZE: usize = 20 * 1024 * 1024;
1040    
1041    pub fn new() -> Self {
1042        Self {
1043            buffer: Vec::new(),
1044            next_sequence: 0,
1045        }
1046    }
1047    
1048    /// Add data to the internal buffer for parsing.
1049    ///
1050    /// # Security
1051    ///
1052    /// This method enforces a maximum buffer size to prevent memory exhaustion
1053    /// attacks. If the buffer would exceed MAX_BUFFER_SIZE (20 MB), the data
1054    /// is rejected and an error is returned.
1055    pub fn add_data(&mut self, data: &[u8]) -> RiResult<()> {
1056        // Security: Check buffer size limit to prevent memory exhaustion
1057        let new_size = self.buffer.len().saturating_add(data.len());
1058        if new_size > Self::MAX_BUFFER_SIZE {
1059            log::warn!(
1060                "[Ri.FrameParser] Buffer size limit exceeded: {} bytes (max {} bytes)",
1061                new_size, Self::MAX_BUFFER_SIZE
1062            );
1063            return Err(RiError::FrameError(format!(
1064                "Buffer size limit exceeded: {} bytes (max {} bytes)",
1065                new_size, Self::MAX_BUFFER_SIZE
1066            )));
1067        }
1068        
1069        self.buffer.extend_from_slice(data);
1070        Ok(())
1071    }
1072    
1073    pub fn parse_frame(&mut self) -> RiResult<Option<RiFrame>> {
1074        if self.buffer.len() < 32 {
1075            return Ok(None);
1076        }
1077        
1078        let header = RiFrameHeader::from_bytes(&self.buffer[0..32])?;
1079        
1080        // Security: Check payload length limit
1081        if header.payload_length > RiFrameHeader::MAX_PAYLOAD_LENGTH {
1082            // Clear buffer to recover from attack
1083            self.buffer.clear();
1084            return Err(RiError::FrameError(format!(
1085                "Payload length {} exceeds maximum allowed {}",
1086                header.payload_length, RiFrameHeader::MAX_PAYLOAD_LENGTH
1087            )));
1088        }
1089        
1090        let total_length = 32usize.saturating_add(header.payload_length as usize);
1091        
1092        if self.buffer.len() < total_length {
1093            return Ok(None);
1094        }
1095        
1096        let frame_bytes = self.buffer[0..total_length].to_vec();
1097        let frame = RiFrame::from_bytes(&frame_bytes)?;
1098        
1099        if frame.header.sequence_number != self.next_sequence {
1100            return Ok(None);
1101        }
1102        
1103        self.buffer.drain(0..total_length);
1104        self.next_sequence = self.next_sequence.wrapping_add(1);
1105        
1106        Ok(Some(frame))
1107    }
1108    
1109    pub fn buffer_len(&self) -> usize {
1110        self.buffer.len()
1111    }
1112    
1113    pub fn clear_buffer(&mut self) {
1114        self.buffer.clear();
1115    }
1116    
1117    pub fn reset_sequence(&mut self) {
1118        self.next_sequence = 0;
1119    }
1120}
1121
1122/// Frame builder for creating protocol frames with automatic sequence numbering.
1123///
1124/// The RiFrameBuilder provides a convenient interface for constructing Ri frames
1125/// while automatically managing sequence numbers. Rather than manually tracking and
1126/// incrementing sequence numbers for each frame, the builder maintains an internal
1127/// counter that is automatically incremented after each frame construction. This
1128/// ensures proper sequence numbering without the risk of human error.
1129///
1130/// ## Builder Pattern Advantages
1131///
1132/// Using the frame builder provides several benefits over direct frame construction:
1133///
1134/// - **Automatic Sequencing**: No need to manually track and increment sequence numbers
1135/// - **Type Safety**: Compile-time checking of frame type construction
1136/// - **Convenience Methods**: Domain-specific constructors for each frame type
1137/// - **State Management**: Builder maintains state across frame constructions
1138///
1139/// ## Sequence Number Management
1140///
1141/// The builder maintains an internal sequence counter that is automatically incremented
1142/// after each frame construction. The counter uses wrapping arithmetic (modulo 2^32)
1143/// to handle overflow gracefully. You can query or set the current sequence number
1144/// using `next_sequence()` and `set_sequence()` methods.
1145///
1146/// ## Python Bindings
1147///
1148/// When compiled with the `pyo3` feature, this struct provides Python bindings:
1149/// ```python
1150/// from ri import RiFrameBuilder
1151///
1152/// # Create builder for convenient frame construction
1153/// builder = RiFrameBuilder.new()
1154///
1155/// # Build frames without manually tracking sequence numbers
1156/// control_frame = builder.build_control_frame(b"\x01\x02\x03")
1157/// data_frame = builder.build_data_frame(b"Hello, World!")
1158/// auth_frame = builder.build_auth_frame(b"token=abc123")
1159///
1160/// # Check current sequence number
1161/// print(f"Next sequence: {builder.next_sequence()}")
1162///
1163/// # Reset sequence for new session
1164/// builder.set_sequence(0)
1165/// ```
1166///
1167/// # Examples
1168///
1169/// Building multiple frames with automatic sequencing:
1170/// ```rust,ignore
1171/// use ri::protocol::frames::RiFrameBuilder;
1172///
1173/// let mut builder = RiFrameBuilder::new();
1174///
1175/// // Build a series of data frames
1176/// let frame1 = builder.build_data_frame(b"Message 1".to_vec())
1177///     .expect("Failed to build frame");
1178/// let frame2 = builder.build_data_frame(b"Message 2".to_vec())
1179///     .expect("Failed to build frame");
1180/// let frame3 = builder.build_data_frame(b"Message 3".to_vec())
1181///     .expect("Failed to build frame");
1182///
1183/// assert_eq!(frame1.sequence_number(), 0);
1184/// assert_eq!(frame2.sequence_number(), 1);
1185/// assert_eq!(frame3.sequence_number(), 2);
1186///
1187/// // Current sequence is now 3
1188/// assert_eq!(builder.next_sequence(), 3);
1189/// ```
1190///
1191/// Building different frame types:
1192/// ```rust,ignore
1193/// use ri::protocol::frames::RiFrameBuilder;
1194///
1195/// let mut builder = RiFrameBuilder::new();
1196///
1197/// // Control frame
1198/// let control = builder.build_control_frame(vec![0x01, 0x00, 0x01])
1199///     .expect("Failed to build control frame");
1200///
1201/// // Authentication frame
1202/// let auth = builder.build_auth_frame(b"credentials=secret".to_vec())
1203///     .expect("Failed to build auth frame");
1204///
1205/// // Keep-alive frame
1206/// let keepalive = builder.build_keepalive_frame()
1207///     .expect("Failed to build keepalive frame");
1208///
1209/// // Error frame
1210/// let error = builder.build_error_frame(0x0401, "Timeout".to_string())
1211///     .expect("Failed to build error frame");
1212/// ```
1213///
1214/// Managing sequence numbers:
1215/// ```rust,ignore
1216/// use ri::protocol::frames::RiFrameBuilder;
1217///
1218/// let mut builder = RiFrameBuilder::new();
1219///
1220/// // Build some frames
1221/// let _ = builder.build_data_frame(b"Frame 0".to_vec()).unwrap();
1222/// let _ = builder.build_data_frame(b"Frame 1".to_vec()).unwrap();
1223/// let _ = builder.build_data_frame(b"Frame 2".to_vec()).unwrap();
1224///
1225/// // Check current sequence
1226/// assert_eq!(builder.next_sequence(), 3);
1227///
1228/// // Set specific sequence for resend or new session
1229/// builder.set_sequence(100);
1230///
1231/// let next = builder.build_data_frame(b"Frame 100".to_vec()).unwrap();
1232/// assert_eq!(next.sequence_number(), 100);
1233/// assert_eq!(builder.next_sequence(), 101);
1234/// ```
1235///
1236/// # Thread Safety
1237///
1238/// This struct is not thread-safe. Multiple threads should not concurrently
1239/// access the same builder instance without external synchronization. For
1240/// concurrent frame building, either use separate builder instances per thread
1241/// or wrap access with a Mutex or RwLock.
1242///
1243/// # Performance Characteristics
1244///
1245/// - Frame construction is O(1) for fixed-size headers
1246/// - Payload copying is O(n) where n is payload size
1247/// - Sequence number operations are O(1)
1248/// - Minimal heap allocation for small payloads
1249#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
1250pub struct RiFrameBuilder {
1251    /// Internal counter for automatic sequence number generation.
1252    ///
1253    /// This counter tracks the sequence number to assign to the next frame
1254    /// constructed by the builder. It is automatically incremented after
1255    /// each frame construction using wrapping arithmetic.
1256    next_sequence: u32,
1257}
1258
1259impl RiFrameBuilder {
1260    pub fn new() -> Self {
1261        Self { next_sequence: 0 }
1262    }
1263    
1264    pub fn build_control_frame(&mut self, control_data: Vec<u8>) -> RiResult<RiFrame> {
1265        let frame = RiFrame::control_frame(control_data, self.next_sequence)?;
1266        self.next_sequence = self.next_sequence.wrapping_add(1);
1267        Ok(frame)
1268    }
1269    
1270    pub fn build_data_frame(&mut self, data: Vec<u8>) -> RiResult<RiFrame> {
1271        let frame = RiFrame::data_frame(data, self.next_sequence)?;
1272        self.next_sequence = self.next_sequence.wrapping_add(1);
1273        Ok(frame)
1274    }
1275    
1276    pub fn build_auth_frame(&mut self, auth_data: Vec<u8>) -> RiResult<RiFrame> {
1277        let frame = RiFrame::auth_frame(auth_data, self.next_sequence)?;
1278        self.next_sequence = self.next_sequence.wrapping_add(1);
1279        Ok(frame)
1280    }
1281    
1282    pub fn build_keepalive_frame(&mut self) -> RiResult<RiFrame> {
1283        let frame = RiFrame::keepalive_frame(self.next_sequence)?;
1284        self.next_sequence = self.next_sequence.wrapping_add(1);
1285        Ok(frame)
1286    }
1287    
1288    pub fn build_error_frame(&mut self, error_code: u32, error_message: String) -> RiResult<RiFrame> {
1289        let frame = RiFrame::error_frame(error_code, error_message, self.next_sequence)?;
1290        self.next_sequence = self.next_sequence.wrapping_add(1);
1291        Ok(frame)
1292    }
1293    
1294    pub fn next_sequence(&self) -> u32 {
1295        self.next_sequence
1296    }
1297    
1298    pub fn set_sequence(&mut self, sequence: u32) {
1299        self.next_sequence = sequence;
1300    }
1301}
1302
1303