capsules_extra/net/thread/
tlv.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Implements Type-Length-Value (TLV) encoding and decoding as outlined
6//! in the Thread 1.1.1 Specification.
7//!
8//! TLVs are used to serialize information exchanged during mesh link
9//! establishment (MLE). MLE is covered in Chapter 4.
10//!
11//! MLE messages consist of a command type and a series of TLV parameters.
12//!
13//! This module, as it stands, implements the minimum subset of TLVs
14//! required to support MLE for attaching a Sleepy End Device (SED) to a
15//! Thread network.
16//!
17//! MLE for network attaching comprises a four-step handshake that works
18//! as follows:
19//!
20//! 1. A child device multicasts a Parent Request MLE command.
21//! 2. Each potential parent device on the network unicasts a Parent
22//!    Response MLE command.
23//! 3. The child device selects a parent based on a hierarchy of
24//!    connectivity metrics and unicasts a Child ID Request MLE
25//!    command.
26//! 4. The selected parent unicasts a Child ID Response MLE command.
27//!
28//! A TLV is comprised of three parts:
29//!
30//! 1. Type   - A one-byte TLV type number.
31//! 2. Length - A one-byte number representing the length of the TLV
32//!    value in bytes.
33//! 3. Value  - The TLV value.
34//!
35//! For some TLVs, the TLV type number is shifted left by one to leave the
36//! least significant bit to denote whether information in the TLV value
37//! is stable. Stable network data is data that is expected to be stable
38//! over weeks or months (Section 5.14).
39//!
40//! TLVs can be nested within a TLV value. Some types of Network Data
41//! TLVs, for example, contain sub-TLVs inside of their TLV value.
42//!
43//! To simplify variable-length TLV value decoding in Rust, TLV values are
44//! assumed to have a maximum length of 128 bytes. This assumption is made
45//! only when a variable-length value must be decoded from network byte
46//! order before it can be interpreted correctly. Excluded from this case
47//! are variable-length values that contain data that must later be
48//! decoded by the caller before being interpreted (for example,
49//! sub-TLVs). Such a value is instead returned as a slice of the original
50//! buffer passed to the decode function.
51//!
52//!
53//! Author: Mateo Garcia <mateog@stanford.edu>
54
55// TODO: Move the MLE explanation above to the MLE module, when it is created.
56
57// NOTES FOR DEBUGGING:
58// - .to_be() may not have been called on values wider than one byte
59// - encode_bytes_be may have been used instead of encode_bytes
60// - decode_bytes_be may have been used instead of decode_bytes
61// - See 4.5.25 Active Operational Dataset TLV and 4.5.26 Pending Operational Dataset TLV
62//    - Are Active and Pending Timestamp TLVs, respectively, required to be sent as well
63//      if either of the dataset tlvs are sent?
64
65use crate::net::stream::SResult;
66use crate::net::stream::{decode_bytes_be, decode_u16, decode_u32, decode_u8};
67use crate::net::stream::{encode_bytes, encode_bytes_be, encode_u16, encode_u32, encode_u8};
68use core::mem;
69
70const TL_WIDTH: usize = 2; // Type and length fields of TLV are each one byte.
71const MAX_VALUE_FIELD_LENGTH: usize = 128; // Assume a TLV value will be no longer than 128 bytes.
72
73/// Type-Length-Value structure.
74pub enum Tlv<'a> {
75    SourceAddress(u16),
76    Mode(u8),
77    Timeout(u32),
78    Challenge([u8; 8]), // Byte string max length 8 bytes.
79    Response([u8; 8]),  // Byte string max length 8 bytes.
80    LinkLayerFrameCounter(u32),
81    // LinkQuality,                  // TLV type Not used in Thread
82    // NetworkParameter,             // TLV type Not used in Thread
83    MleFrameCounter(u32),
84    /*
85    TODO: Not required to implement MLE for SED
86    Route64,
87    */
88    Address16(u16),
89    LeaderData {
90        partition_id: u32,
91        weighting: u8,
92        data_version: u8,
93        stable_data_version: u8,
94        leader_router_id: u8,
95    },
96    NetworkData(&'a [u8]),
97    TlvRequest(&'a [u8]),
98    ScanMask(u8),
99    Connectivity {
100        parent_priority: u8,
101        link_quality_3: u8,
102        link_quality_2: u8,
103        link_quality_1: u8,
104        leader_cost: u8,
105        id_sequence: u8,
106        active_routers: u8,
107        sed_buffer_size: Option<u16>,
108        sed_datagram_count: Option<u8>,
109    },
110    LinkMargin(u8),
111    Status(u8),
112    Version(u16),
113    /*
114    TODO: Not required to implement MLE for SED
115    AddressRegistration
116    AddressRegistration
117    Channel
118    PanId
119    ActiveTimestamp
120    PendingTimestamp
121    ThreadDiscovery
122    */
123    ActiveOperationalDataset(&'a [u8]),
124    PendingOperationalDataset(&'a [u8]),
125}
126
127pub fn unwrap_tlv_offset(res: SResult) -> usize {
128    match res {
129        SResult::Done(val, ()) => val,
130        _ => 0,
131    }
132}
133
134impl Tlv<'_> {
135    /// Serializes TLV data in `buf` into the format specific to the TLV
136    /// type.
137    pub fn encode(&self, buf: &mut [u8]) -> SResult {
138        match *self {
139            Tlv::SourceAddress(ref mac_address) => {
140                let value_width = mem::size_of::<u16>();
141                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
142                offset = enc_consume!(buf, offset; encode_u16, mac_address.to_be());
143                stream_done!(offset)
144            }
145            Tlv::Mode(ref mode) => {
146                let value_width = mem::size_of::<u8>();
147                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
148                offset = enc_consume!(buf, offset; encode_u8, *mode);
149                stream_done!(offset)
150            }
151            Tlv::Timeout(ref max_transmit_interval) => {
152                let value_width = mem::size_of::<u32>();
153                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
154                offset = enc_consume!(buf, offset; encode_u32, max_transmit_interval.to_be());
155                stream_done!(offset)
156            }
157            Tlv::Challenge(ref byte_str) => {
158                let value_width = byte_str.len();
159                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
160                offset = enc_consume!(buf, offset; encode_bytes_be, byte_str);
161                stream_done!(offset)
162            }
163            Tlv::Response(ref byte_str) => {
164                let value_width = byte_str.len();
165                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
166                offset = enc_consume!(buf, offset; encode_bytes_be, byte_str);
167                stream_done!(offset)
168            }
169            Tlv::LinkLayerFrameCounter(ref frame_counter) => {
170                let value_width = mem::size_of::<u32>();
171                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
172                offset = enc_consume!(buf, offset; encode_u32, frame_counter.to_be());
173                stream_done!(offset)
174            }
175            Tlv::MleFrameCounter(ref frame_counter) => {
176                let value_width = mem::size_of::<u32>();
177                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
178                offset = enc_consume!(buf, offset; encode_u32, frame_counter.to_be());
179                stream_done!(offset)
180            }
181            Tlv::Address16(ref mac_address) => {
182                let value_width = mem::size_of::<u16>();
183                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
184                offset = enc_consume!(buf, offset; encode_u16, mac_address.to_be());
185                stream_done!(offset)
186            }
187            Tlv::LeaderData {
188                partition_id,
189                weighting,
190                data_version,
191                stable_data_version,
192                leader_router_id,
193            } => {
194                let value_width = mem::size_of::<u32>()
195                    + mem::size_of::<u8>()
196                    + mem::size_of::<u8>()
197                    + mem::size_of::<u8>()
198                    + mem::size_of::<u8>();
199                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
200                offset = enc_consume!(buf, offset; encode_u32, partition_id.to_be());
201                offset = enc_consume!(buf, offset; encode_u8, weighting);
202                offset = enc_consume!(buf, offset; encode_u8, data_version);
203                offset = enc_consume!(buf, offset; encode_u8, stable_data_version);
204                offset = enc_consume!(buf, offset; encode_u8, leader_router_id);
205                stream_done!(offset)
206            }
207            Tlv::NetworkData(network_data_tlvs) => {
208                let value_width = network_data_tlvs.len();
209                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
210                offset = enc_consume!(buf, offset; encode_bytes, network_data_tlvs);
211                stream_done!(offset)
212            }
213            Tlv::TlvRequest(tlv_codes) => {
214                let value_width = tlv_codes.len();
215                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
216                offset = enc_consume!(buf, offset; encode_bytes, tlv_codes);
217                stream_done!(offset)
218            }
219            Tlv::ScanMask(ref scan_mask) => {
220                let value_width = mem::size_of::<u8>();
221                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
222                offset = enc_consume!(buf, offset; encode_u8, *scan_mask);
223                stream_done!(offset)
224            }
225            Tlv::Connectivity {
226                parent_priority,
227                link_quality_3,
228                link_quality_2,
229                link_quality_1,
230                leader_cost,
231                id_sequence,
232                active_routers,
233                sed_buffer_size,
234                sed_datagram_count,
235            } => {
236                let base_width = mem::size_of::<u8>()
237                    + mem::size_of::<u8>()
238                    + mem::size_of::<u8>()
239                    + mem::size_of::<u8>()
240                    + mem::size_of::<u8>()
241                    + mem::size_of::<u8>()
242                    + mem::size_of::<u8>();
243                let sed_buf_size_width = match sed_buffer_size {
244                    None => 0,
245                    Some(_) => mem::size_of::<u16>(),
246                };
247                let sed_datagram_cnt_width = match sed_datagram_count {
248                    None => 0,
249                    Some(_) => mem::size_of::<u8>(),
250                };
251                let value_width = base_width + sed_buf_size_width + sed_datagram_cnt_width;
252                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
253                offset = enc_consume!(buf, offset; encode_u8, parent_priority);
254                offset = enc_consume!(buf, offset; encode_u8, link_quality_3);
255                offset = enc_consume!(buf, offset; encode_u8, link_quality_2);
256                offset = enc_consume!(buf, offset; encode_u8, link_quality_1);
257                offset = enc_consume!(buf, offset; encode_u8, leader_cost);
258                offset = enc_consume!(buf, offset; encode_u8, id_sequence);
259                offset = enc_consume!(buf, offset; encode_u8, active_routers);
260                if let Some(ref buf_size) = sed_buffer_size {
261                    offset = enc_consume!(buf, offset; encode_u16, buf_size.to_be());
262                }
263                if let Some(ref datagram_cnt) = sed_datagram_count {
264                    offset = enc_consume!(buf, offset; encode_u8, *datagram_cnt);
265                }
266                stream_done!(offset)
267            }
268            Tlv::LinkMargin(ref link_margin) => {
269                let value_width = mem::size_of::<u8>();
270                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
271                offset = enc_consume!(buf, offset; encode_u8, *link_margin);
272                stream_done!(offset)
273            }
274            Tlv::Status(ref status) => {
275                let value_width = mem::size_of::<u8>();
276                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
277                offset = enc_consume!(buf, offset; encode_u8, *status);
278                stream_done!(offset)
279            }
280            Tlv::Version(ref version) => {
281                let value_width = mem::size_of::<u16>();
282                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
283                offset = enc_consume!(buf, offset; encode_u16, *version);
284                stream_done!(offset)
285            }
286            Tlv::ActiveOperationalDataset(network_mgmt_tlvs) => {
287                let value_width = network_mgmt_tlvs.len();
288                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
289                offset = enc_consume!(buf, offset; encode_bytes, network_mgmt_tlvs);
290                stream_done!(offset)
291            }
292            Tlv::PendingOperationalDataset(network_mgmt_tlvs) => {
293                let value_width = network_mgmt_tlvs.len();
294                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
295                offset = enc_consume!(buf, offset; encode_bytes, network_mgmt_tlvs);
296                stream_done!(offset)
297            }
298        }
299    }
300
301    fn encode_tl(&self, buf: &mut [u8], value_width: usize) -> SResult {
302        stream_len_cond!(buf, TL_WIDTH + value_width);
303        buf[0] = TlvType::from(self) as u8;
304        buf[1] = value_width as u8;
305        stream_done!(TL_WIDTH)
306    }
307
308    /// Deserializes TLV data from `buf` into the TLV variant specific to
309    /// the TLV type.
310    /// `SResult::Error` is returned if the type field does not match any
311    /// implemented TLV type.
312    pub fn decode(buf: &[u8]) -> SResult<Tlv> {
313        let (offset, tlv_type) = dec_try!(buf; decode_u8);
314        let tlv_type = TlvType::from(tlv_type);
315        let (offset, length) = dec_try!(buf, offset; decode_u8);
316        match tlv_type {
317            TlvType::SourceAddress => {
318                let (offset, mac_address) = dec_try!(buf, offset; decode_u16);
319                stream_done!(offset, Tlv::SourceAddress(mac_address))
320            }
321            TlvType::Mode => {
322                let (offset, mode) = dec_try!(buf, offset; decode_u8);
323                stream_done!(offset, Tlv::Mode(mode))
324            }
325            TlvType::Timeout => {
326                let (offset, max_transmit_interval) = dec_try!(buf, offset; decode_u32);
327                stream_done!(offset, Tlv::Timeout(max_transmit_interval))
328            }
329            TlvType::Challenge => {
330                let mut byte_str = [0u8; 8];
331                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut byte_str);
332                stream_done!(offset, Tlv::Challenge(byte_str))
333            }
334            TlvType::Response => {
335                let mut byte_str = [0u8; 8];
336                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut byte_str);
337                stream_done!(offset, Tlv::Response(byte_str))
338            }
339            TlvType::LinkLayerFrameCounter => {
340                let (offset, frame_counter) = dec_try!(buf, offset; decode_u32);
341                stream_done!(offset, Tlv::LinkLayerFrameCounter(frame_counter))
342            }
343            TlvType::MleFrameCounter => {
344                let (offset, frame_counter) = dec_try!(buf, offset; decode_u32);
345                stream_done!(offset, Tlv::MleFrameCounter(frame_counter))
346            }
347            TlvType::Address16 => {
348                let (offset, mac_address) = dec_try!(buf, offset; decode_u16);
349                stream_done!(offset, Tlv::Address16(mac_address))
350            }
351            TlvType::LeaderData => {
352                let (offset, partition_id) = dec_try!(buf, offset; decode_u32);
353                let (offset, weighting) = dec_try!(buf, offset; decode_u8);
354                let (offset, data_version) = dec_try!(buf, offset; decode_u8);
355                let (offset, stable_data_version) = dec_try!(buf, offset; decode_u8);
356                let (offset, leader_router_id) = dec_try!(buf, offset; decode_u8);
357                stream_done!(
358                    offset,
359                    Tlv::LeaderData {
360                        partition_id,
361                        weighting,
362                        data_version,
363                        stable_data_version,
364                        leader_router_id,
365                    }
366                )
367            }
368            TlvType::NetworkData => stream_done!(
369                offset + length as usize,
370                Tlv::NetworkData(&buf[offset..offset + length as usize])
371            ),
372            TlvType::TlvRequest => stream_done!(
373                offset + length as usize,
374                Tlv::TlvRequest(&buf[offset..offset + length as usize])
375            ),
376            TlvType::ScanMask => {
377                let (offset, scan_mask) = dec_try!(buf, offset; decode_u8);
378                stream_done!(offset, Tlv::ScanMask(scan_mask))
379            }
380            TlvType::Connectivity => {
381                let (offset, parent_priority) = dec_try!(buf, offset; decode_u8);
382                let (offset, link_quality_3) = dec_try!(buf, offset; decode_u8);
383                let (offset, link_quality_2) = dec_try!(buf, offset; decode_u8);
384                let (offset, link_quality_1) = dec_try!(buf, offset; decode_u8);
385                let (offset, leader_cost) = dec_try!(buf, offset; decode_u8);
386                let (offset, id_sequence) = dec_try!(buf, offset; decode_u8);
387                let (offset, active_routers) = dec_try!(buf, offset; decode_u8);
388                let mut offset = offset;
389                let mut sed_buffer_size = None;
390                if offset + mem::size_of::<u16>() < length as usize {
391                    let (new_offset, sed_buffer_size_raw) = dec_try!(buf, offset; decode_u16);
392                    offset = new_offset;
393                    sed_buffer_size = Some(sed_buffer_size_raw);
394                }
395                let mut sed_datagram_count = None;
396                if offset + mem::size_of::<u8>() < length as usize {
397                    let (new_offset, sed_datagram_count_raw) = dec_try!(buf, offset; decode_u8);
398                    offset = new_offset;
399                    sed_datagram_count = Some(sed_datagram_count_raw);
400                }
401                stream_done!(
402                    offset,
403                    Tlv::Connectivity {
404                        parent_priority,
405                        link_quality_3,
406                        link_quality_2,
407                        link_quality_1,
408                        leader_cost,
409                        id_sequence,
410                        active_routers,
411                        sed_buffer_size,
412                        sed_datagram_count,
413                    }
414                )
415            }
416            TlvType::LinkMargin => {
417                let (offset, link_margin) = dec_try!(buf, offset; decode_u8);
418                stream_done!(offset, Tlv::LinkMargin(link_margin))
419            }
420            TlvType::Status => {
421                let (offset, status) = dec_try!(buf, offset; decode_u8);
422                stream_done!(offset, Tlv::Status(status))
423            }
424            TlvType::Version => {
425                let (offset, version) = dec_try!(buf, offset; decode_u16);
426                stream_done!(offset, Tlv::Version(version))
427            }
428            TlvType::ActiveOperationalDataset => stream_done!(
429                offset + length as usize,
430                Tlv::ActiveOperationalDataset(&buf[offset..offset + length as usize])
431            ),
432            TlvType::PendingOperationalDataset => stream_done!(
433                offset + length as usize,
434                Tlv::PendingOperationalDataset(&buf[offset..offset + length as usize])
435            ),
436            TlvType::NotPresent => stream_err!(),
437        }
438    }
439}
440
441/// Value encoded in the type field of a Type-Length-Value (TLV)
442/// structure.
443#[repr(u8)]
444pub enum TlvType {
445    SourceAddress = 0,
446    Mode = 1,
447    Timeout = 2,
448    Challenge = 3,
449    Response = 4,
450    LinkLayerFrameCounter = 5,
451    // LinkQuality = 6,         // TLV type not used in Thread
452    // NetworkParameter = 7,    // TLV type not used in Thread
453    MleFrameCounter = 8,
454    /*
455    TODO: Not required to implement MLE for SED
456    Route64 = 9,
457    */
458    Address16 = 10,
459    LeaderData = 11,
460    NetworkData = 12,
461    TlvRequest = 13,
462    ScanMask = 14,
463    Connectivity = 15,
464    LinkMargin = 16,
465    Status = 17,
466    Version = 18,
467    /*
468    TODO: Not required to implement MLE for SED
469    AddressRegistration = 19,
470    Channel = 20,
471    PanId = 21,
472    ActiveTimestamp = 22,
473    PendingTimestamp = 23,
474    */
475    ActiveOperationalDataset = 24,
476    PendingOperationalDataset = 25,
477    /*
478    TODO: Not required to implement MLE for SED
479    ThreadDiscovery = 26,
480    */
481    NotPresent,
482}
483
484impl From<u8> for TlvType {
485    fn from(tlv_type: u8) -> Self {
486        match tlv_type {
487            0 => TlvType::SourceAddress,
488            1 => TlvType::Mode,
489            2 => TlvType::Timeout,
490            3 => TlvType::Challenge,
491            4 => TlvType::Response,
492            5 => TlvType::LinkLayerFrameCounter,
493            8 => TlvType::MleFrameCounter,
494            10 => TlvType::Address16,
495            11 => TlvType::LeaderData,
496            12 => TlvType::NetworkData,
497            13 => TlvType::TlvRequest,
498            14 => TlvType::ScanMask,
499            15 => TlvType::Connectivity,
500            16 => TlvType::LinkMargin,
501            17 => TlvType::Status,
502            18 => TlvType::Version,
503            24 => TlvType::ActiveOperationalDataset,
504            25 => TlvType::PendingOperationalDataset,
505            _ => TlvType::NotPresent,
506        }
507    }
508}
509
510impl From<&Tlv<'_>> for TlvType {
511    fn from(tlv: &Tlv<'_>) -> Self {
512        match *tlv {
513            Tlv::SourceAddress(_) => TlvType::SourceAddress,
514            Tlv::Mode(_) => TlvType::Mode,
515            Tlv::Timeout(_) => TlvType::Timeout,
516            Tlv::Challenge(_) => TlvType::Challenge,
517            Tlv::Response(_) => TlvType::Response,
518            Tlv::LinkLayerFrameCounter(_) => TlvType::LinkLayerFrameCounter,
519            Tlv::MleFrameCounter(_) => TlvType::MleFrameCounter,
520            Tlv::Address16(_) => TlvType::Address16,
521            Tlv::LeaderData { .. } => TlvType::LeaderData,
522            Tlv::NetworkData(_) => TlvType::NetworkData,
523            Tlv::TlvRequest(_) => TlvType::TlvRequest,
524            Tlv::ScanMask(_) => TlvType::ScanMask,
525            Tlv::Connectivity { .. } => TlvType::Connectivity,
526            Tlv::LinkMargin(_) => TlvType::LinkMargin,
527            Tlv::Status(_) => TlvType::Status,
528            Tlv::Version(_) => TlvType::Version,
529            Tlv::ActiveOperationalDataset(_) => TlvType::ActiveOperationalDataset,
530            Tlv::PendingOperationalDataset(_) => TlvType::PendingOperationalDataset,
531        }
532    }
533}
534
535/// Used in Mode TLV.
536#[repr(u8)]
537pub enum LinkMode {
538    ReceiverOnWhenIdle = 0b0000_1000,
539    SecureDataRequests = 0b0000_0100,
540    FullThreadDevice = 0b0000_0010,
541    FullNetworkDataRequired = 0b0000_0001,
542}
543
544/// Used in Scan Mask TLV.
545#[repr(u8)]
546pub enum MulticastResponder {
547    Router = 0b1000_0000,
548    EndDevice = 0b0100_0000,
549}
550
551/// Used in Connectivity TLV.
552pub enum ParentPriority {
553    // Reserved = 0b1000_0000
554    High = 0b0100_0000,
555    Medium = 0b0000_0000,
556    Low = 0b1100_0000,
557}
558
559/// These TLVs are contained within the value of a Network Data TLV.
560/// See Section 5.18.
561pub enum NetworkDataTlv<'a> {
562    Prefix {
563        domain_id: u8,
564        prefix_length_bits: u8,
565        prefix: [u8; 3], // IPv6 prefix max length 48 bits.
566        sub_tlvs: &'a [u8],
567    },
568    CommissioningData {
569        com_length: u8,
570        com_data: [u8; MAX_VALUE_FIELD_LENGTH],
571    },
572    Service {
573        thread_enterprise_number: bool,
574        // See 5.18.6.
575        s_id: u8,
576        s_enterprise_number: u32,
577        s_service_data_length: u8,
578        s_service_data: [u8; MAX_VALUE_FIELD_LENGTH],
579        sub_tlvs: &'a [u8],
580    },
581}
582
583impl NetworkDataTlv<'_> {
584    /// Serializes TLV data in `buf` into the format specific to the
585    /// Network Data TLV type.
586    pub fn encode(&self, buf: &mut [u8], stable: bool) -> SResult {
587        match *self {
588            NetworkDataTlv::Prefix {
589                domain_id,
590                prefix_length_bits,
591                prefix,
592                sub_tlvs,
593            } => {
594                let value_width =
595                    mem::size_of::<u8>() + mem::size_of::<u8>() + prefix.len() + sub_tlvs.len();
596                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
597                offset = enc_consume!(buf, offset; encode_u8, domain_id);
598                offset = enc_consume!(buf, offset; encode_u8, prefix_length_bits);
599                offset = enc_consume!(buf, offset; encode_bytes_be, &prefix);
600                offset = enc_consume!(buf, offset; encode_bytes, sub_tlvs);
601                stream_done!(offset)
602            }
603            NetworkDataTlv::CommissioningData {
604                com_length,
605                com_data,
606            } => {
607                let value_width = com_length as usize;
608                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
609                offset = enc_consume!(buf, offset; encode_bytes_be, &com_data);
610                stream_done!(offset)
611            }
612            NetworkDataTlv::Service {
613                thread_enterprise_number,
614                s_id,
615                s_enterprise_number,
616                s_service_data_length,
617                s_service_data,
618                sub_tlvs,
619            } => {
620                let value_width = mem::size_of::<u8>()
621                    + mem::size_of::<u32>()
622                    + mem::size_of::<u8>()
623                    + s_service_data.len()
624                    + sub_tlvs.len();
625                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
626                let t_bit: u8 = if thread_enterprise_number {
627                    1u8 << 7
628                } else {
629                    0
630                };
631                let first_byte: u8 = t_bit | (0b1111 & s_id);
632                offset = enc_consume!(buf, offset; encode_u8, first_byte);
633                offset = enc_consume!(buf, offset; encode_u32, s_enterprise_number.to_be());
634                offset = enc_consume!(buf, offset; encode_u8, s_service_data_length);
635                offset = enc_consume!(buf, offset; encode_bytes_be, &s_service_data);
636                offset = enc_consume!(buf, offset; encode_bytes, sub_tlvs);
637                stream_done!(offset)
638            }
639        }
640    }
641
642    fn encode_tl(&self, buf: &mut [u8], value_width: usize, stable: bool) -> SResult {
643        stream_len_cond!(buf, TL_WIDTH + value_width);
644        let stable_bit = u8::from(stable);
645        buf[0] = (NetworkDataTlvType::from(self) as u8) << 1 | stable_bit;
646        buf[1] = value_width as u8;
647        stream_done!(TL_WIDTH)
648    }
649
650    /// Deserializes TLV data from `buf` into the Network Data TLV variant
651    /// specific to the TLV type.
652    /// Returns NetworkDataTlv and true if the data stable, false
653    /// otherwise.
654    /// `SResult::Error` is returned if the type field does not match any
655    /// implemented TLV type.
656    pub fn decode(buf: &[u8]) -> SResult<(NetworkDataTlv, bool)> {
657        let (offset, tlv_type_field) = dec_try!(buf; decode_u8);
658        let tlv_type_raw = tlv_type_field >> 1;
659        let tlv_type = NetworkDataTlvType::from(tlv_type_raw);
660        let stable = (tlv_type_field & 1u8) > 0;
661        let (offset, length) = dec_try!(buf, offset; decode_u8);
662        match tlv_type {
663            NetworkDataTlvType::Prefix => {
664                let (offset, domain_id) = dec_try!(buf, offset; decode_u8);
665                let (offset, prefix_length_bits) = dec_try!(buf, offset; decode_u8);
666                let mut prefix = [0u8; 3];
667                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut prefix);
668                stream_done!(
669                    offset + length as usize,
670                    (
671                        NetworkDataTlv::Prefix {
672                            domain_id,
673                            prefix_length_bits,
674                            prefix,
675                            sub_tlvs: &buf[offset..offset + length as usize],
676                        },
677                        stable
678                    )
679                )
680            }
681            NetworkDataTlvType::CommissioningData => {
682                let (offset, com_length) = dec_try!(buf, offset; decode_u8);
683                let mut com_data = [0u8; MAX_VALUE_FIELD_LENGTH];
684                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut com_data);
685                stream_done!(
686                    offset,
687                    (
688                        NetworkDataTlv::CommissioningData {
689                            com_length,
690                            com_data,
691                        },
692                        stable
693                    )
694                )
695            }
696            NetworkDataTlvType::Service => {
697                let (offset, first_byte) = dec_try!(buf, offset; decode_u8);
698                let thread_enterprise_number = (first_byte >> 7) > 0;
699                let s_id = first_byte & 0b1111;
700                let (offset, s_enterprise_number) = dec_try!(buf, offset; decode_u32);
701                let (offset, s_service_data_length) = dec_try!(buf, offset; decode_u8);
702                let mut s_service_data = [0u8; MAX_VALUE_FIELD_LENGTH];
703                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut s_service_data);
704                stream_done!(
705                    offset + length as usize,
706                    (
707                        NetworkDataTlv::Service {
708                            thread_enterprise_number,
709                            s_id,
710                            s_enterprise_number,
711                            s_service_data_length,
712                            s_service_data,
713                            sub_tlvs: &buf[offset..offset + length as usize],
714                        },
715                        stable
716                    )
717                )
718            }
719            NetworkDataTlvType::NotPresent => stream_err!(),
720        }
721    }
722}
723
724/// Value encoded in the type field of a Network Data TLV.
725/// Gaps in type numbers are filled by PrefixSubTlv and ServiceSubTlv.
726#[repr(u8)]
727pub enum NetworkDataTlvType {
728    Prefix = 1,
729    CommissioningData = 4,
730    Service = 5,
731    NotPresent,
732}
733
734impl From<u8> for NetworkDataTlvType {
735    fn from(tlv_type: u8) -> Self {
736        match tlv_type {
737            1 => NetworkDataTlvType::Prefix,
738            4 => NetworkDataTlvType::CommissioningData,
739            5 => NetworkDataTlvType::Service,
740            _ => NetworkDataTlvType::NotPresent,
741        }
742    }
743}
744
745impl From<&NetworkDataTlv<'_>> for NetworkDataTlvType {
746    fn from(network_data_tlv: &NetworkDataTlv<'_>) -> Self {
747        match *network_data_tlv {
748            NetworkDataTlv::Prefix { .. } => NetworkDataTlvType::Prefix,
749            NetworkDataTlv::CommissioningData { .. } => NetworkDataTlvType::CommissioningData,
750            NetworkDataTlv::Service { .. } => NetworkDataTlvType::Service,
751        }
752    }
753}
754
755/// These TLVs are contained within the value of a Prefix TLV.
756pub enum PrefixSubTlv<'a> {
757    HasRoute(&'a [u8]),
758    BorderRouter(&'a [u8]),
759    SixLoWpanId {
760        context_id_compress: bool,
761        context_id: u8,
762        context_length: u8,
763    },
764}
765
766impl PrefixSubTlv<'_> {
767    /// Serializes TLV data in `buf` into the format specific to the
768    /// Prefix sub-TLV type.
769    pub fn encode(&self, buf: &mut [u8], stable: bool) -> SResult {
770        match *self {
771            PrefixSubTlv::HasRoute(r_border_router_16s) => {
772                let value_width = r_border_router_16s.len();
773                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
774                offset = enc_consume!(buf, offset; encode_bytes, r_border_router_16s);
775                stream_done!(offset)
776            }
777            PrefixSubTlv::BorderRouter(p_border_router_16s) => {
778                let value_width = p_border_router_16s.len();
779                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
780                offset = enc_consume!(buf, offset; encode_bytes, p_border_router_16s);
781                stream_done!(offset)
782            }
783            PrefixSubTlv::SixLoWpanId {
784                context_id_compress,
785                context_id,
786                context_length,
787            } => {
788                let value_width = mem::size_of::<u8>() + mem::size_of::<u8>();
789                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
790                let compress_bit = u8::from(context_id_compress);
791                let first_byte = (compress_bit << 4) | (context_id & 0b1111);
792                offset = enc_consume!(buf, offset; encode_u8, first_byte);
793                offset = enc_consume!(buf, offset; encode_u8, context_length);
794                stream_done!(offset)
795            }
796        }
797    }
798
799    fn encode_tl(&self, buf: &mut [u8], value_width: usize, stable: bool) -> SResult {
800        stream_len_cond!(buf, TL_WIDTH + value_width);
801        let stable_bit = u8::from(stable);
802        buf[0] = (PrefixSubTlvType::from(self) as u8) << 1 | stable_bit;
803        buf[1] = value_width as u8;
804        stream_done!(TL_WIDTH)
805    }
806
807    /// Deserializes TLV data from `buf` into the Prefix sub-TLV variant
808    /// specific to the TLV type.
809    /// Returns PrefixSubTlv and true if the data stable, false
810    /// otherwise.
811    /// `SResult::Error` is returned if the type field does not match any
812    /// implemented TLV type.
813    pub fn decode(buf: &[u8]) -> SResult<(PrefixSubTlv, bool)> {
814        let (offset, tlv_type_field) = dec_try!(buf; decode_u8);
815        let tlv_type_raw = tlv_type_field >> 1;
816        let tlv_type = PrefixSubTlvType::from(tlv_type_raw);
817        let stable = (tlv_type_field & 1u8) > 0;
818        let (offset, length) = dec_try!(buf, offset; decode_u8);
819        match tlv_type {
820            PrefixSubTlvType::HasRoute => stream_done!(
821                offset + length as usize,
822                (
823                    PrefixSubTlv::HasRoute(&buf[offset..offset + length as usize]),
824                    stable
825                )
826            ),
827            PrefixSubTlvType::BorderRouter => stream_done!(
828                offset + length as usize,
829                (
830                    PrefixSubTlv::BorderRouter(&buf[offset..offset + length as usize]),
831                    stable
832                )
833            ),
834            PrefixSubTlvType::SixLoWpanId => {
835                let (offset, first_byte) = dec_try!(buf, offset; decode_u8);
836                let context_id_compress = (first_byte & 0b1_0000) > 0;
837                let context_id = first_byte & 0b1111;
838                let (offset, context_length) = dec_try!(buf, offset; decode_u8);
839                stream_done!(
840                    offset,
841                    (
842                        PrefixSubTlv::SixLoWpanId {
843                            context_id_compress,
844                            context_id,
845                            context_length,
846                        },
847                        stable
848                    )
849                )
850            }
851            PrefixSubTlvType::NotPresent => stream_err!(),
852        }
853    }
854}
855
856/// Value encoded in the type field of a Prefix sub-TLV.
857/// Gaps in type numbers are filled by NetworkDataTlv and ServiceSubTlv.
858#[repr(u8)]
859pub enum PrefixSubTlvType {
860    HasRoute = 0,
861    BorderRouter = 2,
862    SixLoWpanId = 3,
863    NotPresent,
864}
865
866impl From<u8> for PrefixSubTlvType {
867    fn from(tlv_type: u8) -> Self {
868        match tlv_type {
869            0 => PrefixSubTlvType::HasRoute,
870            2 => PrefixSubTlvType::BorderRouter,
871            3 => PrefixSubTlvType::SixLoWpanId,
872            _ => PrefixSubTlvType::NotPresent,
873        }
874    }
875}
876
877impl From<&PrefixSubTlv<'_>> for PrefixSubTlvType {
878    fn from(prefix_sub_tlv: &PrefixSubTlv<'_>) -> Self {
879        match *prefix_sub_tlv {
880            PrefixSubTlv::HasRoute(_) => PrefixSubTlvType::HasRoute,
881            PrefixSubTlv::BorderRouter(_) => PrefixSubTlvType::BorderRouter,
882            PrefixSubTlv::SixLoWpanId { .. } => PrefixSubTlvType::SixLoWpanId,
883        }
884    }
885}
886
887/// Used in Has Route TLV.
888pub struct HasRouteTlvValue {
889    // See 5.18.1.
890    r_border_router_16: u16,
891    r_preference: u8,
892}
893
894impl HasRouteTlvValue {
895    /// Serializes this Has Route TLV value into `buf`.
896    pub fn encode(&self, buf: &mut [u8]) -> SResult {
897        stream_len_cond!(buf, 3);
898        let mut offset = enc_consume!(buf, 0; encode_u16, self.r_border_router_16.to_be());
899        let last_byte = (self.r_preference & 0b11) << 6;
900        offset = enc_consume!(buf, offset; encode_u8, last_byte);
901        stream_done!(offset)
902    }
903
904    /// Deserializes Has Route TLV value from `buf` and returns it.
905    pub fn decode(buf: &[u8]) -> SResult<HasRouteTlvValue> {
906        stream_len_cond!(buf, 3);
907        let (offset, r_border_router_16) = dec_try!(buf; decode_u16);
908        let (offset, last_byte) = dec_try!(buf, offset; decode_u8);
909        let r_preference = last_byte >> 6;
910        stream_done!(
911            offset,
912            HasRouteTlvValue {
913                r_border_router_16,
914                r_preference,
915            }
916        )
917    }
918}
919
920/// Used in Border Router TLV.
921pub struct BorderRouterTlvValue {
922    // See 5.18.3.
923    p_border_router_16: u16,
924    p_bits: u16,
925}
926
927/// Used in Border Router TLV value.
928#[repr(u16)]
929pub enum BorderRouterTlvValueBit {
930    // See 5.18.3 for a more detailed explanation of each.
931    Prf = 0b1100_0000_0000_0000, // Preference
932    P = 0b0010_0000_0000_0000,   // Preferred
933    S = 0b0001_0000_0000_0000,   // SLAAC
934    D = 0b0000_1000_0000_0000,   // DHCP
935    C = 0b0000_0100_0000_0000,   // Configure
936    R = 0b0000_0010_0000_0000,   // Default
937    O = 0b0000_0001_0000_0000,   // On mesh
938    N = 0b0000_0000_1000_0000,   // NDDNS
939}
940
941impl BorderRouterTlvValue {
942    /// Serializes this Border Route TLV value into `buf`.
943    pub fn encode(&self, buf: &mut [u8]) -> SResult {
944        stream_len_cond!(buf, 4); // Each Border Router TLV value is 32 bits wide.
945        let mut offset = enc_consume!(buf, 0; encode_u16, self.p_border_router_16.to_be());
946        offset = enc_consume!(buf, offset; encode_u16, self.p_bits.to_be());
947        stream_done!(offset)
948    }
949
950    /// Deserializes Border Route TLV value from `buf` and returns it.
951    pub fn decode(buf: &[u8]) -> SResult<BorderRouterTlvValue> {
952        let (offset, p_border_router_16) = dec_try!(buf; decode_u16);
953        let (offset, p_bits) = dec_try!(buf, offset; decode_u16);
954        stream_done!(
955            offset,
956            BorderRouterTlvValue {
957                p_border_router_16,
958                p_bits,
959            }
960        )
961    }
962}
963
964/// These TLVs are contained within the value of a Service TLV.
965pub enum ServiceSubTlv {
966    Server {
967        // See 5.18.6.
968        s_server_16: u16,
969        s_server_data: [u8; MAX_VALUE_FIELD_LENGTH],
970    },
971}
972
973impl ServiceSubTlv {
974    /// Serializes TLV data in `buf` into the format specific to the
975    /// Service sub-TLV type.
976    pub fn encode(&self, buf: &mut [u8], stable: bool) -> SResult {
977        match *self {
978            ServiceSubTlv::Server {
979                s_server_16,
980                s_server_data,
981            } => {
982                let value_width = mem::size_of::<u16>() + s_server_data.len();
983                let mut offset = enc_consume!(buf; self; encode_tl, value_width, stable);
984                offset = enc_consume!(buf, offset; encode_u16, s_server_16.to_be());
985                offset = enc_consume!(buf, offset; encode_bytes_be, &s_server_data);
986                stream_done!(offset)
987            }
988        }
989    }
990
991    fn encode_tl(&self, buf: &mut [u8], value_width: usize, stable: bool) -> SResult {
992        stream_len_cond!(buf, TL_WIDTH + value_width);
993        let stable_bit = u8::from(stable);
994        buf[0] = (ServiceSubTlvType::from(self) as u8) << 1 | stable_bit;
995        buf[1] = value_width as u8;
996        stream_done!(TL_WIDTH)
997    }
998
999    /// Deserializes TLV data from `buf` into the Service sub-TLV variant
1000    /// specific to the TLV type.
1001    /// Returns ServiceSubTlv and true if the data stable, false
1002    /// otherwise.
1003    /// `SResult::Error` is returned if the type field does not match any
1004    /// implemented TLV type.
1005    pub fn decode(buf: &[u8]) -> SResult<(ServiceSubTlv, bool)> {
1006        let (offset, tlv_type_field) = dec_try!(buf; decode_u8);
1007        let tlv_type_raw = tlv_type_field >> 1;
1008        let tlv_type = ServiceSubTlvType::from(tlv_type_raw);
1009        let stable = (tlv_type_field & 1u8) > 0;
1010        let (offset, _) = dec_try!(buf, offset; decode_u8);
1011        match tlv_type {
1012            ServiceSubTlvType::Server => {
1013                let (offset, s_server_16) = dec_try!(buf, offset; decode_u16);
1014                let mut s_server_data = [0u8; MAX_VALUE_FIELD_LENGTH];
1015                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut s_server_data);
1016                stream_done!(
1017                    offset,
1018                    (
1019                        ServiceSubTlv::Server {
1020                            s_server_16,
1021                            s_server_data,
1022                        },
1023                        stable
1024                    )
1025                )
1026            }
1027            ServiceSubTlvType::NotPresent => stream_err!(),
1028        }
1029    }
1030}
1031
1032/// Value encoded in the type field of a Service sub-TLV.
1033/// Gaps in type numbers are filled by NetworkDataTlv and PrefixSubTlv.
1034#[repr(u8)]
1035pub enum ServiceSubTlvType {
1036    Server = 6,
1037    NotPresent,
1038}
1039
1040impl From<u8> for ServiceSubTlvType {
1041    fn from(tlv_type: u8) -> Self {
1042        match tlv_type {
1043            6 => ServiceSubTlvType::Server,
1044            _ => ServiceSubTlvType::NotPresent,
1045        }
1046    }
1047}
1048
1049impl From<&ServiceSubTlv> for ServiceSubTlvType {
1050    fn from(service_sub_tlv: &ServiceSubTlv) -> Self {
1051        match *service_sub_tlv {
1052            ServiceSubTlv::Server { .. } => ServiceSubTlvType::Server,
1053        }
1054    }
1055}
1056
1057/// These TLVs are contained within the value of a Pending Operational
1058/// Dataset TLV or an Active Operational Dataset TLV.
1059/// See Section 8.10.1.
1060pub enum NetworkManagementTlv<'a> {
1061    Channel {
1062        channel_page: u8,
1063        channel: u16,
1064    },
1065    PanId(u16),
1066    ExtendedPanId([u8; 8]),             // Extended PAN ID length 8 bytes.
1067    NetworkName([u8; 16]),              // Network name max length 16 bytes.
1068    Pskc([u8; 16]),                     // PSKc max length 16 bytes.
1069    NetworkMasterKey([u8; 16]),         // Master key length 128 bits = 16 bytes.
1070    NetworkKeySequenceCounter([u8; 4]), // Counter length 4 bytes.
1071    NetworkMeshLocalPrefix([u8; 8]),    // Mesh-Local Prefix length 8 bytes.
1072    SteeringData([u8; 16]),             // Bloom filter max length 16 bytes.
1073    BorderAgentLocator(u16),
1074    CommissionerId([u8; 64]), // Commissioner ID max length 64 bytes.
1075    CommissionerSessionId(u16),
1076    SecurityPolicy {
1077        rotation_time: u16,
1078        policy_bits: u8,
1079    },
1080    ActiveTimestamp {
1081        timestamp_seconds: [u8; 3], // Timestamp seconds is a 48-bit Unix time value.
1082        timestamp_ticks: u16,
1083        u_bit: bool,
1084    },
1085    CommissionerUdpPort(u16),
1086    PendingTimestamp {
1087        timestamp_seconds: [u8; 3], // Timestamp seconds is a 48-bit Unix time value.
1088        timestamp_ticks: u16,
1089        u_bit: bool,
1090    },
1091    DelayTimer(u32),
1092    ChannelMask(&'a [u8]),
1093}
1094
1095impl NetworkManagementTlv<'_> {
1096    /// Serializes TLV data in `buf` into the format specific to the
1097    /// Network Management TLV type.
1098    pub fn encode(&self, buf: &mut [u8]) -> SResult {
1099        match *self {
1100            NetworkManagementTlv::Channel {
1101                channel_page,
1102                channel,
1103            } => {
1104                // `channel_page` should be 0 (See 8.10.1.1.1)
1105                // `channel` should be 11-26 (See 8.10.1.1.2)
1106                let value_width = mem::size_of::<u8>() + mem::size_of::<u16>();
1107                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1108                offset = enc_consume!(buf, offset; encode_u8, channel_page);
1109                offset = enc_consume!(buf, offset; encode_u16, channel.to_be());
1110                stream_done!(offset)
1111            }
1112            NetworkManagementTlv::PanId(ref pan_id) => {
1113                let value_width = mem::size_of::<u16>();
1114                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1115                offset = enc_consume!(buf, offset; encode_u16, pan_id.to_be());
1116                stream_done!(offset)
1117            }
1118            NetworkManagementTlv::ExtendedPanId(ref extended_pan_id) => {
1119                let value_width = extended_pan_id.len();
1120                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1121                offset = enc_consume!(buf, offset; encode_bytes_be, extended_pan_id);
1122                stream_done!(offset)
1123            }
1124            NetworkManagementTlv::NetworkName(ref network_name) => {
1125                stream_cond!(network_name.len() <= 16);
1126                let value_width = network_name.len();
1127                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1128                offset = enc_consume!(buf, offset; encode_bytes_be, network_name);
1129                stream_done!(offset)
1130            }
1131            NetworkManagementTlv::Pskc(ref pskc) => {
1132                stream_cond!(pskc.len() <= 16);
1133                let value_width = pskc.len();
1134                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1135                offset = enc_consume!(buf, offset; encode_bytes_be, pskc);
1136                stream_done!(offset)
1137            }
1138            NetworkManagementTlv::NetworkMasterKey(ref network_key) => {
1139                let value_width = network_key.len();
1140                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1141                offset = enc_consume!(buf, offset; encode_bytes_be, network_key);
1142                stream_done!(offset)
1143            }
1144            NetworkManagementTlv::NetworkKeySequenceCounter(ref counter) => {
1145                let value_width = counter.len();
1146                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1147                offset = enc_consume!(buf, offset; encode_bytes_be, counter);
1148                stream_done!(offset)
1149            }
1150            NetworkManagementTlv::NetworkMeshLocalPrefix(ref prefix) => {
1151                let value_width = prefix.len();
1152                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1153                offset = enc_consume!(buf, offset; encode_bytes_be, prefix);
1154                stream_done!(offset)
1155            }
1156            NetworkManagementTlv::SteeringData(ref bloom_filter) => {
1157                stream_cond!(bloom_filter.len() <= 16);
1158                let value_width = bloom_filter.len();
1159                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1160                offset = enc_consume!(buf, offset; encode_bytes_be, bloom_filter);
1161                stream_done!(offset)
1162            }
1163            NetworkManagementTlv::BorderAgentLocator(ref rloc_16) => {
1164                let value_width = mem::size_of::<u16>();
1165                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1166                offset = enc_consume!(buf, offset; encode_u16, rloc_16.to_be());
1167                stream_done!(offset)
1168            }
1169            NetworkManagementTlv::CommissionerId(ref commissioner_id) => {
1170                stream_cond!(commissioner_id.len() <= 64);
1171                let value_width = commissioner_id.len();
1172                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1173                offset = enc_consume!(buf, offset; encode_bytes_be, commissioner_id);
1174                stream_done!(offset)
1175            }
1176            NetworkManagementTlv::CommissionerSessionId(ref session_id) => {
1177                let value_width = mem::size_of::<u16>();
1178                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1179                offset = enc_consume!(buf, offset; encode_u16, session_id.to_be());
1180                stream_done!(offset)
1181            }
1182            NetworkManagementTlv::SecurityPolicy {
1183                rotation_time,
1184                policy_bits,
1185            } => {
1186                let value_width = mem::size_of::<u16>() + mem::size_of::<u8>();
1187                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1188                offset = enc_consume!(buf, offset; encode_u16, rotation_time.to_be());
1189                offset = enc_consume!(buf, offset; encode_u8, policy_bits);
1190                stream_done!(offset)
1191            }
1192            NetworkManagementTlv::ActiveTimestamp {
1193                timestamp_seconds,
1194                timestamp_ticks,
1195                u_bit,
1196            } => {
1197                let value_width = timestamp_seconds.len() + mem::size_of::<u16>();
1198                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1199                offset = enc_consume!(buf, offset; encode_bytes_be, &timestamp_seconds);
1200                let u_bit_val = u16::from(u_bit);
1201                let end_bytes = (timestamp_ticks << 1) | u_bit_val;
1202                offset = enc_consume!(buf, offset; encode_u16, end_bytes.to_be());
1203                stream_done!(offset)
1204            }
1205            NetworkManagementTlv::CommissionerUdpPort(udp_port) => {
1206                let value_width = mem::size_of::<u16>();
1207                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1208                offset = enc_consume!(buf, offset; encode_u16, udp_port.to_be());
1209                stream_done!(offset)
1210            }
1211            NetworkManagementTlv::PendingTimestamp {
1212                timestamp_seconds,
1213                timestamp_ticks,
1214                u_bit,
1215            } => {
1216                let value_width = timestamp_seconds.len() + mem::size_of::<u16>();
1217                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1218                offset = enc_consume!(buf, offset; encode_bytes_be, &timestamp_seconds);
1219                let u_bit_val = u16::from(u_bit);
1220                let end_bytes = (timestamp_ticks << 1) | u_bit_val;
1221                offset = enc_consume!(buf, offset; encode_u16, end_bytes.to_be());
1222                stream_done!(offset)
1223            }
1224            NetworkManagementTlv::DelayTimer(time_remaining) => {
1225                let value_width = mem::size_of::<u32>();
1226                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1227                offset = enc_consume!(buf, offset; encode_u32, time_remaining.to_be());
1228                stream_done!(offset)
1229            }
1230            NetworkManagementTlv::ChannelMask(entries) => {
1231                let value_width = entries.len();
1232                let mut offset = enc_consume!(buf; self; encode_tl, value_width);
1233                offset = enc_consume!(buf, offset; encode_bytes, entries);
1234                stream_done!(offset)
1235            }
1236        }
1237    }
1238
1239    fn encode_tl(&self, buf: &mut [u8], value_width: usize) -> SResult {
1240        stream_len_cond!(buf, TL_WIDTH + value_width);
1241        buf[0] = NetworkManagementTlvType::from(self) as u8;
1242        buf[1] = value_width as u8;
1243        stream_done!(TL_WIDTH)
1244    }
1245
1246    /// Deserializes TLV data from `buf` into the Network Management TLV
1247    /// variant specific to the TLV type.
1248    /// Returns ServiceSubTlv and true if the data stable, false
1249    /// otherwise.
1250    /// `SResult::Error` is returned if the type field does not match any
1251    /// implemented TLV type.
1252    pub fn decode(buf: &[u8]) -> SResult<NetworkManagementTlv> {
1253        let (offset, tlv_type_raw) = dec_try!(buf; decode_u8);
1254        let tlv_type = NetworkManagementTlvType::from(tlv_type_raw);
1255        let (offset, length) = dec_try!(buf, offset; decode_u8);
1256        match tlv_type {
1257            NetworkManagementTlvType::Channel => {
1258                let (offset, channel_page) = dec_try!(buf, offset; decode_u8);
1259                let (offset, channel) = dec_try!(buf, offset; decode_u16);
1260                stream_done!(
1261                    offset,
1262                    NetworkManagementTlv::Channel {
1263                        channel_page,
1264                        channel,
1265                    }
1266                )
1267            }
1268            NetworkManagementTlvType::PanId => {
1269                let (offset, pan_id) = dec_try!(buf, offset; decode_u16);
1270                stream_done!(offset, NetworkManagementTlv::PanId(pan_id))
1271            }
1272            NetworkManagementTlvType::ExtendedPanId => {
1273                let mut extended_pan_id = [0u8; 8];
1274                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut extended_pan_id);
1275                stream_done!(offset, NetworkManagementTlv::ExtendedPanId(extended_pan_id))
1276            }
1277            NetworkManagementTlvType::NetworkName => {
1278                let mut network_name = [0u8; 16];
1279                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut network_name);
1280                stream_done!(offset, NetworkManagementTlv::NetworkName(network_name))
1281            }
1282            NetworkManagementTlvType::Pskc => {
1283                let mut pskc = [0u8; 16];
1284                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut pskc);
1285                stream_done!(offset, NetworkManagementTlv::Pskc(pskc))
1286            }
1287            NetworkManagementTlvType::NetworkMasterKey => {
1288                let mut network_key = [0u8; 16];
1289                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut network_key);
1290                stream_done!(offset, NetworkManagementTlv::NetworkMasterKey(network_key))
1291            }
1292            NetworkManagementTlvType::NetworkKeySequenceCounter => {
1293                let mut counter = [0u8; 4];
1294                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut counter);
1295                stream_done!(
1296                    offset,
1297                    NetworkManagementTlv::NetworkKeySequenceCounter(counter)
1298                )
1299            }
1300            NetworkManagementTlvType::NetworkMeshLocalPrefix => {
1301                let mut prefix = [0u8; 8];
1302                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut prefix);
1303                stream_done!(offset, NetworkManagementTlv::NetworkMeshLocalPrefix(prefix))
1304            }
1305            NetworkManagementTlvType::SteeringData => {
1306                let mut bloom_filter = [0u8; 16];
1307                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut bloom_filter);
1308                stream_done!(offset, NetworkManagementTlv::SteeringData(bloom_filter))
1309            }
1310            NetworkManagementTlvType::BorderAgentLocator => {
1311                let (offset, rloc_16) = dec_try!(buf, offset; decode_u16);
1312                stream_done!(offset, NetworkManagementTlv::BorderAgentLocator(rloc_16))
1313            }
1314            NetworkManagementTlvType::CommissionerId => {
1315                let mut commissioner_id = [0u8; 64];
1316                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut commissioner_id);
1317                stream_done!(
1318                    offset,
1319                    NetworkManagementTlv::CommissionerId(commissioner_id)
1320                )
1321            }
1322            NetworkManagementTlvType::CommissionerSessionId => {
1323                let (offset, session_id) = dec_try!(buf, offset; decode_u16);
1324                stream_done!(
1325                    offset,
1326                    NetworkManagementTlv::CommissionerSessionId(session_id)
1327                )
1328            }
1329            NetworkManagementTlvType::SecurityPolicy => {
1330                let (offset, rotation_time) = dec_try!(buf, offset; decode_u16);
1331                let (offset, policy_bits) = dec_try!(buf, offset; decode_u8);
1332                stream_done!(
1333                    offset,
1334                    NetworkManagementTlv::SecurityPolicy {
1335                        rotation_time,
1336                        policy_bits,
1337                    }
1338                )
1339            }
1340            NetworkManagementTlvType::ActiveTimestamp => {
1341                let mut timestamp_seconds = [0u8; 3];
1342                let offset = dec_consume!(buf, offset; decode_bytes_be, &mut timestamp_seconds);
1343                let (offset, timestamp_ticks) = dec_try!(buf, offset; decode_u16);
1344                stream_done!(
1345                    offset,
1346                    NetworkManagementTlv::ActiveTimestamp {
1347                        timestamp_seconds,
1348                        timestamp_ticks: timestamp_ticks >> 1,
1349                        u_bit: (timestamp_ticks & 1u16) > 0,
1350                    }
1351                )
1352            }
1353            NetworkManagementTlvType::CommissionerUdpPort => {
1354                let (offset, udp_port) = dec_try!(buf, offset; decode_u16);
1355                stream_done!(offset, NetworkManagementTlv::CommissionerUdpPort(udp_port))
1356            }
1357            NetworkManagementTlvType::PendingTimestamp => {
1358                let mut timestamp_seconds = [0u8; 3];
1359                let offset = dec_consume!(buf; decode_bytes_be, &mut timestamp_seconds);
1360                let (offset, timestamp_ticks) = dec_try!(buf, offset; decode_u16);
1361                stream_done!(
1362                    offset,
1363                    NetworkManagementTlv::PendingTimestamp {
1364                        timestamp_seconds,
1365                        timestamp_ticks: timestamp_ticks >> 1,
1366                        u_bit: (timestamp_ticks & 1u16) > 0,
1367                    }
1368                )
1369            }
1370            NetworkManagementTlvType::DelayTimer => {
1371                let (offset, time_remaining) = dec_try!(buf, offset; decode_u32);
1372                stream_done!(offset, NetworkManagementTlv::DelayTimer(time_remaining))
1373            }
1374            NetworkManagementTlvType::ChannelMask => stream_done!(
1375                offset + length as usize,
1376                NetworkManagementTlv::ChannelMask(&buf[offset..offset + length as usize])
1377            ),
1378            NetworkManagementTlvType::NotPresent => stream_err!(),
1379        }
1380    }
1381}
1382
1383/// Value encoded in the type field of a Network Management TLV.
1384#[repr(u8)]
1385pub enum NetworkManagementTlvType {
1386    Channel = 0,
1387    PanId = 1,
1388    ExtendedPanId = 2,
1389    NetworkName = 3,
1390    Pskc = 4,
1391    NetworkMasterKey = 5,
1392    NetworkKeySequenceCounter = 6,
1393    NetworkMeshLocalPrefix = 7,
1394    SteeringData = 8,
1395    BorderAgentLocator = 9,
1396    CommissionerId = 10,
1397    CommissionerSessionId = 11,
1398    SecurityPolicy = 12,
1399    ActiveTimestamp = 14,
1400    CommissionerUdpPort = 15,
1401    PendingTimestamp = 51,
1402    DelayTimer = 52,
1403    ChannelMask = 53,
1404    NotPresent,
1405}
1406
1407impl From<u8> for NetworkManagementTlvType {
1408    fn from(type_num: u8) -> Self {
1409        match type_num {
1410            0 => NetworkManagementTlvType::Channel,
1411            1 => NetworkManagementTlvType::PanId,
1412            2 => NetworkManagementTlvType::ExtendedPanId,
1413            3 => NetworkManagementTlvType::NetworkName,
1414            4 => NetworkManagementTlvType::Pskc,
1415            5 => NetworkManagementTlvType::NetworkMasterKey,
1416            6 => NetworkManagementTlvType::NetworkKeySequenceCounter,
1417            7 => NetworkManagementTlvType::NetworkMeshLocalPrefix,
1418            8 => NetworkManagementTlvType::SteeringData,
1419            9 => NetworkManagementTlvType::BorderAgentLocator,
1420            10 => NetworkManagementTlvType::CommissionerId,
1421            11 => NetworkManagementTlvType::CommissionerSessionId,
1422            12 => NetworkManagementTlvType::SecurityPolicy,
1423            14 => NetworkManagementTlvType::ActiveTimestamp,
1424            15 => NetworkManagementTlvType::CommissionerUdpPort,
1425            51 => NetworkManagementTlvType::PendingTimestamp,
1426            52 => NetworkManagementTlvType::DelayTimer,
1427            53 => NetworkManagementTlvType::ChannelMask,
1428            _ => NetworkManagementTlvType::NotPresent,
1429        }
1430    }
1431}
1432
1433impl From<&NetworkManagementTlv<'_>> for NetworkManagementTlvType {
1434    fn from(network_mgmt_tlv: &NetworkManagementTlv<'_>) -> Self {
1435        match *network_mgmt_tlv {
1436            NetworkManagementTlv::Channel { .. } => NetworkManagementTlvType::Channel,
1437            NetworkManagementTlv::PanId(_) => NetworkManagementTlvType::PanId,
1438            NetworkManagementTlv::ExtendedPanId(_) => NetworkManagementTlvType::ExtendedPanId,
1439            NetworkManagementTlv::NetworkName(_) => NetworkManagementTlvType::NetworkName,
1440            NetworkManagementTlv::Pskc(_) => NetworkManagementTlvType::Pskc,
1441            NetworkManagementTlv::NetworkMasterKey(_) => NetworkManagementTlvType::NetworkMasterKey,
1442            NetworkManagementTlv::NetworkKeySequenceCounter(_) => {
1443                NetworkManagementTlvType::NetworkKeySequenceCounter
1444            }
1445            NetworkManagementTlv::NetworkMeshLocalPrefix(_) => {
1446                NetworkManagementTlvType::NetworkMeshLocalPrefix
1447            }
1448            NetworkManagementTlv::SteeringData(_) => NetworkManagementTlvType::SteeringData,
1449            NetworkManagementTlv::BorderAgentLocator(_) => {
1450                NetworkManagementTlvType::BorderAgentLocator
1451            }
1452            NetworkManagementTlv::CommissionerId(_) => NetworkManagementTlvType::CommissionerId,
1453            NetworkManagementTlv::CommissionerSessionId(_) => {
1454                NetworkManagementTlvType::CommissionerSessionId
1455            }
1456            NetworkManagementTlv::SecurityPolicy { .. } => NetworkManagementTlvType::SecurityPolicy,
1457            NetworkManagementTlv::ActiveTimestamp { .. } => {
1458                NetworkManagementTlvType::ActiveTimestamp
1459            }
1460            NetworkManagementTlv::CommissionerUdpPort(_) => {
1461                NetworkManagementTlvType::CommissionerUdpPort
1462            }
1463            NetworkManagementTlv::PendingTimestamp { .. } => {
1464                NetworkManagementTlvType::PendingTimestamp
1465            }
1466            NetworkManagementTlv::DelayTimer(_) => NetworkManagementTlvType::DelayTimer,
1467            NetworkManagementTlv::ChannelMask(_) => NetworkManagementTlvType::ChannelMask,
1468        }
1469    }
1470}
1471
1472/// Used in Security Policy TLV.
1473/// See 8.10.1.15
1474#[repr(u8)]
1475pub enum SecurityPolicy {
1476    O = 0b1000_0000, // Out-of-band commissioning enabled.
1477    N = 0b0100_0000, // Native commissioning using PSKc is allowed.
1478    R = 0b0010_0000, // Thread 1.x Routers are enabled.
1479    C = 0b0001_0000, // External commissioner authentication is allowed using PSKc.
1480    B = 0b0000_1000, // Thread 1.x Beacons are enabled.
1481}
1482
1483/// Used in Channel Mask TLV.
1484pub struct ChannelMaskEntry {
1485    channel_page: u8,
1486    mask_length: u8,
1487    channel_mask: [u8; MAX_VALUE_FIELD_LENGTH],
1488}
1489
1490impl ChannelMaskEntry {
1491    /// Serializes this Channel Mask Entry into `buf`.
1492    pub fn encode(&self, buf: &mut [u8]) -> SResult {
1493        let mut offset = enc_consume!(buf, 0; encode_u8, self.channel_page);
1494        offset = enc_consume!(buf, offset; encode_u8, self.mask_length);
1495        offset = enc_consume!(buf, offset; encode_bytes_be, &self.channel_mask);
1496        stream_done!(offset)
1497    }
1498
1499    /// Deserializes Channel Mask Entry from `buf` and returns it.
1500    pub fn decode(buf: &[u8]) -> SResult<ChannelMaskEntry> {
1501        let (offset, channel_page) = dec_try!(buf; decode_u8);
1502        let (offset, mask_length) = dec_try!(buf, offset; decode_u8);
1503        let mut channel_mask = [0u8; MAX_VALUE_FIELD_LENGTH];
1504        let offset = dec_consume!(buf, offset; decode_bytes_be, &mut channel_mask);
1505        stream_done!(
1506            offset,
1507            ChannelMaskEntry {
1508                channel_page,
1509                mask_length,
1510                channel_mask,
1511            }
1512        )
1513    }
1514}