pub struct DMSCFrame {
pub header: DMSCFrameHeader,
pub payload: Vec<u8>,
}Expand description
Complete protocol frame combining header and payload data.
A DMSCFrame represents the fundamental unit of data transmission in the DMSC protocol. Each frame consists of a fixed 32-byte header containing protocol metadata and a variable-length payload containing the actual application data. Frames are serialized for network transmission and deserialized upon receipt using CRC32 checksums for integrity verification.
§Frame Structure
+------------------+-------------------+
| Header (32B) | Payload (VAR) |
+------------------+-------------------+
| magic | type | v | flags | len | seq |
| timestamp | checksum |
+------------------+-------------------+§Frame Lifecycle
- Creation: Construct a frame using
new()or one of the convenience constructors (data_frame(),control_frame(), etc.) - Serialization: Convert to bytes using
to_bytes()for transmission - Transmission: Send bytes over the network connection
- Reception: Receive bytes and add to frame parser buffer
- Deserialization: Parse bytes back to frame using
from_bytes() - Processing: Handle the frame based on its type
§Frame Validity
A frame is considered valid when:
- The magic number matches the DMSC protocol identifier
- The protocol version is supported
- The CRC32 checksum matches the computed checksum
- The payload length matches the actual payload size
Use the is_valid() method for quick validation checking.
§Python Bindings
When compiled with the pyo3 feature, this struct provides Python bindings:
from dmsc import DMSCFrame, DMSCFrameType
# Create a data frame
frame = DMSCFrame.data_frame(
data=b"Hello, DMSC Protocol!",
sequence_number=1
)
# Serialize for transmission
frame_bytes = frame.to_bytes()
print(f"Frame size: {len(frame_bytes)} bytes")
# Access frame properties
print(f"Frame type: {frame.frame_type()}")
print(f"Sequence: {frame.sequence_number()}")
print(f"Timestamp: {frame.timestamp()}")
print(f"Valid: {frame.is_valid()}")
# Deserialize received frame
received = DMSCFrame.from_bytes(frame_bytes)
assert received.payload == b"Hello, DMSC Protocol!"§Examples
Creating and serializing a data frame:
use dmsc::protocol::frames::{DMSCFrame, DMSCFrameType};
let frame = DMSCFrame::data_frame(
b"Hello, World!".to_vec(),
42
).expect("Failed to create frame");
let bytes = frame.to_bytes().expect("Failed to serialize frame");
println!("Frame serialized to {} bytes", bytes.len());
assert!(frame.is_valid());
assert_eq!(frame.sequence_number(), 42);Creating different frame types:
use dmsc::protocol::frames::{DMSCFrame, DMSCFrameType};
// Control frame with command data
let control = DMSCFrame::control_frame(
vec![0x01, 0x02, 0x03],
1
).expect("Failed to create control frame");
// Authentication frame with credentials
let auth = DMSCFrame::auth_frame(
b"token=abc123".to_vec(),
2
).expect("Failed to create auth frame");
// Keep-alive frame (no payload)
let keepalive = DMSCFrame::keepalive_frame(3)
.expect("Failed to create keepalive frame");
// Error frame with code and message
let error = DMSCFrame::error_frame(
0x0401,
"Connection timeout".to_string(),
4
).expect("Failed to create error frame");Receiving and deserializing frames:
use dmsc::protocol::frames::{DMSCFrame, DMSCFrameType};
let original = DMSCFrame::data_frame(
b"Received data".to_vec(),
100
).expect("Failed to create frame");
let bytes = original.to_bytes().expect("Failed to serialize");
// Simulate network transmission
let received = DMSCFrame::from_bytes(&bytes)
.expect("Failed to deserialize frame");
assert_eq!(received.sequence_number(), 100);
assert_eq!(received.payload, b"Received data");
assert!(received.is_valid());Fields§
§header: DMSCFrameHeaderFrame header containing protocol metadata.
The header provides essential information for frame processing including the frame type, sequence number, timestamp, and integrity checksum. It is always exactly 32 bytes in size and uses big-endian byte ordering.
payload: Vec<u8>Frame payload containing application data.
The payload contains the actual data being transmitted. Its meaning depends on the frame type:
- Control: Protocol management commands
- Data: Application-level message data
- Auth: Authentication credentials or tokens
- KeepAlive: Empty (no payload)
- Error: Error code + error message
- Encrypted: Pre-encrypted application data
Implementations§
Source§impl DMSCFrame
impl DMSCFrame
Sourcepub fn new(
frame_type: DMSCFrameType,
payload: Vec<u8>,
sequence_number: u32,
) -> DMSCResult<Self>
pub fn new( frame_type: DMSCFrameType, payload: Vec<u8>, sequence_number: u32, ) -> DMSCResult<Self>
Create a new frame
Sourcepub fn control_frame(
control_data: Vec<u8>,
sequence_number: u32,
) -> DMSCResult<Self>
pub fn control_frame( control_data: Vec<u8>, sequence_number: u32, ) -> DMSCResult<Self>
Create a control frame
Sourcepub fn data_frame(data: Vec<u8>, sequence_number: u32) -> DMSCResult<Self>
pub fn data_frame(data: Vec<u8>, sequence_number: u32) -> DMSCResult<Self>
Create a data frame
Sourcepub fn auth_frame(auth_data: Vec<u8>, sequence_number: u32) -> DMSCResult<Self>
pub fn auth_frame(auth_data: Vec<u8>, sequence_number: u32) -> DMSCResult<Self>
Create an authentication frame
Sourcepub fn keepalive_frame(sequence_number: u32) -> DMSCResult<Self>
pub fn keepalive_frame(sequence_number: u32) -> DMSCResult<Self>
Create a keep-alive frame
Sourcepub fn error_frame(
error_code: u32,
error_message: String,
sequence_number: u32,
) -> DMSCResult<Self>
pub fn error_frame( error_code: u32, error_message: String, sequence_number: u32, ) -> DMSCResult<Self>
Create an error frame
Sourcepub fn to_bytes(&self) -> DMSCResult<Vec<u8>>
pub fn to_bytes(&self) -> DMSCResult<Vec<u8>>
Serialize frame to bytes
Sourcepub fn from_bytes(bytes: &[u8]) -> DMSCResult<Self>
pub fn from_bytes(bytes: &[u8]) -> DMSCResult<Self>
Deserialize frame from bytes
Sourcepub fn frame_type(&self) -> Option<DMSCFrameType>
pub fn frame_type(&self) -> Option<DMSCFrameType>
Get frame type
Sourcepub fn sequence_number(&self) -> u32
pub fn sequence_number(&self) -> u32
Get sequence number
Trait Implementations§
Source§impl<'py> IntoPyObject<'py> for DMSCFrame
impl<'py> IntoPyObject<'py> for DMSCFrame
Source§impl PyClassImpl for DMSCFrame
impl PyClassImpl for DMSCFrame
Source§const IS_BASETYPE: bool = false
const IS_BASETYPE: bool = false
Source§const IS_SUBCLASS: bool = false
const IS_SUBCLASS: bool = false
Source§const IS_MAPPING: bool = false
const IS_MAPPING: bool = false
Source§const IS_SEQUENCE: bool = false
const IS_SEQUENCE: bool = false
Source§const IS_IMMUTABLE_TYPE: bool = false
const IS_IMMUTABLE_TYPE: bool = false
Source§const RAW_DOC: &'static CStr = /// ```
const RAW_DOC: &'static CStr = /// ```
Source§const DOC: &'static CStr
const DOC: &'static CStr
text_signature if a constructor is defined. Read moreSource§type ThreadChecker = SendablePyClass<DMSCFrame>
type ThreadChecker = SendablePyClass<DMSCFrame>
Source§type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild
type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild
Source§type BaseNativeType = PyAny
type BaseNativeType = PyAny
PyAny by default, and when you declare
#[pyclass(extends=PyDict)], it’s PyDict.fn items_iter() -> PyClassItemsIter
fn lazy_type_object() -> &'static LazyTypeObject<Self>
fn dict_offset() -> Option<isize>
fn weaklist_offset() -> Option<isize>
Source§impl PyTypeInfo for DMSCFrame
impl PyTypeInfo for DMSCFrame
Source§fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
§fn type_object(py: Python<'_>) -> Bound<'_, PyType>
fn type_object(py: Python<'_>) -> Bound<'_, PyType>
§fn is_type_of(object: &Bound<'_, PyAny>) -> bool
fn is_type_of(object: &Bound<'_, PyAny>) -> bool
object is an instance of this type or a subclass of this type.§fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool
object is an instance of this type.impl DerefToPyAny for DMSCFrame
impl ExtractPyClassWithClone for DMSCFrame
Auto Trait Implementations§
impl Freeze for DMSCFrame
impl RefUnwindSafe for DMSCFrame
impl Send for DMSCFrame
impl Sync for DMSCFrame
impl Unpin for DMSCFrame
impl UnwindSafe for DMSCFrame
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<'py, T> IntoPyObjectExt<'py> for Twhere
T: IntoPyObject<'py>,
impl<'py, T> IntoPyObjectExt<'py> for Twhere
T: IntoPyObject<'py>,
§fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>
fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>
self into an owned Python object, dropping type information.§fn into_py_any(self, py: Python<'py>) -> Result<Py<PyAny>, PyErr>
fn into_py_any(self, py: Python<'py>) -> Result<Py<PyAny>, PyErr>
self into an owned Python object, dropping type information and unbinding it
from the 'py lifetime.§fn into_pyobject_or_pyerr(self, py: Python<'py>) -> Result<Self::Output, PyErr>
fn into_pyobject_or_pyerr(self, py: Python<'py>) -> Result<Self::Output, PyErr>
self into a Python object. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PyErrArguments for T
impl<T> PyErrArguments for T
§impl<T> PyTypeCheck for Twhere
T: PyTypeInfo,
impl<T> PyTypeCheck for Twhere
T: PyTypeInfo,
§const NAME: &'static str = T::NAME
const NAME: &'static str = T::NAME
§fn type_check(object: &Bound<'_, PyAny>) -> bool
fn type_check(object: &Bound<'_, PyAny>) -> bool
§fn classinfo_object(py: Python<'_>) -> Bound<'_, PyAny>
fn classinfo_object(py: Python<'_>) -> Bound<'_, PyAny>
isinstance and issubclass function. Read more