Skip to main content

MicroParticipant

Struct MicroParticipant 

Source
pub struct MicroParticipant<T: Transport> { /* private fields */ }
Expand description

MicroParticipant - DDS Participant

Represents a DDS participant on an embedded device.

§Design

  • Single-threaded (no async, no locks)
  • Fixed number of readers/writers (compile-time limit)
  • BEST_EFFORT QoS only (no reliability, no history)

§Example

let mut transport = NullTransport::default();
let participant = MicroParticipant::new(0, transport)?;

Implementations§

Source§

impl<T: Transport> MicroParticipant<T>

Source

pub fn new(domain_id: u32, transport: T) -> Result<Self>

Create a new participant

§Arguments
  • domain_id - DDS domain ID (0-232)
  • transport - Transport implementation
Examples found in repository?
examples/test_encoding.rs (line 19)
12fn main() {
13    println!("=== HDDS Micro Encoding Test ===\n");
14
15    // Create a null transport (captures sent data)
16    let transport = NullTransport::default();
17
18    // Create participant
19    let mut participant = MicroParticipant::new(0, transport).unwrap();
20    let guid_prefix = participant.guid_prefix();
21    let entity_id = participant.allocate_entity_id(true);
22
23    println!("GUID Prefix: {:02X?}", guid_prefix.as_bytes());
24    println!("Entity ID: {:02X?}", entity_id.as_bytes());
25
26    // Create writer (for demonstration, not used in this encoding test)
27    let dest = Locator::udpv4([239, 255, 0, 1], 7400);
28    let _writer = MicroWriter::new(guid_prefix, entity_id, "test/topic", dest).unwrap();
29
30    // Encode temperature-like payload: sensor_id(4) + value(4) + timestamp(8)
31    let mut buf = [0u8; 32];
32    let mut encoder = CdrEncoder::new(&mut buf);
33    encoder.encode_u32(0x42).unwrap(); // sensor_id
34    encoder.encode_f32(25.5).unwrap(); // temperature
35    encoder.encode_u64(12345678).unwrap(); // timestamp
36    let payload = encoder.finish();
37
38    println!("Payload ({} bytes): {:02X?}", payload.len(), payload);
39
40    // Build the packet manually to inspect bytes
41    let mut packet = [0u8; 256];
42
43    // RTPS Header (20 bytes)
44    let header = hdds_micro::rtps::RtpsHeader::new(
45        hdds_micro::rtps::ProtocolVersion::RTPS_2_5,
46        hdds_micro::rtps::VendorId::HDDS,
47        guid_prefix,
48    );
49    let header_len = header.encode(&mut packet).unwrap();
50
51    // DATA submessage
52    let data = hdds_micro::rtps::submessages::Data::new(
53        EntityId::UNKNOWN,
54        entity_id,
55        hdds_micro::rtps::SequenceNumber::new(1),
56    );
57    let data_len = data.encode_header(&mut packet[header_len..]).unwrap();
58
59    // Copy payload
60    let payload_offset = header_len + data_len;
61    packet[payload_offset..payload_offset + payload.len()].copy_from_slice(payload);
62
63    let total_len = payload_offset + payload.len();
64
65    // Update octets_to_next
66    let octets_to_next = (20 + payload.len()) as u16;
67    packet[header_len + 2] = (octets_to_next & 0xff) as u8;
68    packet[header_len + 3] = ((octets_to_next >> 8) & 0xff) as u8;
69
70    println!("\n=== Complete RTPS Packet ({} bytes) ===", total_len);
71
72    // Print in rows of 16
73    for i in (0..total_len).step_by(16) {
74        print!("{:04X}  ", i);
75        for &byte in &packet[i..std::cmp::min(i + 16, total_len)] {
76            print!("{:02X} ", byte);
77        }
78        println!();
79    }
80
81    println!("\n=== Key Bytes Analysis ===");
82    println!(
83        "Bytes 0-3 (RTPS magic): {:02X} {:02X} {:02X} {:02X} = '{}'",
84        packet[0],
85        packet[1],
86        packet[2],
87        packet[3],
88        std::str::from_utf8(&packet[0..4]).unwrap_or("???")
89    );
90    println!("Bytes 4-5 (version): {:02X} {:02X}", packet[4], packet[5]);
91    println!("Bytes 6-7 (vendor): {:02X} {:02X}", packet[6], packet[7]);
92    println!("Bytes 8-19 (GUID prefix): {:02X?}", &packet[8..20]);
93    println!(
94        "Byte 20 (submsg kind): {:02X} (expected: 0x15 for DATA)",
95        packet[20]
96    );
97    println!(
98        "Byte 21 (submsg flags): {:02X} (expected: 0x05)",
99        packet[21]
100    );
101    println!(
102        "Bytes 22-23 (octetsToNext): {:02X} {:02X} = {} bytes",
103        packet[22],
104        packet[23],
105        u16::from_le_bytes([packet[22], packet[23]])
106    );
107
108    // Verify
109    if packet[20] == 0x15 {
110        println!("\n✓ Submessage kind is correct (0x15)");
111    } else {
112        println!(
113            "\n✗ ERROR: Submessage kind is wrong: 0x{:02X} instead of 0x15",
114            packet[20]
115        );
116    }
117}
Source

