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
// Copyright 2019 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 {
    crate::{
        big_endian::BigEndianU16,
        mac::{self, FixedDataHdrFields, FrameControl, SequenceControl},
    },
    ieee80211::{Bssid, MacAddr},
};

pub fn data_hdr_client_to_ap(
    mut frame_ctrl: FrameControl,
    bssid: Bssid,
    client_addr: MacAddr,
    seq_ctrl: SequenceControl,
) -> FixedDataHdrFields {
    frame_ctrl.set_to_ds(true);
    frame_ctrl.set_from_ds(false);
    FixedDataHdrFields {
        frame_ctrl,
        duration: 0,
        addr1: bssid.into(),
        addr2: client_addr,
        addr3: bssid.into(),
        seq_ctrl,
    }
}

pub fn make_snap_llc_hdr(protocol_id: u16) -> mac::LlcHdr {
    mac::LlcHdr {
        dsap: mac::LLC_SNAP_EXTENSION,
        ssap: mac::LLC_SNAP_EXTENSION,
        control: mac::LLC_SNAP_UNNUMBERED_INFO,
        oui: mac::LLC_SNAP_OUI,
        protocol_id: BigEndianU16::from_native(protocol_id),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn client_to_ap() {
        let got = data_hdr_client_to_ap(
            FrameControl(0b00110000_00110000),
            Bssid::from([1; 6]),
            MacAddr::from([2; 6]),
            SequenceControl(4321),
        );
        let expected = FixedDataHdrFields {
            frame_ctrl: FrameControl(0b00110001_00110000),
            duration: 0,
            addr1: MacAddr::from([1; 6]),
            addr2: MacAddr::from([2; 6]),
            addr3: MacAddr::from([1; 6]),
            seq_ctrl: SequenceControl(4321),
        };
        assert_eq!(got, expected);
    }
}