From b76f3ab65f57bc405302c0df1a85e87be7cc18b0 Mon Sep 17 00:00:00 2001 From: Maff Date: Thu, 22 Aug 2019 14:20:35 +0100 Subject: [PATCH] add IUsb interface as connection interface for printer library --- libsharperang/Base.cs | 2 ++ libsharperang/IUsb.cs | 38 +++++++++++++++++++++++ libsharperang/libsharperang.csproj | 1 + libsharperang/usb.cs | 48 ++++++++++++++++++++++++++---- 4 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 libsharperang/IUsb.cs diff --git a/libsharperang/Base.cs b/libsharperang/Base.cs index 3dc9187..ab2cfbd 100644 --- a/libsharperang/Base.cs +++ b/libsharperang/Base.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Text; +using Vadavo.NEscPos; +using Vadavo.NEscPos.Printable; namespace libsharperang { public abstract class Base { diff --git a/libsharperang/IUsb.cs b/libsharperang/IUsb.cs new file mode 100644 index 0000000..b33f6d5 --- /dev/null +++ b/libsharperang/IUsb.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; +using LibUsbDotNet; +using Vadavo.NEscPos.Connectors; + +namespace libsharperang +{ + public class IUsb : IPrinterConnector + { + internal UsbDevice iPrinter; + private UsbEndpointReader pReader; + private UsbEndpointWriter pWriter; + public void Dispose() + { + pReader?.Dispose(); + pWriter?.Dispose(); + IUsbDevice p = iPrinter as IUsbDevice; + _ = p?.ReleaseInterface(0); + _ = iPrinter?.Close(); + throw new NotImplementedException(); + } + + public byte[] Read() + { + if (pReader == null) pReader = iPrinter.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01); + byte[] bRead = new byte[1024]; + _ = pReader.Read(bRead, 100, out int _); + return bRead; + } + + public void Write(byte[] data) + { + if (pWriter == null) pWriter = iPrinter.OpenEndpointWriter(LibUsbDotNet.Main.WriteEndpointID.Ep01); + pWriter?.Write(data, 100, out int _); + } + } +} diff --git a/libsharperang/libsharperang.csproj b/libsharperang/libsharperang.csproj index 4f85f0b..3c6eac6 100644 --- a/libsharperang/libsharperang.csproj +++ b/libsharperang/libsharperang.csproj @@ -8,6 +8,7 @@ + diff --git a/libsharperang/usb.cs b/libsharperang/usb.cs index a99aaa9..5a34453 100644 --- a/libsharperang/usb.cs +++ b/libsharperang/usb.cs @@ -3,14 +3,23 @@ using System.Linq; using System.Collections.Generic; using LibUsbDotNet; using LibUsbDotNet.Main; +using Vadavo.NEscPos.Connectors; namespace libsharperang { public class USB : Base { + //both P1 and P2 models share the same idV and idP over USB public readonly ushort idVendor=0x4348; public readonly ushort idProduct=0x5584; + //differentiating between the two is a case of checking the product name + //P1 is identified as "MiaoMiaoji" or "MTTII Printer" + //P2 is identified as "Paperang_P2" + //Notable is that the idV and idP appear to belong not to Paperang, but to a generic CH34x printer adaptor device + // so it should be a constraint to check that the device descriptors match known details for supported devices, + // not just idV and idP public UsbDevice printer; public List pInstances; public List pIds; + public IUsb pUsb; public USB() { ActiveConnectionType=ConnectionType.USB; @@ -19,12 +28,13 @@ namespace libsharperang { public bool InitUSB() { //NOTE - in order for this to work, you must use Zadig to change the driver for // the printer from usbprint to WinUSB - if (UsbDevice.AllWinUsbDevices.Count == 0) return false; + //On MacOS and Linux libusb should "just work" here - testing is pending however. + if (UsbDevice.AllDevices.Count == 0) return false; //genuinely just having some fun with Linq, don't judge me. //TODO: work out a way of distinguishing multiple devices with same GUID // which happens when two of the same device are connected // the only thing that differs seemingly is the Address - pInstances = (from d in UsbDevice.AllWinUsbDevices + pInstances = (from d in UsbDevice.AllDevices where d.Vid == idVendor && d.Pid == idProduct select d) .ToList(); @@ -35,12 +45,12 @@ namespace libsharperang { return (pIds.Count > 0); } public List GetAddressesFromGuid(Guid deviceId) { - return (from d in UsbDevice.AllWinUsbDevices + return (from d in UsbDevice.AllDevices where d.DeviceInterfaceGuids.Contains(deviceId) select d.DeviceProperties.Where(k => k.Key=="Address").FirstOrDefault().Value).ToList().ConvertAll(v => (int)v); } public bool OpenUSB() { - if (UsbDevice.AllWinUsbDevices.Count == 0) return false; + if (UsbDevice.AllDevices.Count == 0) return false; if (pIds.Count == 0) return false; return OpenUSB(pIds.FirstOrDefault()); } @@ -49,7 +59,7 @@ namespace libsharperang { } public bool OpenUSB(Guid deviceId, int deviceIndex) { //first thought is to say "forgive me lord for i have sinned" but i am absolutely not repentant for this - bool OpenResult = (from d in UsbDevice.AllWinUsbDevices + bool OpenResult = (from d in UsbDevice.AllDevices where d.DeviceInterfaceGuids.Contains(deviceId) && d.DeviceProperties.Where(k=>k.Key=="Address" && (int)k.Value==deviceIndex).Count() > 0 select d) @@ -59,6 +69,34 @@ namespace libsharperang { return OpenResult; } + public bool ClaimUSB() + { + if (printer is null || printer.IsOpen) return false; + IUsbDevice p = printer as IUsbDevice; + p?.SetConfiguration(1); + p?.ClaimInterface(0); + pUsb.iPrinter = printer; + return true; + } + + + + /* + * TODO PollPrinter + * disassembly of Paperang for Mac comes up with the following + * method.Printer.checkConnect() does: + * * method.Printer.checkConnectFlag() && return something + * 0x01a022300 + * 0xffffffff + * 0x00000000963007772c610eeeba51099919c46d078ff4 + * + * need to USBPcap the mac software's comms to confirm above + * + * Paperang for Windows does completely different. + * ...apparently when the USB URB_CONTROL response says "COMMAND SET:ESC/POS" that means you literally just communicate with it using the ESC/POS protocol + * ...so i've wasted a lot of time trying to reverse-engineer an open spec.. + */ + public string FoundPrinterGuids() => pIds .ConvertAll(p => p.ToString()) .Aggregate((a, b) => a+","+b);