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}