Escl: Serve default naps2 icon for scanners

Not sure if it's fully working as no icon is showing up in macOS yet.
This commit is contained in:
Ben Olden-Cooligan 2023-11-26 20:37:25 -08:00
parent bb483b963f
commit c6d55ac76a
5 changed files with 37 additions and 7 deletions

View File

@ -33,7 +33,7 @@ internal class EsclApiController : WebApiController
new XElement(PwgNs + "SerialNumber", caps.SerialNumber),
new XElement(ScanNs + "UUID", "0e468f6d-e5dc-4abe-8e9f-ad08d8546b0c"),
new XElement(ScanNs + "AdminURI", ""),
new XElement(ScanNs + "IconURI", ""),
new XElement(ScanNs + "IconURI", caps.IconPng != null ? $"http://naps2-{caps.Uuid}.local.:{_deviceConfig.Port}/eSCL/icon.png" : ""),
new XElement(ScanNs + "Naps2Extensions", "Progress"),
new XElement(ScanNs + "SettingProfiles",
new XElement(ScanNs + "SettingProfile",
@ -70,6 +70,22 @@ internal class EsclApiController : WebApiController
await writer.WriteAsync(doc);
}
[Route(HttpVerbs.Get, "/icon.png")]
public async Task GetIcon()
{
if (_deviceConfig.Capabilities.IconPng != null)
{
Response.ContentType = "image/png";
using var stream = Response.OutputStream;
var buffer = _deviceConfig.Capabilities.IconPng;
await stream.WriteAsync(buffer, 0, buffer.Length);
}
else
{
Response.StatusCode = 404;
}
}
[Route(HttpVerbs.Get, "/ScannerStatus")]
public async Task GetScannerStatus()
{

View File

@ -14,27 +14,32 @@ public class MdnsAdvertiser : IDisposable
public void AdvertiseDevice(EsclDeviceConfig deviceConfig)
{
if (deviceConfig.Capabilities.Uuid == null)
var caps = deviceConfig.Capabilities;
if (caps.Uuid == null)
{
throw new ArgumentException("UUID must be specified");
}
var name = deviceConfig.Capabilities.MakeAndModel;
var name = caps.MakeAndModel;
var service = new ServiceProfile(name, "_uscan._tcp", (ushort) deviceConfig.Port);
var domain = $"naps2-{deviceConfig.Capabilities.Uuid}";
var domain = $"naps2-{caps.Uuid}";
service.HostName = DomainName.Join(domain, service.Domain);
service.AddProperty("txtvers", "1");
service.AddProperty("Vers", "2.0"); // TODO: verify
if (deviceConfig.Capabilities.IconPng != null)
{
service.AddProperty("representation", $"http://naps2-{caps.Uuid}.local.:{deviceConfig.Port}/eSCL/icon.png");
}
service.AddProperty("rs", "eSCL");
service.AddProperty("ty", name);
service.AddProperty("pdl", "application/pdf,image/jpeg,image/png");
// TODO: Actual adf/duplex, etc.
service.AddProperty("uuid", deviceConfig.Capabilities.Uuid);
service.AddProperty("uuid", caps.Uuid);
service.AddProperty("cs", "color,grayscale,binary");
service.AddProperty("is", "platen"); // and ,adf
service.AddProperty("duplex", "F");
_sd.Announce(service);
_sd.Advertise(service);
_serviceProfiles.Add(deviceConfig.Capabilities.Uuid, service);
_serviceProfiles.Add(caps.Uuid, service);
}
public void UnadvertiseDevice(EsclDeviceConfig deviceConfig)

View File

@ -2,12 +2,13 @@ namespace NAPS2.Escl;
public class EsclCapabilities
{
public string? Version { get; init; }
public string Version { get; init; } = "2.6";
public string? MakeAndModel { get; init; }
public string? SerialNumber { get; init; }
public string? Uuid { get; init; }
public string? AdminUri { get; init; }
public string? IconUri { get; init; }
public byte[]? IconPng { get; init; }
public string? Naps2Extensions { get; init; }
public EsclInputCaps? PlatenCaps { get; init; }
public EsclInputCaps? AdfSimplexCaps { get; init; }

View File

@ -11,6 +11,7 @@ public class SharedDeviceManager : ISharedDeviceManager
{
_config = config;
_server = new ScanServer(scanningContext);
_server.SetDefaultIcon(Icons.scanner_128);
RegisterDevicesFromConfig();
}

View File

@ -9,6 +9,7 @@ public class ScanServer : IDisposable
private readonly ScanningContext _scanningContext;
private readonly Dictionary<(Driver, string), EsclDeviceConfig> _currentDevices = new();
private EsclServer? _esclServer;
private byte[]? _defaultIconPng;
public ScanServer(ScanningContext scanningContext)
{
@ -18,6 +19,11 @@ public class ScanServer : IDisposable
internal ScanController ScanController { get; set; }
public void SetDefaultIcon(IMemoryImage icon) =>
SetDefaultIcon(icon.SaveToMemoryStream(ImageFileFormat.Png).ToArray());
public void SetDefaultIcon(byte[] iconPng) => _defaultIconPng = iconPng;
public void RegisterDevice(SharedDevice device)
{
var key = (device.Driver, device.Device.ID);
@ -42,6 +48,7 @@ public class ScanServer : IDisposable
{
MakeAndModel = device.Name,
Uuid = device.Uuid,
IconPng = _defaultIconPng,
// TODO: Ideally we want to get the actual device capabilities
PlatenCaps = new EsclInputCaps
{