From 66a86d3e14182b2081c57476675416652fbb040a Mon Sep 17 00:00:00 2001
From: Paul-Winpenny <92634321+Paul-Winpenny@users.noreply.github.com>
Date: Wed, 23 Oct 2024 17:44:02 +0100
Subject: [PATCH] At this point the sending and receiving messages is working

---
 App/RobobinApp/Interfaces/BLEInterfaces.cs    |  20 ++
 .../ViewModels/ConnectionPageViewModel.cs     | 245 +++++++-----------
 App/RobobinApp/Views/ConnectionPage.xaml      |  17 ++
 3 files changed, 137 insertions(+), 145 deletions(-)
 create mode 100644 App/RobobinApp/Interfaces/BLEInterfaces.cs

diff --git a/App/RobobinApp/Interfaces/BLEInterfaces.cs b/App/RobobinApp/Interfaces/BLEInterfaces.cs
new file mode 100644
index 00000000..181124d9
--- /dev/null
+++ b/App/RobobinApp/Interfaces/BLEInterfaces.cs
@@ -0,0 +1,20 @@
+using Plugin.BLE.Abstractions.Contracts;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Robobin.Interfaces
+{
+    public interface IBluetoothLEService
+    {
+        IBluetoothLE Current { get; }
+    }
+
+    public interface IAdapterService
+    {
+        IAdapter Adapter { get; }
+    }
+
+}
diff --git a/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs b/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
index 3cd816e9..14acad7d 100644
--- a/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
+++ b/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
@@ -18,6 +18,7 @@ using Windows.Devices.WiFi;
 using System.Reflection.PortableExecutable;
 using Plugin.BLE.Windows;
 using System.Text;
+using System.Windows.Documents;
 
 namespace RobobinApp.ViewModels
 {
@@ -32,6 +33,9 @@ namespace RobobinApp.ViewModels
         public ICommand ConnectCommand { get; }
         public ICommand SendWifiInfoCommand { get; }
         public ICommand DisconnectCommand { get; }
+        public ICommand TestReadOperation { get; }
+        public ICommand TestWriteOperation { get; }
+
         private bool _isConnected;
         private string ssid;
         private string password;
@@ -39,6 +43,7 @@ namespace RobobinApp.ViewModels
         public const string SendReceiveServiceUUID = "00000001-710e-4a5b-8d75-3e5b444bc3cf";
         public const string rxUUID = "00000002-710e-4a5b-8d75-3e5b444bc3cf";
         public const string wxUUID = "00000003-710e-4a5b-8d75-3e5b444bc3cf";
+        public string tempUnit = "C";
 
         public bool IsConnected
         {
@@ -50,17 +55,31 @@ namespace RobobinApp.ViewModels
                 OnPropertyChanged(nameof(ConnectButtonText));  // Update button text when connection state changes
             }
         }
+        private ICharacteristic _readCharacteristic;
+        private ICharacteristic _writeCharacteristic;
+
+        public ICharacteristic ReadCharacteristic
+        {
+            get => _readCharacteristic;
+            set
+            {
+                _readCharacteristic = value;
+                OnPropertyChanged();
+            }
+        }
 
-        public string SSID
+        public ICharacteristic WriteCharacteristic
         {
-            get => ssid;
+            get => _writeCharacteristic;
             set
             {
-                ssid = value;
-                OnPropertyChanged(nameof(SSID));
+                _writeCharacteristic = value;
+                OnPropertyChanged();
             }
         }
 
