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