1 use std::cell::RefCell;
2 use std::collections::VecDeque;
3 use std::convert::{TryFrom, TryInto};
4 use std::future::Future;
5 use std::pin::Pin;
6 use std::task::{self, Poll};
7
8 use num_traits::ToPrimitive;
9
10 use crate::ec::PrivateKey;
11 use crate::packets::{hci, lmp};
12
13 use crate::procedure::Context;
14
15 #[derive(Default)]
16 pub struct TestContext {
17 pub in_lmp_packets: RefCell<VecDeque<lmp::PacketPacket>>,
18 pub out_lmp_packets: RefCell<VecDeque<lmp::PacketPacket>>,
19 pub hci_events: RefCell<VecDeque<hci::EventPacket>>,
20 pub hci_commands: RefCell<VecDeque<hci::CommandPacket>>,
21 private_key: RefCell<Option<PrivateKey>>,
22 features_pages: [u64; 3],
23 peer_features_pages: [u64; 3],
24 }
25
26 impl TestContext {
new() -> Self27 pub fn new() -> Self {
28 Self::default()
29 .with_page_1_feature(hci::LMPFeaturesPage1Bits::SecureSimplePairingHostSupport)
30 .with_peer_page_1_feature(hci::LMPFeaturesPage1Bits::SecureSimplePairingHostSupport)
31 }
32
with_page_1_feature(mut self, feature: hci::LMPFeaturesPage1Bits) -> Self33 pub fn with_page_1_feature(mut self, feature: hci::LMPFeaturesPage1Bits) -> Self {
34 self.features_pages[1] |= feature.to_u64().unwrap();
35 self
36 }
37
with_page_2_feature(mut self, feature: hci::LMPFeaturesPage2Bits) -> Self38 pub fn with_page_2_feature(mut self, feature: hci::LMPFeaturesPage2Bits) -> Self {
39 self.features_pages[2] |= feature.to_u64().unwrap();
40 self
41 }
42
with_peer_page_1_feature(mut self, feature: hci::LMPFeaturesPage1Bits) -> Self43 pub fn with_peer_page_1_feature(mut self, feature: hci::LMPFeaturesPage1Bits) -> Self {
44 self.peer_features_pages[1] |= feature.to_u64().unwrap();
45 self
46 }
47
with_peer_page_2_feature(mut self, feature: hci::LMPFeaturesPage2Bits) -> Self48 pub fn with_peer_page_2_feature(mut self, feature: hci::LMPFeaturesPage2Bits) -> Self {
49 self.peer_features_pages[2] |= feature.to_u64().unwrap();
50 self
51 }
52 }
53
54 impl Context for TestContext {
poll_hci_command<C: TryFrom<hci::CommandPacket>>(&self) -> Poll<C>55 fn poll_hci_command<C: TryFrom<hci::CommandPacket>>(&self) -> Poll<C> {
56 let command =
57 self.hci_commands.borrow().front().and_then(|command| command.clone().try_into().ok());
58
59 if let Some(command) = command {
60 self.hci_commands.borrow_mut().pop_front();
61 Poll::Ready(command)
62 } else {
63 Poll::Pending
64 }
65 }
66
poll_lmp_packet<P: TryFrom<lmp::PacketPacket>>(&self) -> Poll<P>67 fn poll_lmp_packet<P: TryFrom<lmp::PacketPacket>>(&self) -> Poll<P> {
68 let packet =
69 self.in_lmp_packets.borrow().front().and_then(|packet| packet.clone().try_into().ok());
70
71 if let Some(packet) = packet {
72 self.in_lmp_packets.borrow_mut().pop_front();
73 Poll::Ready(packet)
74 } else {
75 Poll::Pending
76 }
77 }
78
send_hci_event<E: Into<hci::EventPacket>>(&self, event: E)79 fn send_hci_event<E: Into<hci::EventPacket>>(&self, event: E) {
80 self.hci_events.borrow_mut().push_back(event.into());
81 }
82
send_lmp_packet<P: Into<lmp::PacketPacket>>(&self, packet: P)83 fn send_lmp_packet<P: Into<lmp::PacketPacket>>(&self, packet: P) {
84 self.out_lmp_packets.borrow_mut().push_back(packet.into());
85 }
86
peer_address(&self) -> hci::Address87 fn peer_address(&self) -> hci::Address {
88 hci::Address { bytes: [0; 6] }
89 }
90
peer_handle(&self) -> u1691 fn peer_handle(&self) -> u16 {
92 0x42
93 }
94
peer_extended_features(&self, features_page: u8) -> Option<u64>95 fn peer_extended_features(&self, features_page: u8) -> Option<u64> {
96 Some(self.peer_features_pages[features_page as usize])
97 }
98
extended_features(&self, features_page: u8) -> u6499 fn extended_features(&self, features_page: u8) -> u64 {
100 self.features_pages[features_page as usize]
101 }
102
get_private_key(&self) -> Option<PrivateKey>103 fn get_private_key(&self) -> Option<PrivateKey> {
104 self.private_key.borrow().clone()
105 }
106
set_private_key(&self, key: &PrivateKey)107 fn set_private_key(&self, key: &PrivateKey) {
108 *self.private_key.borrow_mut() = Some(key.clone())
109 }
110 }
111
poll(future: Pin<&mut impl Future<Output = ()>>) -> Poll<()>112 pub fn poll(future: Pin<&mut impl Future<Output = ()>>) -> Poll<()> {
113 let waker = crate::future::noop_waker();
114 future.poll(&mut task::Context::from_waker(&waker))
115 }
116