zenoh_codec/scouting/
hello.rs1use alloc::{vec, vec::Vec};
15
16use zenoh_buffers::{
17 reader::{DidntRead, Reader},
18 writer::{DidntWrite, Writer},
19};
20use zenoh_protocol::{
21 common::{imsg, ZExtUnknown},
22 core::{Locator, WhatAmI, ZenohIdProto},
23 scouting::{
24 hello::{flag, HelloProto},
25 id,
26 },
27};
28
29use crate::{RCodec, WCodec, Zenoh080, Zenoh080Header, Zenoh080Length};
30
31impl<W> WCodec<&HelloProto, &mut W> for Zenoh080
32where
33 W: Writer,
34{
35 type Output = Result<(), DidntWrite>;
36
37 fn write(self, writer: &mut W, x: &HelloProto) -> Self::Output {
38 let HelloProto {
39 version,
40 whatami,
41 zid,
42 locators,
43 } = x;
44
45 let mut header = id::HELLO;
47 if !locators.is_empty() {
48 header |= flag::L;
49 }
50 self.write(&mut *writer, header)?;
51
52 self.write(&mut *writer, version)?;
54
55 let mut flags: u8 = 0;
56 let whatami: u8 = match whatami {
57 WhatAmI::Router => 0b00,
58 WhatAmI::Peer => 0b01,
59 WhatAmI::Client => 0b10,
60 };
61 flags |= whatami & 0b11;
62 flags |= ((zid.size() - 1) as u8) << 4;
63 self.write(&mut *writer, flags)?;
64
65 let lodec = Zenoh080Length::new(zid.size());
66 lodec.write(&mut *writer, zid)?;
67
68 if !locators.is_empty() {
69 self.write(&mut *writer, locators.as_slice())?;
70 }
71
72 Ok(())
73 }
74}
75
76impl<R> RCodec<HelloProto, &mut R> for Zenoh080
77where
78 R: Reader,
79{
80 type Error = DidntRead;
81
82 fn read(self, reader: &mut R) -> Result<HelloProto, Self::Error> {
83 let header: u8 = self.read(&mut *reader)?;
84 let codec = Zenoh080Header::new(header);
85 codec.read(reader)
86 }
87}
88
89impl<R> RCodec<HelloProto, &mut R> for Zenoh080Header
90where
91 R: Reader,
92{
93 type Error = DidntRead;
94
95 fn read(self, reader: &mut R) -> Result<HelloProto, Self::Error> {
96 if imsg::mid(self.header) != id::HELLO {
97 return Err(DidntRead);
98 }
99
100 let version: u8 = self.codec.read(&mut *reader)?;
102 let flags: u8 = self.codec.read(&mut *reader)?;
103 let whatami = match flags & 0b11 {
104 0b00 => WhatAmI::Router,
105 0b01 => WhatAmI::Peer,
106 0b10 => WhatAmI::Client,
107 _ => return Err(DidntRead),
108 };
109 let length = 1 + ((flags >> 4) as usize);
110 let lodec = Zenoh080Length::new(length);
111 let zid: ZenohIdProto = lodec.read(&mut *reader)?;
112
113 let locators = if imsg::has_flag(self.header, flag::L) {
114 let locs: Vec<Locator> = self.codec.read(&mut *reader)?;
115 locs
116 } else {
117 vec![]
118 };
119
120 let mut has_extensions = imsg::has_flag(self.header, flag::Z);
122 while has_extensions {
123 let (_, more): (ZExtUnknown, bool) = self.codec.read(&mut *reader)?;
124 has_extensions = more;
125 }
126
127 Ok(HelloProto {
128 version,
129 zid,
130 whatami,
131 locators,
132 })
133 }
134}