1 //
2 // Copyright (c) 2010-2025 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using System.Collections.Concurrent;
9 using System.Collections.Generic;
10 using AntShell.Terminal;
11 using Antmicro.Renode.Core;
12 using Antmicro.Renode.Logging;
13 using Antmicro.Renode.Peripherals;
14 using Antmicro.Renode.Peripherals.UART;
15 using Antmicro.Renode.Utilities;
16 using Antmicro.Migrant;
17 
18 namespace Antmicro.Renode.Analyzers
19 {
20     [Transient]
21     public class SocketUartAnalyzer : BasicPeripheralBackendAnalyzer<UARTBackend>, IExternal, IDisposable
22     {
AttachTo(UARTBackend backend)23         public override void AttachTo(UARTBackend backend)
24         {
25             var ioProvider = new IOProvider();
26             ioSource = new SimpleActiveIOSource();
27             ioProvider.Backend = ioSource;
28             base.AttachTo(backend);
29             (Backend as UARTBackend).BindAnalyzer(ioProvider);
30             StartServer();
31         }
32 
Show()33         public override void Show()
34         {
35         }
36 
Hide()37         public override void Hide()
38         {
39         }
40 
Dispose()41         public void Dispose()
42         {
43             server?.Stop();
44         }
45 
46         public int? Port => server?.Port;
47 
48         public IUART UART => (Backend as UARTBackend)?.UART;
49 
StartServer()50         private void StartServer()
51         {
52             server = new SocketServerProvider(true, false, serverName: "UartSocketTerminalServer");
53             server.DataReceived += WriteToUart;
54             ioSource.ByteWritten += WriteToClient;
55 
56             server.Start(0);
57             this.Log(LogLevel.Info, "Opened socket UART terminal on port {0}", Port);
58         }
59 
WriteToClient(byte b)60         private void WriteToClient(byte b)
61         {
62             server.SendByte(b);
63         }
64 
WriteToUart(int c)65         private void WriteToUart(int c)
66         {
67             ioSource.InvokeByteRead(c);
68         }
69 
70         private SimpleActiveIOSource ioSource;
71         private SocketServerProvider server;
72 
73         private class SimpleActiveIOSource : IActiveIOSource
74         {
Flush()75             public void Flush()
76             {}
77 
Write(byte b)78             public void Write(byte b)
79             {
80                 ByteWritten?.Invoke(b);
81             }
82 
InvokeByteRead(int b)83             public void InvokeByteRead(int b)
84             {
85                 ByteRead?.Invoke(b);
86             }
87 
Pause()88             public void Pause()
89             {}
90 
Resume()91             public void Resume()
92             {}
93 
94             public bool IsAnythingAttached => true;
95 
96             public event Action<int> ByteRead;
97 
98             public event Action<byte> ByteWritten;
99         }
100     }
101 }
102