Add project files.

This commit is contained in:
EugeneTes
2026-01-13 09:06:47 +01:00
parent dd935fe1fa
commit 7390693f50
187 changed files with 83457 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Inspectron.Epson\Inspectron.Epson.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,107 @@
using System.Net;
using System.Net.Sockets;
namespace Inspectron.Epson;
public class PrinterDiscoveryService
{
private const int DiscoveryPort = 3289;
private const string DiscoveryMessage = "EPSONQ";
private const int MessageLength = 14;
/// <summary>
/// Discovers Epson printers on the local network using UDP broadcast
/// </summary>
/// <param name="timeout">How long to wait for responses (default: 5 seconds)</param>
/// <param name="onPrinterDiscovered">Optional callback invoked when a printer is discovered</param>
/// <returns>List of discovered printer information</returns>
public async Task<List<DiscoveredPrinter>> DiscoverPrintersAsync(
TimeSpan? timeout = null,
Action<DiscoveredPrinter>? onPrinterDiscovered = null)
{
timeout ??= TimeSpan.FromSeconds(5);
using var udpClient = new UdpClient();
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 0));
// Send discovery broadcast message
var msg = BuildDiscoveryMessage();
var broadcastEndpoint = new IPEndPoint(IPAddress.Broadcast, DiscoveryPort);
await udpClient.SendAsync(msg, msg.Length, broadcastEndpoint);
// Receive responses
var discoveredPrinters = new List<DiscoveredPrinter>();
var endTime = DateTime.UtcNow.Add(timeout.Value);
while (DateTime.UtcNow < endTime)
{
try
{
var remainingTime = endTime - DateTime.UtcNow;
if (remainingTime <= TimeSpan.Zero)
break;
var receiveTask = udpClient.ReceiveAsync();
var timeoutTask = Task.Delay(remainingTime);
var completedTask = await Task.WhenAny(receiveTask, timeoutTask);
if (completedTask == receiveTask)
{
var result = await receiveTask;
// Check if we've already discovered this printer
if (!discoveredPrinters.Any(p => p.IPAddress.Equals(result.RemoteEndPoint.Address)))
{
var printer = new DiscoveredPrinter
{
IPAddress = result.RemoteEndPoint.Address,
ResponseData = result.Buffer,
DiscoveredAt = DateTime.UtcNow
};
discoveredPrinters.Add(printer);
onPrinterDiscovered?.Invoke(printer);
}
}
else
{
break; // Timeout reached
}
}
catch (Exception)
{
// Ignore errors and continue waiting for other responses
break;
}
}
return discoveredPrinters;
}
private static byte[] BuildDiscoveryMessage()
{
// msg = b'EPSONQ' + bytes([0x00] * 8)
var msg = new byte[MessageLength];
Array.Copy(System.Text.Encoding.ASCII.GetBytes(DiscoveryMessage), msg, 6);
msg[6] = 3;
for (int i = 7; i < msg.Length; i++)
{
msg[i] = 0x00;
}
msg[10] = 0x10;
return msg;
}
}
public class DiscoveredPrinter
{
public required IPAddress IPAddress { get; init; }
public required byte[] ResponseData { get; init; }
public DateTime DiscoveredAt { get; init; }
public string GetResponseDataAsHex()
{
return string.Join(" ", ResponseData.Select(b => $"{b:X2}"));
}
}

18
Discovery/Program.cs Normal file
View File

@@ -0,0 +1,18 @@
using Inspectron.Epson;
Console.WriteLine("Listening for printer responses...\n");
var discoveryService = new PrinterDiscoveryService();
var printers = await discoveryService.DiscoverPrintersAsync(
timeout: TimeSpan.FromSeconds(5),
onPrinterDiscovered: printer =>
{
Console.WriteLine($"Received {printer.ResponseData.Length} bytes from {printer.IPAddress}");
Console.WriteLine(printer.GetResponseDataAsHex());
Console.WriteLine();
});
Console.WriteLine($"\nDiscovery complete. Found {printers.Count} printer(s).");

68
Discovery/discovery.c Normal file
View File

@@ -0,0 +1,68 @@
#include <stdio.h>
#include <winsock.h>
#define MAXBUF 512
char buf[MAXBUF];
int main(int argc, char* argv[])
{
WSADATA data;
SOCKET sock;
struct sockaddr_in addr;
int i, len, fromlen;
if (argc != 2) {
printf("usage: wudp <IP address>\n");
exit(1);
}
/* initialize windows socket */
WSAStartup(0x0101, &data);
/* Create socket */
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
fprintf(stderr, "Error socket(): %d\n", WSAGetLastError());
exit(1);
}
/* initialize the parameter */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(3289);
addr.sin_addr.s_addr = inet_addr(argv[1]);
/* make a packet (PRINTER STATUS) */
buf[0] = 'E';
buf[1] = 'P';
buf[2] = 'S';
buf[3] = 'O';
buf[4] = 'N';
buf[5] = 'Q'; // PacketType(Q)
buf[6] = 0x03; // DeviceType(3)
buf[7] = 0x00; // DeviceNumber(0)
buf[8] = 0x00; // Function(0010h)
buf[9] = 0x10;
buf[10] = 0x00; // Result
buf[11] = 0x00;
buf[12] = 0x00; // Parameter length
buf[13] = 0x00;
/* send a packet */
i = sendto(sock, buf, 14, 0, (struct sockaddr*)&addr, sizeof(addr));
/* receive packet */
fromlen = sizeof(addr);
len = recvfrom(sock, buf, MAXBUF, 0, (struct sockaddr*)&addr, &fromlen);
/* print receive packet */
if (len) {
if ((buf[10] == 0x00) && (buf[11] == 0x00))
for (i = 0; i < len; i++)
printf("%3d:%02Xh\n", i, buf[i] & 0xff);
}
/* close socket */
closesocket(sock);
return 0;
}