• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use super::h4::PacketError;
16 use crate::devices::chip::{self, ChipIdentifier};
17 use crate::devices::devices_handler::{add_chip, remove_chip};
18 use crate::transport::h4;
19 use crate::wireless;
20 use crate::wireless::packet::{register_transport, unregister_transport, Response};
21 use bytes::Bytes;
22 use log::{error, info, warn};
23 use netsim_proto::common::ChipKind;
24 use std::io::{ErrorKind, Write};
25 use std::net::{Ipv4Addr, SocketAddrV4, TcpListener, TcpStream};
26 use std::thread;
27 
28 // The HCI server implements the Bluetooth UART transport protocol
29 // (a.k.a. H4) over TCP. Each new connection on the HCI port spawns a
30 // new virtual controller associated with a new device.
31 
32 /// Start the socket-based transport.
33 ///
34 /// The socket transport reads/writes host-controller messages
35 /// for bluetooth (h4 hci) over a [TcpStream] transport.
36 ///
37 
38 struct SocketTransport {
39     stream: TcpStream,
40 }
41 
42 impl Response for SocketTransport {
response(&mut self, packet: Bytes, packet_type: u8)43     fn response(&mut self, packet: Bytes, packet_type: u8) {
44         let mut buffer = Vec::new();
45         buffer.push(packet_type);
46         buffer.extend(packet);
47         if let Err(e) = self.stream.write_all(&buffer[..]) {
48             error!("error writing {}", e);
49         };
50     }
51 }
52 
run_socket_transport(hci_port: u16)53 pub fn run_socket_transport(hci_port: u16) {
54     thread::Builder::new()
55         .name("hci_transport".to_string())
56         .spawn(move || {
57             accept_incoming(hci_port)
58                 .unwrap_or_else(|e| error!("Failed to accept incoming stream: {:?}", e));
59         })
60         .unwrap();
61 }
62 
accept_incoming(hci_port: u16) -> std::io::Result<()>63 fn accept_incoming(hci_port: u16) -> std::io::Result<()> {
64     let hci_socket = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, hci_port);
65     let listener = TcpListener::bind(hci_socket)?;
66     info!("Hci socket server is listening on: {}", hci_port);
67 
68     for stream in listener.incoming() {
69         let stream = stream?;
70         // the socket address of the remote peer of this TCP connection
71         info!("Hci client address: {}", stream.peer_addr().unwrap());
72         thread::Builder::new()
73             .name("hci_transport client".to_string())
74             .spawn(move || {
75                 handle_hci_client(stream);
76             })
77             .unwrap();
78     }
79     Ok(())
80 }
81 
handle_hci_client(stream: TcpStream)82 fn handle_hci_client(stream: TcpStream) {
83     // ...
84     let chip_create_params = chip::CreateParams {
85         kind: ChipKind::BLUETOOTH,
86         address: String::new(),
87         name: Some(format!("socket-{}", stream.peer_addr().unwrap())),
88         manufacturer: "Google".to_string(),
89         product_name: "Google".to_string(),
90         bt_properties: None,
91     };
92     #[cfg(not(test))]
93     let wireless_create_params =
94         wireless::CreateParam::Bluetooth(wireless::bluetooth::CreateParams {
95             address: String::new(),
96             bt_properties: None,
97         });
98     #[cfg(test)]
99     let wireless_create_params = wireless::CreateParam::Mock(wireless::mocked::CreateParams {
100         chip_kind: ChipKind::BLUETOOTH,
101     });
102     let result = match add_chip(
103         &stream.peer_addr().unwrap().port().to_string(),
104         &format!("socket-{}", stream.peer_addr().unwrap()),
105         &chip_create_params,
106         &wireless_create_params,
107     ) {
108         Ok(chip_result) => chip_result,
109         Err(err) => {
110             warn!("{err}");
111             return;
112         }
113     };
114     let tcp_rx = stream.try_clone().unwrap();
115     register_transport(result.chip_id, Box::new(SocketTransport { stream }));
116 
117     let _ = reader(tcp_rx, ChipKind::BLUETOOTH, result.chip_id);
118 
119     // unregister before remove_chip because facade may re-use facade_id
120     // on an intertwining create_chip and the unregister here might remove
121     // the recently added chip creating a disconnected transport.
122     unregister_transport(result.chip_id);
123 
124     if let Err(err) = remove_chip(result.device_id, result.chip_id) {
125         warn!("{err}");
126     };
127     info!("Removed chip: device_id: {} chip_id: {}.", result.device_id, result.chip_id);
128 }
129 
130 /// read from the socket and pass to the packet hub.
131 ///
reader(mut tcp_rx: TcpStream, kind: ChipKind, chip_id: ChipIdentifier) -> std::io::Result<()>132 fn reader(mut tcp_rx: TcpStream, kind: ChipKind, chip_id: ChipIdentifier) -> std::io::Result<()> {
133     loop {
134         if let ChipKind::BLUETOOTH = kind {
135             match h4::read_h4_packet(&mut tcp_rx) {
136                 Ok(packet) => {
137                     wireless::handle_request(chip_id, &packet.payload, packet.h4_type);
138                 }
139                 Err(PacketError::IoError(e)) if e.kind() == ErrorKind::UnexpectedEof => {
140                     info!("End socket reader connection with {}.", &tcp_rx.peer_addr().unwrap());
141                     return Ok(());
142                 }
143                 Err(e) => {
144                     error!("End socket reader connection with {}. Failed to reading hci control packet: {:?}",  &tcp_rx.peer_addr().unwrap(), e);
145                     return Ok(());
146                 }
147             }
148         }
149     }
150 }
151