1pub mod declare;
15pub mod interest;
16pub mod oam;
17pub mod push;
18pub mod request;
19pub mod response;
20pub mod timestamp_stack;
21
22use core::fmt;
23
24pub use declare::{
25 Declare, DeclareBody, DeclareFinal, DeclareKeyExpr, DeclareQueryable, DeclareSubscriber,
26 DeclareToken, UndeclareKeyExpr, UndeclareQueryable, UndeclareSubscriber, UndeclareToken,
27};
28pub use interest::Interest;
29pub use oam::Oam;
30pub use push::Push;
31pub use request::{AtomicRequestId, Request, RequestId};
32pub use response::{Response, ResponseFinal};
33
34use crate::core::{CongestionControl, Priority, Reliability, WireExpr};
35#[cfg(feature = "shared-memory")]
36use crate::zenoh::{PushBody, RequestBody, ResponseBody};
37
38pub mod id {
39 pub const OAM: u8 = 0x1f;
42 pub const DECLARE: u8 = 0x1e;
43 pub const PUSH: u8 = 0x1d;
44 pub const REQUEST: u8 = 0x1c;
45 pub const RESPONSE: u8 = 0x1b;
46 pub const RESPONSE_FINAL: u8 = 0x1a;
47 pub const INTEREST: u8 = 0x19;
48}
49
50#[repr(u8)]
51#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
52pub enum Mapping {
53 #[default]
54 Receiver = 0,
55 Sender = 1,
56}
57
58impl Mapping {
59 pub const DEFAULT: Self = Self::Receiver;
60
61 #[cfg(feature = "test")]
62 #[doc(hidden)]
63 pub fn rand() -> Self {
64 use rand::Rng;
65
66 let mut rng = rand::thread_rng();
67 if rng.gen_bool(0.5) {
68 Mapping::Sender
69 } else {
70 Mapping::Receiver
71 }
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
77pub enum NetworkBody {
78 Push(Push),
79 Request(Request),
80 Response(Response),
81 ResponseFinal(ResponseFinal),
82 Interest(Interest),
83 Declare(Declare),
84 OAM(Oam),
85}
86
87#[derive(Debug, Copy, Clone, PartialEq, Eq)]
88pub enum NetworkBodyRef<'a> {
89 Push(&'a Push),
90 Request(&'a Request),
91 Response(&'a Response),
92 ResponseFinal(&'a ResponseFinal),
93 Interest(&'a Interest),
94 Declare(&'a Declare),
95 OAM(&'a Oam),
96}
97
98#[derive(Debug, PartialEq, Eq)]
99pub enum NetworkBodyMut<'a> {
100 Push(&'a mut Push),
101 Request(&'a mut Request),
102 Response(&'a mut Response),
103 ResponseFinal(&'a mut ResponseFinal),
104 Interest(&'a mut Interest),
105 Declare(&'a mut Declare),
106 OAM(&'a mut Oam),
107}
108
109#[derive(Debug, Clone, PartialEq, Eq)]
110pub struct NetworkMessage {
111 pub body: NetworkBody,
112 pub reliability: Reliability,
113}
114
115#[derive(Debug, Copy, Clone, PartialEq, Eq)]
116pub struct NetworkMessageRef<'a> {
117 pub body: NetworkBodyRef<'a>,
118 pub reliability: Reliability,
119}
120
121#[derive(Debug, PartialEq, Eq)]
122pub struct NetworkMessageMut<'a> {
123 pub body: NetworkBodyMut<'a>,
124 pub reliability: Reliability,
125}
126
127pub trait NetworkMessageExt {
128 #[doc(hidden)]
129 fn body(&self) -> NetworkBodyRef<'_>;
130
131 #[doc(hidden)]
132 fn reliability(&self) -> Reliability;
133
134 #[inline]
135 fn is_reliable(&self) -> bool {
136 self.reliability() == Reliability::Reliable
137 }
138
139 #[inline]
140 fn is_express(&self) -> bool {
141 match self.body() {
142 NetworkBodyRef::Push(msg) => msg.ext_qos.is_express(),
143 NetworkBodyRef::Request(msg) => msg.ext_qos.is_express(),
144 NetworkBodyRef::Response(msg) => msg.ext_qos.is_express(),
145 NetworkBodyRef::ResponseFinal(msg) => msg.ext_qos.is_express(),
146 NetworkBodyRef::Interest(msg) => msg.ext_qos.is_express(),
147 NetworkBodyRef::Declare(msg) => msg.ext_qos.is_express(),
148 NetworkBodyRef::OAM(msg) => msg.ext_qos.is_express(),
149 }
150 }
151
152 #[inline]
153 fn congestion_control(&self) -> CongestionControl {
154 match self.body() {
155 NetworkBodyRef::Push(msg) => msg.ext_qos.get_congestion_control(),
156 NetworkBodyRef::Request(msg) => msg.ext_qos.get_congestion_control(),
157 NetworkBodyRef::Response(msg) => msg.ext_qos.get_congestion_control(),
158 NetworkBodyRef::ResponseFinal(msg) => msg.ext_qos.get_congestion_control(),
159 NetworkBodyRef::Interest(msg) => msg.ext_qos.get_congestion_control(),
160 NetworkBodyRef::Declare(msg) => msg.ext_qos.get_congestion_control(),
161 NetworkBodyRef::OAM(msg) => msg.ext_qos.get_congestion_control(),
162 }
163 }
164
165 #[inline]
166 #[cfg(feature = "shared-memory")]
167 fn is_shm(&self) -> bool {
168 match self.body() {
169 NetworkBodyRef::Push(Push { payload, .. }) => match payload {
170 PushBody::Put(p) => p.ext_shm.is_some(),
171 PushBody::Del(_) => false,
172 },
173 NetworkBodyRef::Request(Request { payload, .. }) => match payload {
174 RequestBody::Query(b) => b.ext_body.as_ref().is_some_and(|b| b.ext_shm.is_some()),
175 },
176 NetworkBodyRef::Response(Response { payload, .. }) => match payload {
177 ResponseBody::Reply(b) => match &b.payload {
178 PushBody::Put(p) => p.ext_shm.is_some(),
179 PushBody::Del(_) => false,
180 },
181 ResponseBody::Err(e) => e.ext_shm.is_some(),
182 },
183 NetworkBodyRef::ResponseFinal(_)
184 | NetworkBodyRef::Interest(_)
185 | NetworkBodyRef::Declare(_)
186 | NetworkBodyRef::OAM(_) => false,
187 }
188 }
189
190 #[inline]
191 fn is_droppable(&self) -> bool {
192 !self.is_reliable() || self.congestion_control() == CongestionControl::Drop
193 }
194
195 #[inline]
196 fn priority(&self) -> Priority {
197 match self.body() {
198 NetworkBodyRef::Push(msg) => msg.ext_qos.get_priority(),
199 NetworkBodyRef::Request(msg) => msg.ext_qos.get_priority(),
200 NetworkBodyRef::Response(msg) => msg.ext_qos.get_priority(),
201 NetworkBodyRef::ResponseFinal(msg) => msg.ext_qos.get_priority(),
202 NetworkBodyRef::Interest(msg) => msg.ext_qos.get_priority(),
203 NetworkBodyRef::Declare(msg) => msg.ext_qos.get_priority(),
204 NetworkBodyRef::OAM(msg) => msg.ext_qos.get_priority(),
205 }
206 }
207
208 #[inline]
209 fn wire_expr(&self) -> Option<&WireExpr<'_>> {
210 match &self.body() {
211 NetworkBodyRef::Push(m) => Some(&m.wire_expr),
212 NetworkBodyRef::Request(m) => Some(&m.wire_expr),
213 NetworkBodyRef::Response(m) => Some(&m.wire_expr),
214 NetworkBodyRef::ResponseFinal(_) => None,
215 NetworkBodyRef::Interest(m) => m.wire_expr.as_ref(),
216 NetworkBodyRef::Declare(m) => match &m.body {
217 DeclareBody::DeclareKeyExpr(m) => Some(&m.wire_expr),
218 DeclareBody::UndeclareKeyExpr(_) => None,
219 DeclareBody::DeclareSubscriber(m) => Some(&m.wire_expr),
220 DeclareBody::UndeclareSubscriber(m) => Some(&m.ext_wire_expr.wire_expr),
221 DeclareBody::DeclareQueryable(m) => Some(&m.wire_expr),
222 DeclareBody::UndeclareQueryable(m) => Some(&m.ext_wire_expr.wire_expr),
223 DeclareBody::DeclareToken(m) => Some(&m.wire_expr),
224 DeclareBody::UndeclareToken(m) => Some(&m.ext_wire_expr.wire_expr),
225 DeclareBody::DeclareFinal(_) => None,
226 },
227 NetworkBodyRef::OAM(_) => None,
228 }
229 }
230
231 #[inline]
232 fn payload_size(&self) -> Option<usize> {
233 match &self.body() {
234 NetworkBodyRef::Push(p) => Some(p.payload_size()),
235 NetworkBodyRef::Request(r) => Some(r.payload_size()),
236 NetworkBodyRef::Response(r) => Some(r.payload_size()),
237 NetworkBodyRef::ResponseFinal(_)
238 | NetworkBodyRef::Interest(_)
239 | NetworkBodyRef::Declare(_)
240 | NetworkBodyRef::OAM(_) => None,
241 }
242 }
243
244 #[inline]
245 fn as_ref(&self) -> NetworkMessageRef<'_> {
246 NetworkMessageRef {
247 body: self.body(),
248 reliability: self.reliability(),
249 }
250 }
251
252 #[inline]
253 fn to_owned(&self) -> NetworkMessage {
254 NetworkMessage {
255 body: match self.body() {
256 NetworkBodyRef::Push(msg) => NetworkBody::Push(msg.clone()),
257 NetworkBodyRef::Request(msg) => NetworkBody::Request(msg.clone()),
258 NetworkBodyRef::Response(msg) => NetworkBody::Response(msg.clone()),
259 NetworkBodyRef::ResponseFinal(msg) => NetworkBody::ResponseFinal(msg.clone()),
260 NetworkBodyRef::Interest(msg) => NetworkBody::Interest(msg.clone()),
261 NetworkBodyRef::Declare(msg) => NetworkBody::Declare(msg.clone()),
262 NetworkBodyRef::OAM(msg) => NetworkBody::OAM(msg.clone()),
263 },
264 reliability: self.reliability(),
265 }
266 }
267}
268
269impl<M: NetworkMessageExt> NetworkMessageExt for &M {
270 fn body(&self) -> NetworkBodyRef<'_> {
271 (**self).body()
272 }
273
274 fn reliability(&self) -> Reliability {
275 (**self).reliability()
276 }
277}
278
279impl<M: NetworkMessageExt> NetworkMessageExt for &mut M {
280 fn body(&self) -> NetworkBodyRef<'_> {
281 (**self).body()
282 }
283
284 fn reliability(&self) -> Reliability {
285 (**self).reliability()
286 }
287}
288
289impl NetworkMessageExt for NetworkMessage {
290 fn body(&self) -> NetworkBodyRef<'_> {
291 match &self.body {
292 NetworkBody::Push(body) => NetworkBodyRef::Push(body),
293 NetworkBody::Request(body) => NetworkBodyRef::Request(body),
294 NetworkBody::Response(body) => NetworkBodyRef::Response(body),
295 NetworkBody::ResponseFinal(body) => NetworkBodyRef::ResponseFinal(body),
296 NetworkBody::Interest(body) => NetworkBodyRef::Interest(body),
297 NetworkBody::Declare(body) => NetworkBodyRef::Declare(body),
298 NetworkBody::OAM(body) => NetworkBodyRef::OAM(body),
299 }
300 }
301
302 fn reliability(&self) -> Reliability {
303 self.reliability
304 }
305}
306
307impl NetworkMessageExt for NetworkMessageRef<'_> {
308 fn body(&self) -> NetworkBodyRef<'_> {
309 self.body
310 }
311
312 fn reliability(&self) -> Reliability {
313 self.reliability
314 }
315}
316
317impl NetworkMessageExt for NetworkMessageMut<'_> {
318 fn body(&self) -> NetworkBodyRef<'_> {
319 match &self.body {
320 NetworkBodyMut::Push(body) => NetworkBodyRef::Push(body),
321 NetworkBodyMut::Request(body) => NetworkBodyRef::Request(body),
322 NetworkBodyMut::Response(body) => NetworkBodyRef::Response(body),
323 NetworkBodyMut::ResponseFinal(body) => NetworkBodyRef::ResponseFinal(body),
324 NetworkBodyMut::Interest(body) => NetworkBodyRef::Interest(body),
325 NetworkBodyMut::Declare(body) => NetworkBodyRef::Declare(body),
326 NetworkBodyMut::OAM(body) => NetworkBodyRef::OAM(body),
327 }
328 }
329
330 fn reliability(&self) -> Reliability {
331 self.reliability
332 }
333}
334
335impl NetworkMessage {
336 #[cfg(feature = "test")]
337 #[doc(hidden)]
338 pub fn rand() -> Self {
339 use rand::Rng;
340
341 let mut rng = rand::thread_rng();
342
343 let body = match rng.gen_range(0..6) {
344 0 => NetworkBody::Push(Push::rand()),
345 1 => NetworkBody::Request(Request::rand()),
346 2 => NetworkBody::Response(Response::rand()),
347 3 => NetworkBody::ResponseFinal(ResponseFinal::rand()),
348 4 => NetworkBody::Declare(Declare::rand()),
349 5 => NetworkBody::OAM(Oam::rand()),
350 _ => unreachable!(),
351 };
352
353 body.into()
354 }
355
356 #[inline]
357 pub fn as_mut(&mut self) -> NetworkMessageMut<'_> {
358 let body = match &mut self.body {
359 NetworkBody::Push(body) => NetworkBodyMut::Push(body),
360 NetworkBody::Request(body) => NetworkBodyMut::Request(body),
361 NetworkBody::Response(body) => NetworkBodyMut::Response(body),
362 NetworkBody::ResponseFinal(body) => NetworkBodyMut::ResponseFinal(body),
363 NetworkBody::Interest(body) => NetworkBodyMut::Interest(body),
364 NetworkBody::Declare(body) => NetworkBodyMut::Declare(body),
365 NetworkBody::OAM(body) => NetworkBodyMut::OAM(body),
366 };
367 NetworkMessageMut {
368 body,
369 reliability: self.reliability,
370 }
371 }
372}
373
374impl NetworkMessageMut<'_> {
375 #[inline]
376 pub fn as_mut(&mut self) -> NetworkMessageMut<'_> {
377 let body = match &mut self.body {
378 NetworkBodyMut::Push(body) => NetworkBodyMut::Push(body),
379 NetworkBodyMut::Request(body) => NetworkBodyMut::Request(body),
380 NetworkBodyMut::Response(body) => NetworkBodyMut::Response(body),
381 NetworkBodyMut::ResponseFinal(body) => NetworkBodyMut::ResponseFinal(body),
382 NetworkBodyMut::Interest(body) => NetworkBodyMut::Interest(body),
383 NetworkBodyMut::Declare(body) => NetworkBodyMut::Declare(body),
384 NetworkBodyMut::OAM(body) => NetworkBodyMut::OAM(body),
385 };
386 NetworkMessageMut {
387 body,
388 reliability: self.reliability,
389 }
390 }
391}
392
393impl fmt::Display for NetworkMessageRef<'_> {
394 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395 match &self.body {
396 NetworkBodyRef::OAM(_) => write!(f, "OAM"),
397 NetworkBodyRef::Push(_) => write!(f, "Push"),
398 NetworkBodyRef::Request(_) => write!(f, "Request"),
399 NetworkBodyRef::Response(_) => write!(f, "Response"),
400 NetworkBodyRef::ResponseFinal(_) => write!(f, "ResponseFinal"),
401 NetworkBodyRef::Interest(_) => write!(f, "Interest"),
402 NetworkBodyRef::Declare(_) => write!(f, "Declare"),
403 }
404 }
405}
406
407impl fmt::Display for NetworkMessage {
408 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409 self.as_ref().fmt(f)
410 }
411}
412
413impl fmt::Display for NetworkMessageMut<'_> {
414 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
415 self.as_ref().fmt(f)
416 }
417}
418
419impl From<NetworkBody> for NetworkMessage {
420 #[inline]
421 fn from(body: NetworkBody) -> Self {
422 Self {
423 body,
424 reliability: Reliability::DEFAULT,
425 }
426 }
427}
428
429#[cfg(feature = "test")]
430impl From<Push> for NetworkMessage {
431 fn from(push: Push) -> Self {
432 NetworkBody::Push(push).into()
433 }
434}
435
436pub mod ext {
438 use core::fmt;
439
440 use crate::{
441 common::{imsg, ZExtZ64},
442 core::{CongestionControl, EntityId, Priority, ZenohIdProto},
443 };
444
445 #[repr(transparent)]
460 #[derive(Clone, Copy, PartialEq, Eq)]
461 pub struct QoSType<const ID: u8> {
462 inner: u8,
463 }
464
465 impl<const ID: u8> QoSType<{ ID }> {
466 const P_MASK: u8 = 0b00000111;
467 const D_FLAG: u8 = 0b00001000;
468 const E_FLAG: u8 = 0b00010000;
469 const F_FLAG: u8 = 0b00100000;
470
471 pub const DEFAULT: Self = Self::new(Priority::DEFAULT, CongestionControl::DEFAULT, false);
472
473 pub const DECLARE: Self =
474 Self::new(Priority::Control, CongestionControl::DEFAULT_DECLARE, false);
475 pub const INTEREST: Self = Self::new(
476 Priority::Control,
477 CongestionControl::DEFAULT_INTEREST,
478 false,
479 );
480 pub const PUSH: Self = Self::new(Priority::DEFAULT, CongestionControl::DEFAULT_PUSH, false);
481 pub const REQUEST: Self =
482 Self::new(Priority::DEFAULT, CongestionControl::DEFAULT_REQUEST, false);
483 pub const OAM: Self = Self::new(Priority::Control, CongestionControl::DEFAULT_OAM, false);
484
485 pub const fn new(
486 priority: Priority,
487 congestion_control: CongestionControl,
488 is_express: bool,
489 ) -> Self {
490 let mut inner = priority as u8;
491 match congestion_control {
492 CongestionControl::Block => inner |= Self::D_FLAG,
493 #[cfg(feature = "unstable")]
494 CongestionControl::BlockFirst => inner |= Self::F_FLAG,
495 _ => {}
496 }
497 if is_express {
498 inner |= Self::E_FLAG;
499 }
500 Self { inner }
501 }
502
503 pub fn set_priority(&mut self, priority: Priority) {
504 self.inner = imsg::set_bitfield(self.inner, priority as u8, Self::P_MASK);
505 }
506
507 pub const fn get_priority(&self) -> Priority {
508 unsafe { core::mem::transmute(self.inner & Self::P_MASK) }
509 }
510
511 pub fn set_congestion_control(&mut self, cctrl: CongestionControl) {
512 match cctrl {
513 CongestionControl::Block => {
514 self.inner = imsg::set_flag(self.inner, Self::D_FLAG);
515 self.inner = imsg::unset_flag(self.inner, Self::F_FLAG);
516 }
517 CongestionControl::Drop => {
518 self.inner = imsg::unset_flag(self.inner, Self::D_FLAG);
519 self.inner = imsg::unset_flag(self.inner, Self::F_FLAG);
520 }
521 #[cfg(feature = "unstable")]
522 CongestionControl::BlockFirst => {
523 self.inner = imsg::unset_flag(self.inner, Self::D_FLAG);
524 self.inner = imsg::set_flag(self.inner, Self::F_FLAG);
525 }
526 }
527 }
528
529 pub const fn get_congestion_control(&self) -> CongestionControl {
530 match (
531 imsg::has_flag(self.inner, Self::D_FLAG),
532 imsg::has_flag(self.inner, Self::F_FLAG),
533 ) {
534 (false, false) => CongestionControl::Drop,
535 #[cfg(feature = "unstable")]
536 (false, true) => CongestionControl::BlockFirst,
537 #[cfg(not(feature = "unstable"))]
538 (false, true) => CongestionControl::Drop,
539 (true, _) => CongestionControl::Block,
540 }
541 }
542
543 pub fn set_is_express(&mut self, is_express: bool) {
544 match is_express {
545 true => self.inner = imsg::set_flag(self.inner, Self::E_FLAG),
546 false => self.inner = imsg::unset_flag(self.inner, Self::E_FLAG),
547 }
548 }
549
550 pub const fn is_express(&self) -> bool {
551 imsg::has_flag(self.inner, Self::E_FLAG)
552 }
553
554 #[cfg(feature = "test")]
555 #[doc(hidden)]
556 pub fn rand() -> Self {
557 use rand::Rng;
558 let mut rng = rand::thread_rng();
559
560 let inner: u8 = rng.gen();
561 Self { inner }
562 }
563 }
564
565 impl<const ID: u8> Default for QoSType<{ ID }> {
566 fn default() -> Self {
567 Self::new(Priority::DEFAULT, CongestionControl::DEFAULT, false)
568 }
569 }
570
571 impl<const ID: u8> From<ZExtZ64<{ ID }>> for QoSType<{ ID }> {
572 fn from(ext: ZExtZ64<{ ID }>) -> Self {
573 Self {
574 inner: ext.value as u8,
575 }
576 }
577 }
578
579 impl<const ID: u8> From<QoSType<{ ID }>> for ZExtZ64<{ ID }> {
580 fn from(ext: QoSType<{ ID }>) -> Self {
581 ZExtZ64::new(ext.inner as u64)
582 }
583 }
584
585 impl<const ID: u8> fmt::Debug for QoSType<{ ID }> {
586 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
587 f.debug_struct("QoS")
588 .field("priority", &self.get_priority())
589 .field("congestion", &self.get_congestion_control())
590 .field("express", &self.is_express())
591 .finish()
592 }
593 }
594
595 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
604 pub struct TimestampType<const ID: u8> {
605 pub timestamp: uhlc::Timestamp,
606 }
607
608 impl<const ID: u8> TimestampType<{ ID }> {
609 #[cfg(feature = "test")]
610 #[doc(hidden)]
611 pub fn rand() -> Self {
612 use rand::Rng;
613 let mut rng = rand::thread_rng();
614
615 let time = uhlc::NTP64(rng.gen());
616 let id = uhlc::ID::try_from(ZenohIdProto::rand().to_le_bytes()).unwrap();
617 let timestamp = uhlc::Timestamp::new(time, id);
618 Self { timestamp }
619 }
620 }
621
622 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
631 pub struct NodeIdType<const ID: u8> {
632 pub node_id: u16,
633 }
634
635 impl<const ID: u8> NodeIdType<{ ID }> {
636 pub const DEFAULT: Self = Self { node_id: 0 };
638
639 #[cfg(feature = "test")]
640 #[doc(hidden)]
641 pub fn rand() -> Self {
642 use rand::Rng;
643 let mut rng = rand::thread_rng();
644 let node_id = rng.gen();
645 Self { node_id }
646 }
647 }
648
649 impl<const ID: u8> Default for NodeIdType<{ ID }> {
650 fn default() -> Self {
651 Self::DEFAULT
652 }
653 }
654
655 impl<const ID: u8> From<ZExtZ64<{ ID }>> for NodeIdType<{ ID }> {
656 fn from(ext: ZExtZ64<{ ID }>) -> Self {
657 Self {
658 node_id: ext.value as u16,
659 }
660 }
661 }
662
663 impl<const ID: u8> From<NodeIdType<{ ID }>> for ZExtZ64<{ ID }> {
664 fn from(ext: NodeIdType<{ ID }>) -> Self {
665 ZExtZ64::new(ext.node_id as u64)
666 }
667 }
668
669 #[derive(Debug, Clone, PartialEq, Eq)]
680 pub struct EntityGlobalIdType<const ID: u8> {
681 pub zid: ZenohIdProto,
682 pub eid: EntityId,
683 }
684
685 impl<const ID: u8> EntityGlobalIdType<{ ID }> {
686 #[cfg(feature = "test")]
687 #[doc(hidden)]
688 pub fn rand() -> Self {
689 use rand::Rng;
690 let mut rng = rand::thread_rng();
691
692 let zid = ZenohIdProto::rand();
693 let eid: EntityId = rng.gen();
694 Self { zid, eid }
695 }
696 }
697}