From 800e7913ce88d885ddac1af9d573a16cf9255409 Mon Sep 17 00:00:00 2001 From: Gregory Mallios Date: Sat, 16 Mar 2024 18:20:43 +0200 Subject: [PATCH] feat: support connecting to BLE devices from the app --- manager-ui/src/screens/bluetoothSearch.tsx | 18 +++++++++++++----- manager-ui/src/stores/bluetoothSlice.tsx | 10 ++++++++++ soundcore-lib/src/device.rs | 6 ++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/manager-ui/src/screens/bluetoothSearch.tsx b/manager-ui/src/screens/bluetoothSearch.tsx index 6bf7d64..bc0cb11 100644 --- a/manager-ui/src/screens/bluetoothSearch.tsx +++ b/manager-ui/src/screens/bluetoothSearch.tsx @@ -18,18 +18,25 @@ import { DiscoveredDevice } from '../types/soundcore-lib'; import BluetoothIcon from '@mui/icons-material/Bluetooth'; export const BluetoothSearchScreen: React.FC = () => { - const { isLoading, startScan, latestScanResults } = useSoundcoreStore( + const { isLoading, startScan, latestScanResults, connectDevice } = useSoundcoreStore( useShallow((state) => ({ isLoading: state.isLoading, startScan: state.startScan, - latestScanResults: state.latestScan + latestScanResults: state.latestScan, + connectDevice: state.connectDevice })) ); - const [selectedDevice, setSelectedDevice] = React.useState(); + const [selectedDevice, setSelectedDevice] = React.useState(null); const connectFabClick = () => { - console.log(selectedDevice); + if (!selectedDevice) return; + connectDevice(selectedDevice); + }; + + const searchFabClick = () => { + startScan(); + setSelectedDevice(null); }; // useEffect(() => { @@ -68,12 +75,13 @@ export const BluetoothSearchScreen: React.FC = () => { size="medium" color="primary" aria-label="add" + disabled={!selectedDevice} sx={{ position: 'absolute', bottom: 16, right: 16 }}> Connect startScan()} + onClick={() => searchFabClick()} variant="extended" size="medium" color="primary" diff --git a/manager-ui/src/stores/bluetoothSlice.tsx b/manager-ui/src/stores/bluetoothSlice.tsx index d669441..35d3f61 100644 --- a/manager-ui/src/stores/bluetoothSlice.tsx +++ b/manager-ui/src/stores/bluetoothSlice.tsx @@ -17,6 +17,15 @@ export const createBluetoothSlice: StateCreator = (set, _get) => console.error(`Could not start scan. ${error}`); set({ hasFailed: true }); }); + }, + connectDevice: (device: DiscoveredDevice) => { + useAsyncBridgeRequest({ command: 'connect', payload: device }) + .then(() => { + set({ connectedDevices: [..._get().connectedDevices, device.descriptor.addr] }); + }) + .catch((error) => { + console.error(`Could not connect to device. ${error}`); + }); } }); @@ -27,4 +36,5 @@ export interface BluetoothSlice { connectedDevices: Array; setLatestScan: (scanRes: DiscoveredDevice[]) => void; startScan: () => void; + connectDevice: (device: DiscoveredDevice) => void; } diff --git a/soundcore-lib/src/device.rs b/soundcore-lib/src/device.rs index bb01a0f..4823acf 100644 --- a/soundcore-lib/src/device.rs +++ b/soundcore-lib/src/device.rs @@ -58,6 +58,12 @@ impl SoundcoreBLEDevice Ok(initial_state) } + // TODO: Change the strategy to: + // 1. Send the state request packet + // 2. Check if the state is received within a certain time frame and retry if not + // 3. If the state is received, check if we have a SN + // 4. If not send a SN request packet + // 5. Resolve the state and the model async fn fetch_initial_state( connection: &Connection, byte_channel: &mut mpsc::Receiver>,