use crate::core;
use bt_common::Bluetooth;
use bt_hci::{Address, CommandSender, EventRegistry};
-use bt_packets::hci::EventChild::ConnectionComplete;
+use bt_packets::hci::EventChild::{
+ AuthenticationComplete, ConnectionComplete, DisconnectionComplete,
+};
use bt_packets::hci::{
AcceptConnectionRequestBuilder, AcceptConnectionRequestRole, ClockOffsetValid,
CreateConnectionBuilder, CreateConnectionCancelBuilder, CreateConnectionRoleSwitch,
- DisconnectBuilder, DisconnectReason, ErrorCode, EventChild, EventCode, PageScanRepetitionMode,
- RejectConnectionReason, RejectConnectionRequestBuilder, Role,
+ DisconnectBuilder, DisconnectReason, ErrorCode, EventChild, EventCode, EventPacket,
+ PageScanRepetitionMode, RejectConnectionReason, RejectConnectionRequestBuilder, Role,
};
use bytes::Bytes;
use gddi::{module, provides, Stoppable};
pub enum ConnectionEvent {
/// Connection was disconnected with the specified code.
Disconnected(ErrorCode),
+ /// Connection authentication was completed
+ AuthenticationComplete,
}
impl Connection {
addr: Address,
#[allow(dead_code)]
shared: Arc<Mutex<ConnectionShared>>,
+ hci_evt_tx: Sender<EventPacket>,
}
#[derive(Debug)]
let (evt_tx, mut evt_rx) = channel(3);
events.register(EventCode::ConnectionComplete, evt_tx.clone()).await;
- events.register(EventCode::ConnectionRequest, evt_tx).await;
+ events.register(EventCode::ConnectionRequest, evt_tx.clone()).await;
+ events.register(EventCode::AuthenticationComplete, evt_tx).await;
loop {
select! {
let connection_internal = ConnectionInternal {
addr,
shared,
+ hci_evt_tx: core_conn.evt_tx.clone(),
};
assert!(connections.lock().await.insert(handle, connection_internal).is_none());
role: AcceptConnectionRequestRole::BecomeCentral
}).await;
}
-
- }
+ },
+ AuthenticationComplete(e) => dispatch_to(e.get_connection_handle(), &connections, evt).await,
_ => unimplemented!(),
}
}
}
}
+async fn dispatch_to(
+ handle: u16,
+ connections: &Arc<Mutex<HashMap<u16, ConnectionInternal>>>,
+ event: EventPacket,
+) {
+ if let Some(c) = connections.lock().await.get_mut(&handle) {
+ c.hci_evt_tx.send(event).await.unwrap();
+ }
+}
+
async fn run_connection(
handle: u16,
evt_tx: Sender<ConnectionEvent>,
loop {
select! {
Some(evt) = core.evt_rx.recv() => {
- match evt {
- core::Event::Disconnected(reason) => {
+ match evt.specialize() {
+ DisconnectionComplete(evt) => {
connections.lock().await.remove(&handle);
- evt_tx.send(ConnectionEvent::Disconnected(reason)).await.unwrap();
+ evt_tx.send(ConnectionEvent::Disconnected(evt.get_reason())).await.unwrap();
return; // At this point, there is nothing more to run on the connection.
- }
+ },
+ AuthenticationComplete(_) => evt_tx.send(ConnectionEvent::AuthenticationComplete).await.unwrap(),
+ _ => unimplemented!(),
}
},
Some(req) = req_rx.recv() => {
use bt_hal::AclHal;
use bt_hci::{ControllerExports, EventRegistry};
use bt_packets::hci::EventChild::{DisconnectionComplete, NumberOfCompletedPackets};
-use bt_packets::hci::{AclPacket, ErrorCode, EventCode};
+use bt_packets::hci::{AclPacket, EventCode, EventPacket};
use bytes::Bytes;
use futures::stream::{SelectAll, StreamExt};
use gddi::{module, provides, Stoppable};
pub tx: Option<Sender<Bytes>>,
handle: u16,
requests: Sender<Request>,
- pub evt_rx: Receiver<Event>,
+ pub evt_rx: Receiver<EventPacket>,
+ pub evt_tx: Sender<EventPacket>,
}
struct ConnectionInternal {
reassembler: Reassembler,
bt: Bluetooth,
close_tx: oneshot::Sender<()>,
- evt_tx: Sender<Event>,
-}
-
-/// Events that can be generated by the underlying layer
-#[derive(Debug)]
-pub enum Event {
- /// Underlying connection was disconnected. Reports reason why.
- Disconnected(ErrorCode),
+ evt_tx: Sender<EventPacket>,
}
/// Manages rx and tx for open ACL connections
reassembler: Reassembler::new(out_tx),
bt,
close_tx,
- evt_tx,
+ evt_tx: evt_tx.clone(),
}).is_none());
match bt {
tx: Some(in_tx),
handle,
requests: req_tx_clone.clone(),
- evt_rx
+ evt_rx,
+ evt_tx,
}).unwrap();
},
}
DisconnectionComplete(evt) => {
if let Some(connection) = connections.remove(&evt.get_connection_handle()) {
connection.close_tx.send(()).unwrap();
- connection.evt_tx.send(Event::Disconnected(evt.get_reason())).await.unwrap();
+ connection.evt_tx.send(evt.into()).await.unwrap();
}
},
_ => unimplemented!(),