zenoh_protocol/scouting/
scout.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use crate::core::{whatami::WhatAmIMatcher, ZenohIdProto};
15
16/// # Scout message
17///
18/// The [`Scout`] message MAY be sent at any point in time to discover the available zenoh nodes in the
19/// network. The [`Scout`] message SHOULD be sent in a multicast or broadcast fashion. Upon receiving a
20/// [`Scout`] message, a zenoh node MUST first verify whether the matching criteria are satisfied, then
21/// it SHOULD reply with a [`super::HelloProto`] message in a unicast fashion including all the requested
22/// information.
23///
24/// The scouting message flow is the following:
25///
26/// ```text
27/// A                   B                   C
28/// |       SCOUT       |                   |
29/// |------------------>|                   |
30/// |         \---------------------------->|
31/// |                   |                   |
32/// |       HELLO       |                   |
33/// |<------------------|                   |
34/// |                   |      HELLO        |
35/// |<--------------------------------------|
36/// |                   |                   |
37/// ```
38///
39/// The SCOUT message structure is defined as follows:
40///
41/// ```text
42/// Header flags:
43/// - X: Reserved
44/// - X: Reserved
45/// - Z: Extensions     If Z==1 then zenoh extensions will follow.
46///
47///  7 6 5 4 3 2 1 0
48/// +-+-+-+-+-+-+-+-+
49/// |Z|X|X|  SCOUT  |
50/// +-+-+-+---------+
51/// |    version    |
52/// +---------------+
53/// |zid_len|I| what| (#)(*)
54/// +-+-+-+-+-+-+-+-+
55/// ~      [u8]     ~ if Flag(I)==1 -- ZenohID
56/// +---------------+
57///
58/// (#) ZID length. If Flag(I)==1 it indicates how many bytes are used for the ZenohID bytes.
59///     A ZenohID is minimum 1 byte and maximum 16 bytes. Therefore, the actual length is computed as:
60///         real_zid_len := 1 + zid_len
61///
62/// (*) What. It indicates a bitmap of WhatAmI interests.
63///    The valid bitflags are:
64///    - 0b001: Router
65///    - 0b010: Peer
66///    - 0b100: Client
67/// ```
68pub mod flag {
69    pub const I: u8 = 1 << 3; // 0x04 ZenohID       if I==1 then the ZenohID is present
70                              // pub const X: u8 = 1 << 6; // 0x40       Reserved
71    pub const Z: u8 = 1 << 7; // 0x80 Extensions    if Z==1 then an extension will follow
72}
73
74#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct Scout {
76    pub version: u8,
77    pub what: WhatAmIMatcher,
78    pub zid: Option<ZenohIdProto>,
79}
80
81impl Scout {
82    #[cfg(feature = "test")]
83    #[doc(hidden)]
84    pub fn rand() -> Self {
85        use rand::Rng;
86
87        let mut rng = rand::thread_rng();
88
89        let version: u8 = rng.gen();
90        let what = WhatAmIMatcher::rand();
91        let zid = rng.gen_bool(0.5).then_some(ZenohIdProto::rand());
92        Self { version, what, zid }
93    }
94}