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.
45use bitfield::bitfield;
67use crate::frame::error::FrameParseError;
8use crate::frame::FrameTypeMarker;
9use crate::DLCI;
1011/// 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! {
14pub struct AddressField(u8);
15impl Debug;
16pub bool, ea_bit, set_ea_bit: 0;
17pub bool, cr_bit, set_cr_bit: 1;
18pub u8, dlci_raw, set_dlci: 7, 2;
19}
2021impl AddressField {
22/// Returns the DLCI specified by the Address Field.
23pub fn dlci(&self) -> Result<DLCI, FrameParseError> {
24 DLCI::try_from(self.dlci_raw())
25 }
26}
2728/// 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! {
31pub struct ControlField(u8);
32impl Debug;
33pub bool, poll_final, set_poll_final: 4;
34pub u8, frame_type_raw, set_frame_type: 7, 0;
35}
3637impl ControlField {
38/// Returns the frame type specified by the Control Field.
39pub 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.
42const FRAME_TYPE_MASK: u8 = 0b11101111;
43 FrameTypeMarker::try_from(self.frame_type_raw() & FRAME_TYPE_MASK)
44 }
45}
4647/// 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;
4950/// 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;
5455bitfield! {
56pub struct InformationField(u8);
57impl Debug;
58pub bool, ea_bit, set_ea_bit: 0;
59pub u8, length, set_length_inner: 7, 1;
60}
6162impl InformationField {
63pub fn set_length(&mut self, length: u8) {
64// The length is only 7 bits wide.
65let mask = 0b1111111;
66self.set_length_inner(length & mask);
67 }
68}