diff --git a/server/Program.cs b/server/Program.cs
index 5c93acd..0ed5a83 100644
--- a/server/Program.cs
+++ b/server/Program.cs
@@ -1,16 +1,26 @@
-using System.Net;
+using System.Reflection;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
-builder.Services.AddSwaggerGen(c =>
+builder.Services.AddSwaggerGen(options =>
{
- c.SwaggerDoc("v1", new OpenApiInfo
+ options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "FPGA Web Lab API",
Description = "Use FPGA in the cloud",
Version = "v1"
});
+ // Generate Doc and Exam
+ var executingAssembly = Assembly.GetExecutingAssembly();
+ var xmlFilename = $"{executingAssembly.GetName().Name}.xml";
+ options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
+ var referencedProjectsXmlDocPaths =
+ executingAssembly.GetReferencedAssemblies()
+ .Where(assembly => assembly.Name != null && assembly.Name.StartsWith("server", StringComparison.InvariantCultureIgnoreCase))
+ .Select(assembly => Path.Combine(AppContext.BaseDirectory, $"{assembly.Name}.xml"))
+ .Where(path => File.Exists(path));
+ foreach (var xmlDocPath in referencedProjectsXmlDocPaths) options.IncludeXmlComments(xmlDocPath);
});
var app = builder.Build();
diff --git a/server/server.csproj b/server/server.csproj
index aa05bf8..c74cb1d 100644
--- a/server/server.csproj
+++ b/server/server.csproj
@@ -4,13 +4,14 @@
net9.0
enable
enable
+ true
-
+
diff --git a/server/src/JtagController.cs b/server/src/JtagController.cs
new file mode 100644
index 0000000..bcbc267
--- /dev/null
+++ b/server/src/JtagController.cs
@@ -0,0 +1,69 @@
+using System.Net;
+using Common;
+using DotNext;
+using WebProtocol;
+
+namespace JtagController;
+
+///
+/// Global Constant Jtag Address
+///
+public static class JtagAddr
+{
+ ///
+ /// Jtag State Reg
+ ///
+ public const UInt32 STATE = 0x10_00_00_00;
+ ///
+ /// Jtag Read Reg
+ ///
+ public const UInt32 READ_DATA = 0x10_00_00_01;
+ ///
+ /// Jtag Write Reg
+ ///
+ public const UInt32 WRITE_DATA = 0x10_00_00_02;
+ ///
+ /// Jtag Write Command
+ ///
+ public const UInt32 WRITE_CMD = 0x10_00_00_03;
+}
+
+class Jtag
+{
+
+ readonly int port;
+ readonly string address;
+ private IPEndPoint ep;
+
+ public Jtag(string address, int port)
+ {
+ this.address = address;
+ this.port = port;
+ this.ep = new IPEndPoint(IPAddress.Parse(address), port);
+ }
+
+ public async ValueTask> ClearRegisters()
+ {
+ var ret = true;
+ var opts = new SendAddrPackOptions();
+
+ opts.burstType = BurstType.FixedBurst;
+ opts.burstLength = 4;
+ opts.commandID = 0;
+ opts.address = JtagAddr.STATE;
+
+ // Write Jtag State Register
+ opts.isWrite = true;
+ ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
+ if (!ret) throw new Exception("Send 1st Address Package Failed!");
+ ret = await UDPClientPool.SendDataPackAsync(ep,
+ new SendDataPackage(NumberProcessor.NumberToBytes(0xFF_FF_FF_FF, 4).Value));
+ if (!ret) throw new Exception("Send Data Package Failed!");
+
+ // Read Jtag State Register
+ ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts));
+ if (!ret) throw new Exception("Send 2rd Address Package Failed!");
+
+ return ret;
+ }
+}
diff --git a/server/src/Router.cs b/server/src/Router.cs
index b21e362..d8532a9 100644
--- a/server/src/Router.cs
+++ b/server/src/Router.cs
@@ -1,41 +1,68 @@
using System.Net;
using Common;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
namespace Router
{
+ ///
+ /// Web API
+ ///
class API
{
- public static void SendString(string address, int port, string text)
+ ///
+ /// Send some String
+ ///
+ /// IP V4/V6 address
+ /// Device UDP port
+ /// Text for send
+ /// Json: true or false
+ public static async ValueTask SendString(string address, int port, string text)
{
var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
- UDPClientPool.AsyncSendString(endPoint, [text]);
+ var ret = await UDPClientPool.SendStringAsync(endPoint, [text]);
+ if (ret) { return Results.Json(true); }
+ else { return Results.Json(false); }
}
- public static void SendAddrPackage(
+
+ [HttpPost]
+ public static async ValueTask SendAddrPackage(
string address,
int port,
- WebProtocol.BurstType burstType,
- byte commandID,
- bool isWrite,
- byte burstLength,
- UInt32 devAddress)
+ // WebProtocol.BurstType burstType,
+ // byte commandID,
+ // bool isWrite,
+ // byte burstLength,
+ // UInt32 devAddress)
+ WebProtocol.SendAddrPackOptions opts)
{
- WebProtocol.SendAddrPackOptions opts;
- opts.burstType = burstType;
- opts.commandID = commandID;
- opts.isWrite = isWrite;
- opts.burstLength = burstLength;
- opts.address = devAddress;
+ // WebProtocol.SendAddrPackOptions opts;
+ // opts.burstType = burstType;
+ // opts.commandID = commandID;
+ // opts.isWrite = isWrite;
+ // opts.burstLength = burstLength;
+ // opts.address = devAddress;
var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
- UDPClientPool.SendAddrPack(endPoint, new WebProtocol.SendAddrPackage(opts));
+ var ret = await UDPClientPool.SendAddrPackAsync(endPoint, new WebProtocol.SendAddrPackage(opts));
+ if (ret) { return Results.Json(true); }
+ else { return Results.Json(false); }
}
- public static void SendDataPackage(string address, int port, string data)
+ public static async ValueTask SendDataPackage(string address, int port, string data)
{
var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
- UDPClientPool.SendDataPack(endPoint,
+ var ret = await UDPClientPool.SendDataPackAsync(endPoint,
new WebProtocol.SendDataPackage(NumberProcessor.StringToBytes(data).Value));
+ if (ret) { return Results.Json(true); }
+ else { return Results.Json(false); }
+ }
+
+ public static async ValueTask GetDeviceIDCode(string address, int port)
+ {
+
+
}
}
}
diff --git a/server/src/UdpClientPool.cs b/server/src/UdpClientPool.cs
index d197de9..17d52a4 100644
--- a/server/src/UdpClientPool.cs
+++ b/server/src/UdpClientPool.cs
@@ -6,61 +6,73 @@ class UDPClientPool
{
private static IPAddress localhost = IPAddress.Parse("127.0.0.1");
- public static void SendString(IPEndPoint endPoint, string[] stringArray)
+ public static bool SendString(IPEndPoint endPoint, string[] stringArray)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]);
- socket.SendTo(sendbuf, endPoint);
+ var sendLen = socket.SendTo(sendbuf, endPoint);
+ if (sendLen == stringArray[0].Length) { return true; }
+ else { return false; }
}
- public async static void AsyncSendString(IPEndPoint endPoint, string[] stringArray)
+ public async static ValueTask SendStringAsync(IPEndPoint endPoint, string[] stringArray)
{
- await Task.Run(() => { SendString(endPoint, stringArray); });
+ return await Task.Run(() => { return SendString(endPoint, stringArray); });
}
- public static void SendBytes(IPEndPoint endPoint, byte[] buf)
+ public static bool SendBytes(IPEndPoint endPoint, byte[] buf)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SendTo(buf, endPoint);
+ var sendLen = socket.SendTo(buf, endPoint);
+ if (sendLen == buf.Length) { return true; }
+ else { return false; }
}
- public async static void AsyncSendBytes(IPEndPoint endPoint, byte[] buf)
+ public async static ValueTask SendBytesAsync(IPEndPoint endPoint, byte[] buf)
{
- await Task.Run(() => { SendBytes(endPoint, buf); });
+ return await Task.Run(() => { return SendBytes(endPoint, buf); });
}
- public static void SendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
+ public static bool SendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SendTo(pkg.ToBytes(), endPoint);
+ var sendBytes = pkg.ToBytes();
+ var sendLen = socket.SendTo(sendBytes, endPoint);
+ if (sendLen == sendBytes.Length) { return true; }
+ else { return false; }
}
- public async static void AsyncSendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
+ public async static ValueTask SendAddrPackAsync(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg)
{
- await Task.Run(() => { SendAddrPack(endPoint, pkg); });
+ return await Task.Run(() => { return SendAddrPack(endPoint, pkg); });
}
- public static void SendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
+ public static bool SendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SendTo(pkg.ToBytes(), endPoint);
+ var sendBytes = pkg.ToBytes();
+ var sendLen = socket.SendTo(sendBytes, endPoint);
+ if (sendLen == sendBytes.Length) { return true; }
+ else { return false; }
}
- public async static void AsyncSendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
+ public async static ValueTask SendDataPackAsync(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg)
{
- await Task.Run(() => { SendDataPack(endPoint, pkg); });
+ return await Task.Run(() => { return SendDataPack(endPoint, pkg); });
}
- public static void SendLocalHost(int port, string[] stringArray)
+ public static bool SendLocalHost(int port, string[] stringArray)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]);
+ byte[] sendBytes = Encoding.ASCII.GetBytes(stringArray[0]);
IPEndPoint ep = new IPEndPoint(localhost, port);
- socket.SendTo(sendbuf, ep);
+ var sendLen = socket.SendTo(sendBytes, ep);
+ if (sendLen == sendBytes.Length) { return true; }
+ else { return false; }
}
public static void CycleSendLocalHost(int times, int sleepMilliSeconds, int port, string[] stringArray)
diff --git a/server/src/UdpServer.cs b/server/src/UdpServer.cs
index 35090bb..740c4ad 100644
--- a/server/src/UdpServer.cs
+++ b/server/src/UdpServer.cs
@@ -2,12 +2,29 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
+public struct UDPData
+{
+ public DateTime datetime;
+ public string addr;
+ public int port;
+ public byte[] data;
+}
+
+///
+/// UDP Server
+///
public class UDPServer
{
private int listenPort;
private UdpClient listener;
private IPEndPoint groupEP;
+ private Dictionary udpData = new Dictionary();
+ ///
+ /// Construct a udp server with fixed port
+ ///
+ /// Device UDP Port
+ /// UDPServer class
public UDPServer(int port)
{
// Construction
@@ -31,9 +48,31 @@ public class UDPServer
{
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] bytes = listener.EndReceive(res, ref remoteEP);
+ var nowtime = DateTime.Now;
+ // Handle RemoteEP
+ string remoteStr;
+ if (remoteEP is not null)
+ {
+ var remoteAddress = remoteEP.Address.ToString();
+ var remotePort = remoteEP.Port;
+ // Record UDP Receive Data
+ udpData.Add(remoteAddress, new UDPData()
+ {
+ addr = remoteAddress,
+ port = remotePort,
+ data = bytes,
+ datetime = nowtime,
+ });
+ remoteStr = $"{remoteAddress}:{remotePort}";
+ }
+ else
+ {
+ remoteStr = "Unknown";
+ }
+
+ // Handle Package
var sign = bytes[0];
-
string recvData;
if (sign == (byte)WebProtocol.PackSign.SendAddr)
{
@@ -60,8 +99,7 @@ public class UDPServer
recvData = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
}
- string remoteStr = (remoteEP is null) ? "Unknown" : $"{remoteEP.Address.ToString()}:{remoteEP.Port.ToString()}";
- Console.WriteLine($"Receive Data from {remoteStr} at {DateTime.Now.ToString()}:");
+ Console.WriteLine($"Receive Data from {remoteStr} at {nowtime.ToString()}:");
Console.WriteLine($"Original Data: {BitConverter.ToString(bytes).Replace("-", " ")}");
if (recvData.Length != 0) Console.WriteLine(recvData);
Console.WriteLine();
@@ -69,6 +107,10 @@ public class UDPServer
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
}
+ ///
+ /// Start UDP Server
+ ///
+ /// None
public void Start()
{
try
@@ -85,6 +127,10 @@ public class UDPServer
}
}
+ ///
+ /// Close UDP Server
+ ///
+ /// None
public void Stop()
{
listener.Close();
diff --git a/server/src/WebProtocol.cs b/server/src/WebProtocol.cs
index 16ff7f9..8b721aa 100644
--- a/server/src/WebProtocol.cs
+++ b/server/src/WebProtocol.cs
@@ -3,26 +3,50 @@ using Newtonsoft.Json;
namespace WebProtocol
{
+
+ /// The Sign of Package
public enum PackSign
{
+ /// Package: Send Read or Write Address to Device
SendAddr = 0x00,
+ /// Package: Send Data Which Update the flash of Device
SendData = 0xFF,
+ ///
RecvData = 0x0F,
+ ///
RecvResp = 0xF0,
}
+ /// Package Burst Type
public enum BurstType
{
+ /// Extended Type
ExtendBurst = 0b00,
+ /// Fixed Type
FixedBurst = 0b01,
}
+
+ /// Package options which to send address to read or write
+ ///
+ /// {
+ /// "burType":0,
+ /// "commandID":1,
+ /// }
+ ///
public struct SendAddrPackOptions
{
+
+ /// Package Burst Type
+ [JsonProperty("burstType")]
public BurstType burstType;
+ /// 1
public byte commandID;
+ /// true
public bool isWrite;
+ /// 255
public byte burstLength;
+ /// 0x10_00_00_00
public UInt32 address;
public override string ToString()