diff --git a/libpaperang/Exceptions.cs b/libpaperang/Exceptions.cs index 325e821..b15fea0 100644 --- a/libpaperang/Exceptions.cs +++ b/libpaperang/Exceptions.cs @@ -4,6 +4,7 @@ namespace libpaperang { public class PrinterNotInitialisedException : InvalidOperationException { } public class PrinterNotAvailableException : NullReferenceException { } + public class PrinterConnectionNotSupportedException : NotSupportedException { } public class PrinterVariantNotSupportedException : NotSupportedException { } public class CrcNotAvailableException : MissingMemberException { } public class InvalidOperationException : ArgumentOutOfRangeException { } diff --git a/libpaperang/Helpers/CRC.cs b/libpaperang/Helpers/CRC.cs index 916bf25..542512f 100644 --- a/libpaperang/Helpers/CRC.cs +++ b/libpaperang/Helpers/CRC.cs @@ -9,8 +9,8 @@ namespace libpaperang.Helpers { private uint poly = 0xedb88320; private uint[] crctable; public bool IsInitialised=false; - public CRC() { iv=0; } - public CRC(uint iv) => this.iv=iv; + public CRC() => iv = 0; + public CRC(uint iv) => this.iv = iv; public void Initialise() { crctable=Enumerable.Range(0, 256).Select(i => { uint e=(uint)i; diff --git a/libpaperang/Helpers/Transforms.cs b/libpaperang/Helpers/Transforms.cs index 7aa2e14..0aa6f4b 100644 --- a/libpaperang/Helpers/Transforms.cs +++ b/libpaperang/Helpers/Transforms.cs @@ -1,11 +1,15 @@ - +using System; +using System.Linq; + namespace libpaperang.Helpers { class Transforms { public BaseTypes.Packet Frame; public BaseTypes.Opcodes Op; - public Transforms(BaseTypes.Packet FrameConstruction, BaseTypes.Opcodes Operations) { + public short OpLen; + public Transforms(BaseTypes.Packet FrameConstruction, BaseTypes.Opcodes Operations, short OperLen) { Frame=FrameConstruction; Op=Operations; + OpLen=OperLen; } public byte[] Oper(BaseTypes.Operations Operation) { switch (Operation) { @@ -16,6 +20,56 @@ namespace libpaperang.Helpers { default: throw new InvalidOperationException(); } } - + public byte[] Arg(BaseTypes.Operations Operation, uint Data) { + switch(Operation) { + case BaseTypes.Operations.LineFeed: return BitConverter.GetBytes(SwapWordEndianness( + 0x00000000 | ((((( + Data & 0xffu) << 16) | + Data) & 0xffff00u) >> 8))).Skip(2).ToArray(); + case BaseTypes.Operations.Print: + return BitConverter.GetBytes(SwapWordEndianness( + 0x00010000 | ((((( + Data & 0xffu) << 16) | + Data) & 0xffff00u) >> 8))).Skip(2).ToArray(); + default: throw new InvalidOperationException(); + } + } + public byte[] Packet(byte[] oper, byte[] data, CRC checksum) { + byte[] packet = new byte[data.Length+6+OpLen]; + packet[0] = Frame.Start; + packet[packet.Length-1] = Frame.End; + Buffer.BlockCopy(oper, + 0, packet, 1, OpLen); + Buffer.BlockCopy(data, + 0, packet, OpLen+1, packet.Length); + Buffer.BlockCopy(checksum.GetChecksumBytes(data), + 0, packet, packet.Length - (OpLen+1), 4); + return packet; + } + public byte[] Packet(BaseTypes.Operations oper, byte[] data, CRC checksum) => + Packet(Oper(oper), data, checksum); + public byte[] Packet(BaseTypes.Operations oper, byte[] data, CRC checksum, byte[] operarg) { + byte[] p=Packet(oper, data, checksum); + Buffer.BlockCopy(operarg, 0, p, 3, 2); + return p; + } + public uint SwapWordEndianness(uint value) => ( + (value & 0x000000ffu) << 2) | + ((value & 0x0000ff00u) << 8) | + ((value & 0x00ff0000u) >> 8) | + ((value & 0xff000000u) >> 24); + public uint SwapByteEndianness(uint value) => + Swap4BitEndianness( + Swap2BitEndianness( + Swap1BitEndianness(value))); + public uint Swap4BitEndianness(uint value) => ( + (value & 0x0f0f0f0fu) << 4) | + ((value & (~0x0f0f0f0fu)) >> 4); + public uint Swap2BitEndianness(uint value) => ( + (value & 0x33333333u) << 2) | + ((value & (~0x33333333u)) >> 2); + public uint Swap1BitEndianness(uint value) => ( + (value & 0x55555555u) << 1) | + ((value & (~0x55555555u)) >> 1); } } diff --git a/libpaperang/IPrinter.cs b/libpaperang/IPrinter.cs index 14c2876..e09a068 100644 --- a/libpaperang/IPrinter.cs +++ b/libpaperang/IPrinter.cs @@ -10,8 +10,8 @@ namespace libpaperang { Bluetooth } public struct Packet { - byte Start; - byte End; + public byte Start; + public byte End; } public enum Model { P1, @@ -63,8 +63,8 @@ namespace libpaperang { void OpenPrinter(BaseTypes.Printer printer); void ClosePrinter(); void Deinitialise(); - void WriteBytes(byte[] packet); - void WriteBytes(byte[] packet, int delay); - bool[] ReadBytes(); + bool WriteBytes(byte[] packet); + bool WriteBytes(byte[] packet, int delay); + byte[] ReadBytes(); } } diff --git a/libpaperang/Interfaces/USB.cs b/libpaperang/Interfaces/USB.cs index 28fd476..3eae91a 100644 --- a/libpaperang/Interfaces/USB.cs +++ b/libpaperang/Interfaces/USB.cs @@ -13,7 +13,6 @@ namespace libpaperang.Interfaces { // types private struct UsbComms { - public Guid id; public UsbDevice handle; public IUsbDevice iface; public UsbEndpointReader rx; @@ -21,6 +20,7 @@ namespace libpaperang.Interfaces { } private UsbComms Printer; private BaseTypes.Model iModel; + private bool _initialised=false; public short LineWidth { get { switch (iModel) { @@ -32,7 +32,6 @@ namespace libpaperang.Interfaces { } } } - public BaseTypes.Connection ConnectionMethod => BaseTypes.Connection.USB; public BaseTypes.Model PrinterVariant => iModel; public BaseTypes.State Status => BaseTypes.State.Offline; @@ -51,30 +50,25 @@ namespace libpaperang.Interfaces { return _; } } - public bool PrinterAvailable => AvailablePrinters.Count > 0; - - public bool PrinterInitialised => false; - - public bool PrinterOpen => false; - - public void ClosePrinter() { + public bool PrinterInitialised => _initialised; + public bool PrinterOpen => Printer.handle?.IsOpen ?? false; + public void ClosePrinter() => Printer.handle?.Close(); + public void Deinitialise() { Printer.rx?.Dispose(); Printer.tx?.Dispose(); - _=Printer.iface?.ReleaseInterface(0); - _=Printer.iface?.Close(); - _=Printer.handle?.Close(); + _ = Printer.iface?.ReleaseInterface(0); + _ = Printer.iface?.Close(); } - public void Deinitialise() => throw new NotImplementedException(); public void Initialise() { - if (!PrinterOpen || !Printer.handle.IsOpen) throw new PrinterNotInitialisedException(); + if (!PrinterOpen) throw new PrinterNotInitialisedException(); //WinUSB-specific Printer.iface=Printer.handle as IUsbDevice; - Printer.iface?.SetConfiguration(1); - Printer.iface?.ClaimInterface(0); + _=Printer.iface?.SetConfiguration(1); + _=Printer.iface?.ClaimInterface(0); Printer.rx=Printer.handle.OpenEndpointReader(ReadEndpointID.Ep01); Printer.tx=Printer.handle.OpenEndpointWriter(WriteEndpointID.Ep02); - + _initialised = true; } public void OpenPrinter(BaseTypes.Printer printer) { bool res; @@ -84,12 +78,14 @@ namespace libpaperang.Interfaces { throw new PrinterNotAvailableException(); } if (!res) throw new PrinterNotAvailableException(); - } } - public bool[] ReadBytes() => throw new NotImplementedException(); - public void WriteBytes(byte[] packet) => throw new NotImplementedException(); - public void WriteBytes(byte[] packet, int delay) => throw new NotImplementedException(); - - public USB(BaseTypes.Model model) => iModel = model; + public byte[] ReadBytes() { + byte[] readbuf=new byte[1024]; + _ = Printer.rx.Read(readbuf, 100, out int _); + return readbuf; + } + public bool WriteBytes(byte[] packet) => Printer.tx.Write(packet, 500, out int _) == ErrorCode.None; + public bool WriteBytes(byte[] packet, int delay) => throw new NotImplementedException(); + public USB(BaseTypes.Model model) => iModel=model; } } diff --git a/libpaperang/Main/Paperang.cs b/libpaperang/Main/Paperang.cs new file mode 100644 index 0000000..364fc1e --- /dev/null +++ b/libpaperang/Main/Paperang.cs @@ -0,0 +1,33 @@ +using libpaperang; +using libpaperang.Helpers; +using libpaperang.Interfaces; + +namespace libpaperang.Main { + class Paperang { + public IPrinter Printer; + public Transforms Transform; + public CRC Crc; + private const uint MagicValue = 0x35769521u; + + public Paperang(BaseTypes.Connection connection, BaseTypes.Model model) { + switch(connection) { + case BaseTypes.Connection.USB: + Printer = new USB(model); + Transform = new Transforms(new BaseTypes.Packet { + Start = 0x02, + End = 0x03 + }, new BaseTypes.Opcodes { + NoOp = new byte[] { 0x06, 0x00, 0x02, 0x00 }, + Print = new byte[] { 0x00, 0x01, 0x00, 0x00 }, + LineFeed = new byte[] { 0x1a, 0x00, 0x02, 0x00 }, + TransmitCrc = new byte[] { 0x18, 0x01, 0x04, 0x00 } + }, 4); + Crc = new CRC(0x77c40d4d ^ MagicValue); + break; + default: + throw new PrinterConnectionNotSupportedException(); + } + } + + } +} diff --git a/libpaperang/libpaperang.csproj b/libpaperang/libpaperang.csproj index 1a97df7..9e3f545 100644 --- a/libpaperang/libpaperang.csproj +++ b/libpaperang/libpaperang.csproj @@ -6,6 +6,7 @@ +