From 526befba60963f655da45c8230cc1ffcb0fcda80 Mon Sep 17 00:00:00 2001
From: Paul-Winpenny <92634321+Paul-Winpenny@users.noreply.github.com>
Date: Tue, 22 Oct 2024 18:32:41 +0100
Subject: [PATCH] read and write works, issue is disconnecting doesn't discard
 properly, resulting in issues

---
 .../ViewModels/ConnectionPageViewModel.cs     | 209 +++++++++++++-----
 1 file changed, 154 insertions(+), 55 deletions(-)

diff --git a/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs b/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
index 0b639ce4..3cd816e9 100644
--- a/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
+++ b/App/RobobinApp/ViewModels/ConnectionPageViewModel.cs
@@ -154,6 +154,7 @@ namespace RobobinApp.ViewModels
             if (SelectedWifiNetwork != null)
             {
                 Debug.WriteLine("Wifi been selected");
+                Debug.WriteLine($"Selected Network {SelectedWifiNetwork.SSID}");
             }
             if (!_isConnected || _connectedDevice == null)
             {
@@ -315,7 +316,7 @@ namespace RobobinApp.ViewModels
                 try
                 {
                     Debug.WriteLine($"Attempt {attempt}: Connecting to device {deviceId}");
-                    var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
+                    var cancellationTokenSource = new CancellationTokenSource(); // No timeout specified
                     device = await _adapter.ConnectToKnownDeviceAsync(deviceId, new ConnectParameters(false, true), cancellationTokenSource.Token);
                     return device;
                 }
@@ -330,7 +331,6 @@ namespace RobobinApp.ViewModels
             }
             return device;
         }
-
         private async void OnConnect()
         {
             if (SelectedDevice == null)
@@ -340,86 +340,138 @@ namespace RobobinApp.ViewModels
             }
 
             Debug.WriteLine($"Attempting to connect to {SelectedDevice.Name}, MAC Address {SelectedDevice.MacAddress}");
-            await Application.Current.MainPage.DisplayAlert("Connection", $"Connecting to {SelectedDevice.Name}...", "OK");
 
             try
             {
                 await _adapter.StopScanningForDevicesAsync();
-                Debug.WriteLine("Stopped scanning for devices.");
                 IsConnected = true;
 
-                // Connect to the selected device
                 _connectedDevice = await TryConnectAsync(Guid.Parse(SelectedDevice.MacAddress));
 
-                Debug.WriteLine($"Successfully connected to {SelectedDevice.Name}.");
-                var services = await _connectedDevice.GetServicesAsync();
-                IsWifiNetworkSelectionVisible = true;
-                // Iterate through the discovered services
-                foreach (var service in services)
-                {
-                    Debug.WriteLine($"Service: ID={service.Id}, Name={service.Name}");
-
-
-                }
-     
-
-                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)
+                if (_connectedDevice != null)
                 {
-                    Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name}");
-                    if (characteristic.Uuid.Equals(rxUUID))
+                    Debug.WriteLine($"Successfully connected to {SelectedDevice.Name}.");
+                    var services = await _connectedDevice.GetServicesAsync();
+                    IsWifiNetworkSelectionVisible = true;
+                    // Iterate through the discovered services
+                    foreach (var service in services)
                     {
-                        Debug.WriteLine("Found Read");
-
-                        // Read the value from the characteristic
-                        var temperatureData = await characteristic.ReadAsync();
-
-                        // Convert the byte array to a string
-                        var temperatureValue = System.Text.Encoding.UTF8.GetString(temperatureData.data);
-
-                        Debug.WriteLine($"Temperature Value: {temperatureValue}");
+                        Debug.WriteLine($"Service: ID={service.Id}, Name={service.Name}");
+
+                        if (service.Id.Equals(Guid.Parse("00000001-710e-4a5b-8d75-3e5b444bc3cf")) )
+                        {
+                            var characteristics = await service.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))
+                                {
+                                    const string data = "C";
+                                    await WriteOperationAsync(characteristic,data);
+
+                                }
+                            }
+                        }
                     }
-                    else if (characteristic.Uuid.Equals(wxUUID))
-                    {
-                        Debug.WriteLine("Found Write");
+                    var transmissionService = services.FirstOrDefault(s => s.Id == Guid.Parse(SendReceiveServiceUUID));
+                    var readCharacteristic = await transmissionService.GetCharacteristicAsync(Guid.Parse(rxUUID));
 
-                        // Read the current value (if needed)
-                        var writeValueData = await characteristic.ReadAsync();
-                        var writeValue = System.Text.Encoding.UTF8.GetString(writeValueData.data);
+                    var result2 = await ReadOperationAsync(readCharacteristic);
 
-                        Debug.WriteLine($"Current Write Value: {writeValue}");
-
-                    }
                 }
-
-
+                else
+                {
+                    Debug.WriteLine("Failed to connect to the device.");
+                    IsConnected = false;
                 }
+            }
             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");
             }
+            finally
+            {
+                // Ensure we reset connection state
+                if (_connectedDevice == null)
+                {
+                    IsConnected = false;
+                    // Consider resetting any other related UI state
+                }
+            }
+        }
+
+       
+
+
+        private async Task<string> ReadOperationAsync(ICharacteristic characteristic, int retryCount = 3)
+        {
+            for (int attempt = 1; attempt <= retryCount; attempt++)
+            {
+                try
+                {
+                    Debug.WriteLine($"Attempt {attempt}: Reading from characteristic {characteristic.Uuid}");
+                    var temperatureData = await characteristic.ReadAsync();
+                    var temperatureValue = System.Text.Encoding.UTF8.GetString(temperatureData.data);
+                    Debug.WriteLine($"Temperature Value: {temperatureValue}");
+                    return temperatureValue;
+                }
+                catch (Exception ex)
+                {
+                    Debug.WriteLine($"Read attempt {attempt} failed: {ex.Message}");
+                    if (attempt == retryCount)
+                    {
+                        Debug.WriteLine("Max retry attempts reached for reading.");
+                        throw; 
+                    } else
+                    {
+                        await Task.Delay(1000);
+                    }
+                }
+            }
+            return null; 
         }
 
+        private async Task WriteOperationAsync(ICharacteristic characteristic,string sendData, int retryCount = 3)
+        {
+            byte[] data = System.Text.Encoding.UTF8.GetBytes(sendData);
+
+            for (int attempt = 1; attempt <= retryCount; attempt++)
+            {
+                try
+                {
+                    Debug.WriteLine($"Attempt {attempt}: Writing to characteristic {characteristic.Uuid}");
+                    await characteristic.WriteAsync(data);
+                    Debug.WriteLine("Write operation succeeded.");
+                    return;
+                }
+                catch (Exception ex)
+                {
+                    Debug.WriteLine($"Write attempt {attempt} failed: {ex.Message}");
+                    if (attempt == retryCount)
+                    {
+                        Debug.WriteLine("Max retry attempts reached for writing.");
+                        throw; 
+                    } else
+                    {
+                        await Task.Delay(1000);
+                    }
+                }
+            }
+        }
+
+
         private async void OnDisconnect()
         {
             if (_connectedDevice != null)
@@ -435,6 +487,7 @@ namespace RobobinApp.ViewModels
                         _connectedDevice.Dispose();
                     _connectedDevice = null;
                     IsConnected = false;
+                    ScanDevices();
                     await Application.Current.MainPage.DisplayAlert("Disconnected", "Device disconnected successfully.", "OK");
                 }
                 catch (Exception ex)
@@ -452,4 +505,50 @@ 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");
+            }
+        } **/
 }
-- 
GitLab