bt_rfcomm/frame/
field.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use bitfield::bitfield;
6
7use crate::frame::error::FrameParseError;
8use crate::frame::FrameTypeMarker;
9use crate::DLCI;
10
11/// The Address field is the first byte in the frame. See GSM 7.10 Section 5.2.1.2.
12pub(crate) const FRAME_ADDRESS_IDX: usize = 0;
13bitfield! {
14    pub struct AddressField(u8);
15    impl Debug;
16    pub bool, ea_bit, set_ea_bit: 0;
17    pub bool, cr_bit, set_cr_bit: 1;
18    pub u8, dlci_raw, set_dlci: 7, 2;
19}
20
21impl AddressField {
22    /// Returns the DLCI specified by the Address Field.
23    pub fn dlci(&self) -> Result<DLCI, FrameParseError> {
24        DLCI::try_from(self.dlci_raw())
25    }
26}
27
28/// The Control field is the second byte in the frame. See GSM 7.10 Section 5.2.1.3.
29pub(crate) const FRAME_CONTROL_IDX: usize = 1;
30bitfield! {
31    pub struct ControlField(u8);
32    impl Debug;
33    pub bool, poll_final, set_poll_final: 4;
34    pub u8, frame_type_raw, set_frame_type: 7, 0;
35}
36
37impl ControlField {
38    /// Returns the frame type specified by the Control Field.
39    pub fn frame_type(&self) -> Result<FrameTypeMarker, FrameParseError> {
40        // The P/F bit is ignored when determining Frame Type. See RFCOMM 4.2 and GSM 7.10
41        // Section 5.2.1.3.
42        const FRAME_TYPE_MASK: u8 = 0b11101111;
43        FrameTypeMarker::try_from(self.frame_type_raw() & FRAME_TYPE_MASK)
44    }
45}
46
47/// The Information field is the third byte in the frame. See GSM 7.10 Section 5.2.1.4.
48pub(crate) const FRAME_INFORMATION_IDX: usize = 2;
49
50/// The information field can be represented as two E/A padded octets, each 7-bits wide.
51/// This shift is used to access the upper bits of a two-octet field.
52/// See GSM 7.10 Section 5.2.1.4.
53pub(crate) const INFORMATION_SECOND_OCTET_SHIFT: usize = 7;
54
55bitfield! {
56    pub struct InformationField(u8);
57    impl Debug;
58    pub bool, ea_bit, set_ea_bit: 0;
59    pub u8, length, set_length_inner: 7, 1;
60}
61
62impl InformationField {
63    pub fn set_length(&mut self, length: u8) {
64        // The length is only 7 bits wide.
65        let mask = 0b1111111;
66        self.set_length_inner(length & mask);
67    }
68}