pub const fn domain_id(&self) -> u32

Get domain ID

Source

pub const fn guid_prefix(&self) -> GuidPrefix

Get GUID prefix

Examples found in repository?
examples/test_encoding.rs (line 20)
12fn main() {
13    println!("=== HDDS Micro Encoding Test ===\n");
14
15    // Create a null transport (captures sent data)
16    let transport = NullTransport::default();
17
18    // Create participant
19    let mut participant = MicroParticipant::new(0, transport).unwrap();
20    let guid_prefix = participant.guid_prefix();
21    let entity_id = participant.allocate_entity_id(true);
22
23    println!("GUID Prefix: {:02X?}", guid_prefix.as_bytes());
24    println!("Entity ID: {:02X?}", entity_id.as_bytes());
25
26    // Create writer (for demonstration, not used in this encoding test)
27    let dest = Locator::udpv4([239, 255, 0, 1], 7400);
28    let _writer = MicroWriter::new(guid_prefix, entity_id, "test/topic", dest).unwrap();
29
30    // Encode temperature-like payload: sensor_id(4) + value(4) + timestamp(8)
31    let mut buf = [0u8; 32];
32    let mut encoder = CdrEncoder::new(&mut buf);
33    encoder.encode_u32(0x42).unwrap(); // sensor_id
34    encoder.encode_f32(25.5).unwrap(); // temperature
35    encoder.encode_u64(12345678).unwrap(); // timestamp
36    let payload = encoder.finish();
37
38    println!("Payload ({} bytes): {:02X?}", payload.len(), payload);
39
40    // Build the packet manually to inspect bytes
41    let mut packet = [0u8; 256];
42
43    // RTPS Header (20 bytes)
44    let header = hdds_micro::rtps::RtpsHeader::new(
45        hdds_micro::rtps::ProtocolVersion::RTPS_2_5,
46        hdds_micro::rtps::VendorId::HDDS,
47        guid_prefix,
48    );
49    let header_len = header.encode(&mut packet).unwrap();
50
51    // DATA submessage
52    let data = hdds_micro::rtps::submessages::Data::new(
53        EntityId::UNKNOWN,
54        entity_id,
55        hdds_micro::rtps::SequenceNumber::new(1),
56    );
57    let data_len = data.encode_header(&mut packet[header_len..]).unwrap();
58
59    // Copy payload
60    let payload_offset = header_len + data_len;
61    packet[payload_offset..payload_offset + payload.len()].copy_from_slice(payload);
62
63    let total_len = payload_offset + payload.len();
64
65    // Update octets_to_next
66    let octets_to_next = (20 + payload.len()) as u16;
67    packet[header_len + 2] = (octets_to_next & 0xff) as u8;
68    packet[header_len + 3] = ((octets_to_next >> 8) & 0xff) as u8;
69
70    println!("\n=== Complete RTPS Packet ({} bytes) ===", total_len);
71
72    // Print in rows of 16
73    for i in (0..total_len).step_by(16) {
74        print!("{:04X}  ", i);
75        for &byte in &packet[i..std::cmp::min(i + 16, total_len)] {
76            print!("{:02X} ", byte);
77        }
78        println!();
79    }
80
81    println!("\n=== Key Bytes Analysis ===");
82    println!(
83        "Bytes 0-3 (RTPS magic): {:02X} {:02X} {:02X} {:02X} = '{}'",
84        packet[0],
85        packet[1],
86        packet[2],
87        packet[3],
88        std::str::from_utf8(&packet[0..4]).unwrap_or("???")
89    );
90    println!("Bytes 4-5 (version): {:02X} {:02X}", packet[4], packet[5]);
91    println!("Bytes 6-7 (vendor): {:02X} {:02X}", packet[6], packet[7]);
92    println!("Bytes 8-19 (GUID prefix): {:02X?}", &packet[8..20]);
93    println!(
94        "Byte 20 (submsg kind): {:02X} (expected: 0x15 for DATA)",
95        packet[20]
96    );
97    println!(
98        "Byte 21 (submsg flags): {:02X} (expected: 0x05)",
99        packet[21]
100    );
101    println!(
102        "Bytes 22-23 (octetsToNext): {:02X} {:02X} = {} bytes",
103        packet[22],
104        packet[23],
105        u16::from_le_bytes([packet[22], packet[23]])
106    );
107
108    // Verify
109    if packet[20] == 0x15 {
110        println!("\n✓ Submessage kind is correct (0x15)");
111    } else {
112        println!(
113            "\n✗ ERROR: Submessage kind is wrong: 0x{:02X} instead of 0x15",
114            packet[20]
115        );
116    }
117}
Source

pub const fn guid(&self) -> GUID

Get GUID

Source

pub fn local_locator(&self) -> Locator

Get local locator

Source

pub fn allocate_entity_id(&mut self, is_writer: bool) -> EntityId

Allocate next entity ID

