diff --git a/Source/v2/Meadow.Cli/Meadow.CLI.csproj b/Source/v2/Meadow.Cli/Meadow.CLI.csproj
index af8572bb..7fad0a2f 100644
--- a/Source/v2/Meadow.Cli/Meadow.CLI.csproj
+++ b/Source/v2/Meadow.Cli/Meadow.CLI.csproj
@@ -10,7 +10,7 @@
Wilderness Labs, Inc
Wilderness Labs, Inc
true
- 2.0.58.0
+ 2.0.60.0
AnyCPU
http://developer.wildernesslabs.co/Meadow/Meadow.CLI/
https://github.com/WildernessLabs/Meadow.CLI
diff --git a/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs b/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs
index dcd1693f..873026bf 100644
--- a/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs
+++ b/Source/v2/Meadow.Cli/Properties/AssemblyInfo.cs
@@ -6,5 +6,5 @@ namespace Meadow.CLI;
public static class Constants
{
- public const string CLI_VERSION = "2.0.58.0";
+ public const string CLI_VERSION = "2.0.60.0";
}
\ No newline at end of file
diff --git a/Source/v2/Meadow.HCom/Connections/SerialConnection.ListenerProc.cs b/Source/v2/Meadow.HCom/Connections/SerialConnection.ListenerProc.cs
index 1b449d9c..e7433e33 100644
--- a/Source/v2/Meadow.HCom/Connections/SerialConnection.ListenerProc.cs
+++ b/Source/v2/Meadow.HCom/Connections/SerialConnection.ListenerProc.cs
@@ -1,4 +1,4 @@
-namespace Meadow.Hcom
+namespace Meadow.Hcom
{
public partial class SerialConnection
{
@@ -52,6 +52,34 @@ private async Task ListenerProc()
var delimiter = new byte[] { 0x00 };
var receivedLength = 0;
+ async Task ReOpen() // local function
+ {
+ Debug.WriteLine($"Device reset detected");
+
+ var timeout = 20;
+ try { _port.Close(); } catch { } // Swallow any exceptions on close - there is nothing we can do about it
+
+ while (!_port.IsOpen)
+ {
+ await Task.Delay(500);
+
+ if (timeout-- < 0)
+ {
+ return;
+ }
+
+ try
+ {
+ Open();
+ Debug.WriteLine($"Port re-opened");
+ }
+ catch
+ {
+ Debug.WriteLine($"Failed to re-open port");
+ }
+ }
+ }
+
while (!_isDisposed)
{
if (_port.IsOpen)
@@ -64,32 +92,20 @@ private async Task ListenerProc()
try
{
receivedLength = _port.Read(readBuffer, 0, readBuffer.Length);
+ if (receivedLength == 0)
+ {
+ Debug.WriteLine($"Received 0 bytes");
+ throw new OperationCanceledException();
+ }
}
catch (OperationCanceledException)
{
- Debug.WriteLine($"Device reset detected");
-
- var timeout = 20;
-
- while (!_port.IsOpen)
- {
- await Task.Delay(500);
-
- if (timeout-- < 0)
- {
- return;
- }
-
- try
- {
- Open();
- Debug.WriteLine($"Port re-opened");
- }
- catch
- {
- Debug.WriteLine($"Failed to re-open port");
- }
- }
+ await ReOpen();
+ goto read;
+ }
+ catch (InvalidOperationException)
+ {
+ await ReOpen();
goto read;
}
diff --git a/Source/v2/Meadow.HCom/Connections/SerialConnection.cs b/Source/v2/Meadow.HCom/Connections/SerialConnection.cs
index 452d93eb..ef37f8b5 100755
--- a/Source/v2/Meadow.HCom/Connections/SerialConnection.cs
+++ b/Source/v2/Meadow.HCom/Connections/SerialConnection.cs
@@ -1,4 +1,4 @@
-using System.Buffers;
+using System.Buffers;
using System.IO.Ports;
using System.Security.Cryptography;
@@ -1254,7 +1254,7 @@ public override async Task StartDebuggingSession(int port, ILog
var debuggingServer = new DebuggingServer(this, port, logger);
logger?.LogDebug("Tell the Debugging Server to Start Listening");
- _ = debuggingServer.StartListening(cancellationToken);
+ await debuggingServer.StartListening(cancellationToken);
logger?.LogDebug($"Start Debugging on port: {port}");
await Device.StartDebugging(port, logger, cancellationToken);
diff --git a/Source/v2/Meadow.HCom/Debugging/DebuggingServer.ActiveClient.cs b/Source/v2/Meadow.HCom/Debugging/DebuggingServer.ActiveClient.cs
index ce6cb7a2..f25cb25d 100644
--- a/Source/v2/Meadow.HCom/Debugging/DebuggingServer.ActiveClient.cs
+++ b/Source/v2/Meadow.HCom/Debugging/DebuggingServer.ActiveClient.cs
@@ -1,7 +1,6 @@
-using System.Buffers;
+using System.Buffers;
using System.Collections.Concurrent;
using System.Net.Sockets;
-using System.Security.Cryptography;
namespace Meadow.Hcom;
@@ -10,17 +9,16 @@ public partial class DebuggingServer
private class ActiveClient : IDisposable
{
private readonly IMeadowConnection _connection;
- private readonly TcpClient _tcpClient;
- private readonly NetworkStream _networkStream;
+ private TcpClient _tcpClient;
+ private NetworkStream _networkStream;
private readonly CancellationTokenSource _cts;
- private readonly Task _receiveVsDebugDataTask;
- private readonly Task _receiveMeadowDebugDataTask;
+ private Task _receiveVsDebugDataTask;
+ private Task _receiveMeadowDebugDataTask;
private readonly ILogger? _logger;
private bool _disposed;
private readonly BlockingCollection _debuggerMessages = new();
- private readonly AutoResetEvent _vsDebugDataReady = new(false);
- internal ActiveClient(IMeadowConnection connection, TcpClient tcpClient, ILogger? logger, CancellationToken? cancellationToken)
+ internal ActiveClient(IMeadowConnection connection, ILogger? logger, CancellationToken? cancellationToken)
{
_cts = cancellationToken != null
? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken.Value)
@@ -28,13 +26,15 @@ internal ActiveClient(IMeadowConnection connection, TcpClient tcpClient, ILogger
_logger = logger;
_connection = connection;
- _tcpClient = tcpClient;
- _networkStream = tcpClient.GetStream();
-
- _logger?.LogDebug("Starting receive task");
-
_connection.DebuggerMessageReceived += MeadowConnection_DebuggerMessageReceived;
+ }
+ public async Task Start(TcpListener tcpListener)
+ {
+ _tcpClient = await tcpListener.AcceptTcpClientAsync();
+ _networkStream = _tcpClient.GetStream();
+
+ _logger?.LogDebug("Starting receive task");
_receiveVsDebugDataTask = Task.Factory.StartNew(SendToMeadowAsync, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
_receiveMeadowDebugDataTask = Task.Factory.StartNew(SendToVisualStudio, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
@@ -42,7 +42,6 @@ internal ActiveClient(IMeadowConnection connection, TcpClient tcpClient, ILogger
private void MeadowConnection_DebuggerMessageReceived(object sender, byte[] e)
{
_debuggerMessages.Add(e);
- _vsDebugDataReady.Set();
}
private const int RECEIVE_BUFFER_SIZE = 256;
@@ -51,9 +50,7 @@ private async Task SendToMeadowAsync()
{
try
{
- using var md5 = MD5.Create();
var receiveBuffer = ArrayPool.Shared.Rent(RECEIVE_BUFFER_SIZE);
- var meadowBuffer = Array.Empty();
while (!_cts.Token.IsCancellationRequested)
{
@@ -69,13 +66,12 @@ private async Task SendToMeadowAsync()
continue;
}
- var destIndex = meadowBuffer.Length;
- Array.Resize(ref meadowBuffer, destIndex + bytesRead);
- Array.Copy(receiveBuffer, 0, meadowBuffer, destIndex, bytesRead);
+ var meadowBuffer = new byte[bytesRead];
+ Array.Copy(receiveBuffer, 0, meadowBuffer, 0, bytesRead);
_logger?.LogTrace("Received {count} bytes from VS, will forward to HCOM/Meadow. {hash}",
meadowBuffer.Length,
- BitConverter.ToString(md5.ComputeHash(meadowBuffer))
+ BitConverter.ToString(meadowBuffer)
.Replace("-", string.Empty)
.ToLowerInvariant());
@@ -83,7 +79,6 @@ private async Task SendToMeadowAsync()
Debug.WriteLine($"ToMeadow: {BitConverter.ToString(meadowBuffer)}");
- meadowBuffer = Array.Empty();
} while (_networkStream.DataAvailable);
}
else
@@ -96,12 +91,10 @@ private async Task SendToMeadowAsync()
catch (IOException ioe)
{
_logger?.LogInformation("Visual Studio has Disconnected");
- _logger?.LogTrace(ioe, "Visual Studio has Disconnected");
}
catch (ObjectDisposedException ode)
{
_logger?.LogInformation("Visual Studio has stopped debugging");
- _logger?.LogTrace(ode, "Visual Studio has stopped debugging");
}
catch (Exception ex)
{
@@ -114,33 +107,23 @@ private async Task SendToVisualStudio()
{
try
{
- while (!_cts.Token.IsCancellationRequested)
+ while (!_cts.IsCancellationRequested)
{
- if (_networkStream != null && _networkStream.CanWrite)
+ if (!_debuggerMessages.TryTake(out var byteData, 500, _cts.Token))
{
- _vsDebugDataReady.WaitOne(500);
-
- while (_debuggerMessages.Count > 0)
- {
- var byteData = _debuggerMessages.Take(_cts.Token);
-
- _logger?.LogTrace("Received {count} bytes from Meadow, will forward to VS", byteData.Length);
- if (!_tcpClient.Connected)
- {
- _logger?.LogDebug("Cannot forward data, Visual Studio is not connected");
- return;
- }
-
- await _networkStream.WriteAsync(byteData, 0, byteData.Length, _cts.Token);
- _logger?.LogTrace("Forwarded {count} bytes to VS", byteData.Length);
-
- Debug.WriteLine($"ToVisStu: {BitConverter.ToString(byteData)}");
- }
+ continue;
}
- else
+
+ _logger?.LogTrace("Received {count} bytes from Meadow, will forward to VS", byteData.Length);
+ if (!_tcpClient.Connected || _networkStream == null || !_networkStream.CanWrite)
{
- _logger?.LogInformation("Unable to Write Data from Visual Studio");
+ _logger?.LogDebug("Cannot forward data, Visual Studio is not connected");
+ break;
}
+
+ await _networkStream.WriteAsync(byteData, 0, byteData.Length, _cts.Token);
+ _logger?.LogTrace("Forwarded {count} bytes to VS", byteData.Length);
+ Debug.WriteLine($"ToVisStu: {BitConverter.ToString(byteData)}");
}
}
catch (OperationCanceledException oce)
diff --git a/Source/v2/Meadow.HCom/Debugging/DebuggingServer.cs b/Source/v2/Meadow.HCom/Debugging/DebuggingServer.cs
index 1b359759..62418990 100644
--- a/Source/v2/Meadow.HCom/Debugging/DebuggingServer.cs
+++ b/Source/v2/Meadow.HCom/Debugging/DebuggingServer.cs
@@ -1,4 +1,4 @@
-using System.Net;
+using System.Net;
using System.Net.Sockets;
namespace Meadow.Hcom;
@@ -50,8 +50,7 @@ public async Task StartListening(CancellationToken cancellationToken)
_logger?.LogInformation($"Listening for Visual Studio to connect");
// This call will wait for the client to connect, before continuing.
- var tcpClient = await _listener.AcceptTcpClientAsync();
- _activeClient = CreateActiveClient(tcpClient);
+ _activeClient = await CreateActiveClient(_listener);
}
///
@@ -70,23 +69,22 @@ public async Task StopListening()
}
}
- private ActiveClient? CreateActiveClient(TcpClient tcpClient)
+ private async Task CreateActiveClient(TcpListener listener)
{
try
{
- lock (_lck)
+ if (_activeClient != null)
{
- _logger?.LogInformation("Visual Studio has Connected" + Environment.NewLine);
-
- if (_activeClient != null)
- {
- _logger?.LogDebug("Closing active client");
- _activeClient?.Dispose();
- _activeClient = null;
- }
-
- return new ActiveClient(_connection, tcpClient, _logger, _cancellationTokenSource?.Token);
+ _logger?.LogDebug("Closing active client");
+ _activeClient?.Dispose();
+ _activeClient = null;
}
+
+
+ var client = new ActiveClient(_connection, _logger, _cancellationTokenSource?.Token);
+ await client.Start(listener);
+ _logger?.LogInformation("Debugger has connected" + Environment.NewLine);
+ return client;
}
catch (Exception ex)
{