• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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