Examples found in repository?
examples/test_encoding.rs (line 21)
12fn main() {
13    println!("=== HDDS Micro Encoding Test ===\n");
14
15    // Create a null transport (captures sent data)
16    let transport = NullTransport::default();
17
18    // Create participant
19    let mut participant = MicroParticipant::new(0, transport).unwrap();
20    let guid_prefix = participant.guid_prefix();
21    let entity_id = participant.allocate_entity_id(true);
22
23    println!("GUID Prefix: {:02X?}", guid_prefix.as_bytes());
24    println!("Entity ID: {:02X?}", entity_id.as_bytes());
25
26    // Create writer (for demonstration, not used in this encoding test)
27    let dest = Locator::udpv4([239, 255, 0, 1], 7400);
28    let _writer = MicroWriter::new(guid_prefix, entity_id, "test/topic", dest).unwrap();
29
30    // Encode temperature-like payload: sensor_id(4) + value(4) + timestamp(8)
31    let mut buf = [0u8; 32];
32    let mut encoder = CdrEncoder::new(&mut buf);
33    encoder.encode_u32(0x42).unwrap(); // sensor_id
34    encoder.encode_f32(25.5).unwrap(); // temperature
35    encoder.encode_u64(12345678).unwrap(); // timestamp
36    let payload = encoder.finish();
37
38    println!("Payload ({} bytes): {:02X?}", payload.len(), payload);
39
40    // Build the packet manually to inspect bytes
41    let mut packet = [0u8; 256];
42
43    // RTPS Header (20 bytes)
44    let header = hdds_micro::rtps::RtpsHeader::new(
45        hdds_micro::rtps::ProtocolVersion::RTPS_2_5,
46        hdds_micro::rtps::VendorId::HDDS,
47        guid_prefix,
48    );
49    let header_len = header.encode(&mut packet).unwrap();
50
51    // DATA submessage
52    let data = hdds_micro::rtps::submessages::Data::new(
53        EntityId::UNKNOWN,
54        entity_id,
55        hdds_micro::rtps::SequenceNumber::new(1),
56    );
57    let data_len = data.encode_header(&mut packet[header_len..]).unwrap();
58
59    // Copy payload
60    let payload_offset = header_len + data_len;
61    packet[payload_offset..payload_offset + payload.len()].copy_from_slice(payload);
62
63    let total_len = payload_offset + payload.len();
64
65    // Update octets_to_next
66    let octets_to_next = (20 + payload.len()) as u16;
67    packet[header_len + 2] = (octets_to_next & 0xff) as u8;
68    packet[header_len + 3] = ((octets_to_next >> 8) & 0xff) as u8;
69
70    println!("\n=== Complete RTPS Packet ({} bytes) ===", total_len);
71
72    // Print in rows of 16
73    for i in (0..total_len).step_by(16) {
74        print!("{:04X}  ", i);
75        for &byte in &packet[i..std::cmp::min(i + 16, total_len)] {
76            print!("{:02X} ", byte);
77        }
78        println!();
79    }
80
81    println!("\n=== Key Bytes Analysis ===");
82    println!(
83        "Bytes 0-3 (RTPS magic): {:02X} {:02X} {:02X} {:02X} = '{}'",
84        packet[0],
85        packet[1],
86        packet[2],
87        packet[3],
88        std::str::from_utf8(&packet[0..4]).unwrap_or("???")
89    );
90    println!("Bytes 4-5 (version): {:02X} {:02X}", packet[4], packet[5]);
91    println!("Bytes 6-7 (vendor): {:02X} {:02X}", packet[6], packet[7]);
92    println!("Bytes 8-19 (GUID prefix): {:02X?}", &packet[8..20]);
93    println!(
94        "Byte 20 (submsg kind): {:02X} (expected: 0x15 for DATA)",
95        packet[20]
96    );
97    println!(
98        "Byte 21 (submsg flags): {:02X} (expected: 0x05)",
99        packet[21]
100    );
101    println!(
102        "Bytes 22-23 (octetsToNext): {:02X} {:02X} = {} bytes",
103        packet[22],
104        packet[23],
105        u16::from_le_bytes([packet[22], packet[23]])
106    );
107
108    // Verify
109    if packet[20] == 0x15 {
110        println!("\n✓ Submessage kind is correct (0x15)");
111    } else {
112        println!(
113            "\n✗ ERROR: Submessage kind is wrong: 0x{:02X} instead of 0x15",
114            packet[20]
115        );
116    }
117}
Source

pub fn transport_mut(&mut self) -> &mut T

Get transport (mutable)

Source

pub fn transport(&self) -> &T

Get transport (immutable)

Source

pub fn shutdown(self) -> Result<()>

Shutdown participant

Auto Trait Implementations§

§

impl<T> Freeze for MicroParticipant<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for MicroParticipant<T>
where T: RefUnwindSafe,

§

impl<T> Send for MicroParticipant<T>
where T: Send,

§

impl<T> Sync for MicroParticipant<T>
where T: Sync,

§

impl<T> Unpin for MicroParticipant<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for MicroParticipant<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for MicroParticipant<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.