+
+
         public string Password
         {
             get => password;
@@ -76,7 +95,7 @@ namespace RobobinApp.ViewModels
         public string ConnectButtonText => IsConnected ? "Disconnect" : "Connect";
         private bool _isWifiNetworkSelectionVisible;
         private WifiNetwork _selectedWifiNetwork;
-
+        
         public bool IsWifiNetworkSelectionVisible
         {
             get => _isWifiNetworkSelectionVisible;
@@ -94,9 +113,12 @@ namespace RobobinApp.ViewModels
             WifiNetworks = new ObservableCollection<WifiNetwork>();
             ConnectCommand = new Command(OnConnect);
             DisconnectCommand = new Command(OnDisconnect);
-            SendWifiInfoCommand = new Command(OnSendWifiInfo);
             GoHomeCommand = new Command(async () => await OnGoHome());
             ConnectCommand = new Command(OnToggleConnection);
+            TestReadOperation = new Command(async () => await ReadOperationAsync());
+            SendWifiInfoCommand = new Command(OnSendWifiInfo);
+
+            TestWriteOperation = new Command(async() => await PingPiASync());
             _bluetoothLE = CrossBluetoothLE.Current;
             _adapter = _bluetoothLE.Adapter;
             _adapter.DeviceDiscovered += OnDeviceDiscovered;
@@ -104,36 +126,53 @@ namespace RobobinApp.ViewModels
 
             Debug.WriteLine("Checking and requesting Bluetooth permissions.");
             CheckAndRequestBluetoothPermissions();
-            //ScanForWifiNetworks();
         }
-        private async void ScanForWifiNetworks()
+
+        private void OnSendWifiInfo(object obj)
         {
-            WifiNetworks.Clear();
-            Debug.WriteLine("Scanning for Wi-Fi networks...");
+            var SSID = SelectedWifiNetwork.SSID;
+            var result = WriteOperationAsync("CONNECT", SSID + "," + password);
+            Debug.WriteLine($"Result: {result}");
+        }
 
-            var wifiAdapter = await GetWifiAdapterAsync();
-            if (wifiAdapter == null)
+        private async Task PingPiASync()
+        {
+            if (tempUnit.Equals("C"))
             {
-                Debug.WriteLine("Wi-Fi adapter not found.");
-                return;
+                tempUnit = "F";
+            } else
+            {
+                tempUnit = "C";
             }
+            WriteOperationAsync(tempUnit);
+
+        }
 
-            await wifiAdapter.ScanAsync();
-            Debug.Write("Scanning for networks");
-            var networks = wifiAdapter.NetworkReport.AvailableNetworks;
+        private async void ScanForWifiNetworks()
+        {
+            WifiNetworks.Clear();
+            Debug.WriteLine("Retrieving Wifi networks from readCharacteristic");
 
-            var addedSsids = new HashSet<string>(); // To keep track of added SSIDs
+            //Delay 5 seconds
+            await Task.Delay(5000);
 
-            foreach (var network in networks)
+            //var networks = await ReadOperationAsync();
+            var networks = "Network1\nNetwork2\nNetwork3"; // For testing
+            Debug.WriteLine(networks);
+            var delimiter = "\n";
+            var networkList = networks.Split(delimiter);
+            var addedSsids = new HashSet<string>(); 
+
+            foreach (var network in networkList)
             {
-                Debug.Write("This network exists: " + network.Ssid);
+                Debug.Write("This network exists: " + network);
 
-                if (addedSsids.Add(network.Ssid))
+                if (addedSsids.Add(network))
                 {
                     var wifiNetwork = new WifiNetwork
                     {
-                        SSID = network.Ssid,
-                        SignalStrength = network.NetworkRssiInDecibelMilliwatts
+                        SSID = network,
+                        SignalStrength = 0.0
                     };
 
                     Microsoft.Maui.Controls.Device.BeginInvokeOnMainThread(() => WifiNetworks.Add(wifiNetwork));
@@ -143,67 +182,6 @@ namespace RobobinApp.ViewModels
         }
 
 
-        private async Task<WiFiAdapter> GetWifiAdapterAsync()
-        {
-            var result = await WiFiAdapter.FindAllAdaptersAsync();
-            return result.FirstOrDefault(); // Get the first available Wi-Fi adapter
-        }
-
-        private async void OnSendWifiInfo(object obj)
-        {
-            if (SelectedWifiNetwork != null)
-            {
-                Debug.WriteLine("Wifi been selected");
-                Debug.WriteLine($"Selected Network {SelectedWifiNetwork.SSID}");
-            }
-            if (!_isConnected || _connectedDevice == null)
-            {
-                Debug.WriteLine("Cannot send WiFi information: No device is connected.");
-                await Application.Current.MainPage.DisplayAlert("Error", "No device is connected.", "OK");
-                return;
-            }
-
-            try
-            {
-                Debug.WriteLine($"Sending WiFi information to {_connectedDevice.Name}...");
-
-
-                var services = await _connectedDevice.GetServicesAsync();
-                var uartService = services.FirstOrDefault(s => s.Id == Guid.Parse("6e400001-b5a3-f393-e0a9-e50e24dcca9e"));
-
-                if (uartService == null)
-                {
-                    Debug.WriteLine("UART service not found.");
-                    await Application.Current.MainPage.DisplayAlert("Error", "UART service not found on the device.", "OK");
-                    return;
-                }
-
-                var characteristics = await uartService.GetCharacteristicsAsync();
-                var rxCharacteristic = characteristics.FirstOrDefault(c => c.Id == Guid.Parse(rxUUID));
-
-                if (rxCharacteristic == null)
-                {
-                    Debug.WriteLine("RX characteristic not found.");
-                    await Application.Current.MainPage.DisplayAlert("Error", "RX characteristic not found on the device.", "OK");
-                    return;
-                }
-
-                string wifiInfo = $"{SSID},{Password}";
-                byte[] data = System.Text.Encoding.UTF8.GetBytes(wifiInfo);
-
-                await rxCharacteristic.WriteAsync(data);
-
-                Debug.WriteLine("WiFi information sent successfully.");
-                await Application.Current.MainPage.DisplayAlert("Success", "WiFi information sent successfully.", "OK");
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine($"Error sending WiFi information: {ex.Message}");
-                await Application.Current.MainPage.DisplayAlert("Error", $"Failed to send WiFi information: {ex.Message}", "OK");
-            }
-        }
-
-
         public BluetoothDevice SelectedDevice
         {
             get => _selectedDevice;
@@ -351,29 +329,38 @@ namespace RobobinApp.ViewModels
                 if (_connectedDevice != null)
                 {
                     Debug.WriteLine($"Successfully connected to {SelectedDevice.Name}.");
+                    //
                     var services = await _connectedDevice.GetServicesAsync();
+                    Debug.WriteLine("Services gotten");
                     IsWifiNetworkSelectionVisible = true;
                     // Iterate through the discovered services
+                    //var service = await _connectedDevice.GetServiceAsync(Guid.Parse("00000001-710e-4a5b-8d75-3e5b444bc3cf"));
                     foreach (var service in services)
+
                     {
                         Debug.WriteLine($"Service: ID={service.Id}, Name={service.Name}");
 
                         if (service.Id.Equals(Guid.Parse("00000001-710e-4a5b-8d75-3e5b444bc3cf")) )
                         {
+                            Debug.WriteLine("Found RW service");
                             var characteristics = await service.GetCharacteristicsAsync();
 
                             foreach (var characteristic in characteristics)
                             {
-                                Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name}");
+                                var descriptor = await characteristic.GetDescriptorsAsync();
+                                Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name} | {descriptor}");
                                 if (characteristic.Uuid.Equals(rxUUID))
                                 {
-                                    var result = await ReadOperationAsync(characteristic);
+                                    ReadCharacteristic = characteristic;
+                                    var result = await ReadOperationAsync();
 
                                 }
                                 else if (characteristic.Uuid.Equals(wxUUID))
                                 {
-                                    const string data = "C";
-                                    await WriteOperationAsync(characteristic,data);
+                                    WriteCharacteristic = characteristic;
+                                    const string command = "SCAN";                                  
+                                    await WriteOperationAsync(command);
+                                    ScanForWifiNetworks();
 
                                 }
                             }
@@ -382,7 +369,7 @@ namespace RobobinApp.ViewModels
                     var transmissionService = services.FirstOrDefault(s => s.Id == Guid.Parse(SendReceiveServiceUUID));
                     var readCharacteristic = await transmissionService.GetCharacteristicAsync(Guid.Parse(rxUUID));
 
-                    var result2 = await ReadOperationAsync(readCharacteristic);
+                    var result2 = await ReadOperationAsync();
 
                 }
                 else
@@ -415,14 +402,20 @@ namespace RobobinApp.ViewModels
        
 
 
-        private async Task<string> ReadOperationAsync(ICharacteristic characteristic, int retryCount = 3)
+        private async Task<string> ReadOperationAsync(int retryCount = 3)
         {
+            if (ReadCharacteristic == null)
+            {
+                Debug.WriteLine("Read characteristic is not set.");
+                return "Failure";
+            }
+            Debug.WriteLine($"READ COMMAND : {ReadCharacteristic.Uuid}");
             for (int attempt = 1; attempt <= retryCount; attempt++)
             {
                 try
                 {
-                    Debug.WriteLine($"Attempt {attempt}: Reading from characteristic {characteristic.Uuid}");
-                    var temperatureData = await characteristic.ReadAsync();
+                    Debug.WriteLine($"Attempt {attempt}: Reading from characteristic {ReadCharacteristic.Uuid}");
+                    var temperatureData = await ReadCharacteristic.ReadAsync();
                     var temperatureValue = System.Text.Encoding.UTF8.GetString(temperatureData.data);
                     Debug.WriteLine($"Temperature Value: {temperatureValue}");
                     return temperatureValue;
@@ -440,21 +433,27 @@ namespace RobobinApp.ViewModels
                     }
                 }
             }
-            return null; 
+            return "Failure"; 
         }
 
-        private async Task WriteOperationAsync(ICharacteristic characteristic,string sendData, int retryCount = 3)
+        private async Task<string> WriteOperationAsync(string command, string arguments="", int retryCount = 3)
         {
-            byte[] data = System.Text.Encoding.UTF8.GetBytes(sendData);
+            if (WriteCharacteristic == null)
+            {
+                Debug.WriteLine("Write characteristic is not set.");
+                return "Failure";
+            }
+            string joinedData = command + ":" + arguments;
+            Debug.WriteLine($"WRITE COMMAND {joinedData}, UUID: {WriteCharacteristic}");
+            byte[] data = System.Text.Encoding.UTF8.GetBytes(joinedData);
 
             for (int attempt = 1; attempt <= retryCount; attempt++)
             {
                 try
-                {
-                    Debug.WriteLine($"Attempt {attempt}: Writing to characteristic {characteristic.Uuid}");
-                    await characteristic.WriteAsync(data);
+                {    
+                    await WriteCharacteristic.WriteAsync(data);
                     Debug.WriteLine("Write operation succeeded.");
-                    return;
+                    return "Success";
                 }
                 catch (Exception ex)
                 {
@@ -469,6 +468,8 @@ namespace RobobinApp.ViewModels
                     }
                 }
             }
+            return "Failure";
+
         }
 
 
@@ -505,50 +506,4 @@ namespace RobobinApp.ViewModels
 
     }
 
-
-    /**
-     * 
-                var transmitService = services.FirstOrDefault(s => s.Id == Guid.Parse(SendReceiveServiceUUID));
-                Debug.WriteLine("Transmit service was accessed");
-                Debug.WriteLine($"{transmitService.Name} : {transmitService.Id}");
-                if (transmitService == null)
-                {
-                    Debug.WriteLine("Transmit service wasn't found");
-                }
-                var characteristics = await transmitService.GetCharacteristicsAsync();
-
-                foreach (var characteristic in characteristics)
-                {
-                    Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name}");
-                    if (characteristic.Uuid.Equals(rxUUID))
-                    {
-                        var result = await ReadOperationAsync(characteristic);
-
-                    }
-                    else if (characteristic.Uuid.Equals(wxUUID))
-                    {
-                        //await WriteOperationAsync(characteristic);
-
-                    }
-                }
-
-            }
-            catch (DeviceConnectionException ex)
-            {
-                Debug.WriteLine($"Connection error: {ex.Message}");
-                await Application.Current.MainPage.DisplayAlert("Connection Error", $"Failed to connect: {ex.Message}", "OK");
-            }
-            catch (TaskCanceledException ex)
-            {
-                Debug.WriteLine($"TaskCanceledException: {ex.Message}");
-                await Application.Current.MainPage.DisplayAlert("Connection Error", "Connection timed out.", "OK");
-                _connectedDevice = null;
-                IsConnected = false;
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine($"General connection error: {ex.Message}");
-                await Application.Current.MainPage.DisplayAlert("Connection Error", $"An error occurred: {ex.Message}", "OK");
-            }
-        } **/
 }
diff --git a/App/RobobinApp/Views/ConnectionPage.xaml b/App/RobobinApp/Views/ConnectionPage.xaml
index a7df6ffa..42521cba 100644
--- a/App/RobobinApp/Views/ConnectionPage.xaml
+++ b/App/RobobinApp/Views/ConnectionPage.xaml
@@ -121,5 +121,22 @@
                         VerticalOptions="End" />
             </StackLayout>
         </StackLayout>
+        <StackLayout Padding="10" 
+             BackgroundColor="Black"
+             HorizontalOptions="FillAndExpand" 
+             VerticalOptions="Start">
+            <Label Text="Admin Panel:" 
+           FontSize="Medium" 
+           HorizontalOptions="Start" />
+
+            <Button Text= "Test Read Operation"
+             Command="{Binding TestReadOperation}"
+                     HorizontalOptions="Center" 
+                     VerticalOptions="End" />
+            <Button Text="Test Write Operation" 
+            Command="{Binding TestWriteOperation}" 
+            HorizontalOptions="Center" 
+            VerticalOptions="End" />
+        </StackLayout>
     </StackLayout>
 </ContentPage>
-- 
GitLab