From 1407e6d7b18ee10eeb8f688e966d45f9599b4abe Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 3 Jun 2018 16:41:06 +0200 Subject: [PATCH] Complete implementation of printer serial transport - Allow to configure the baudrate (it is set by the printer settings, but the transport didn't care) - Implement reading from the serial port (some printers will need us to poll the status and the like, as there is usually no hardware flow control) Change-Id: I70ba2566595d5dfa5eda3d518614db6514cb2398 --- headers/libs/print/libprint/GraphicsDriver.h | 5 + headers/libs/print/libprint/Transport.h | 2 + .../serial_port/SerialTransport.cpp | 91 +++++++++++-------- src/libs/print/libprint/GraphicsDriver.cpp | 29 +++++- src/libs/print/libprint/Transport.cpp | 13 +++ 5 files changed, 97 insertions(+), 43 deletions(-) diff --git a/headers/libs/print/libprint/GraphicsDriver.h b/headers/libs/print/libprint/GraphicsDriver.h index de84ada53e..694a150452 100644 --- a/headers/libs/print/libprint/GraphicsDriver.h +++ b/headers/libs/print/libprint/GraphicsDriver.h @@ -54,6 +54,11 @@ protected: void WriteSpoolChar(char c) throw (TransportException); + void ReadSpoolData(void* buffer, size_t size) + throw (TransportException); + int ReadSpoolChar() + throw (TransportException); + static void ConvertToRGB24(const void* src, void* dst, int width, color_space cs); static void ConvertToGray(const void* src, void* dst, int width, diff --git a/headers/libs/print/libprint/Transport.h b/headers/libs/print/libprint/Transport.h index bcfd06390d..b2f74cc87b 100644 --- a/headers/libs/print/libprint/Transport.h +++ b/headers/libs/print/libprint/Transport.h @@ -39,6 +39,8 @@ public: void Write(const void *buffer, size_t size) throw (TransportException); + void Read(void *buffer, size_t size) + throw (TransportException); bool CheckAbort() const; bool IsPrintToFileCanceled() const; const string& LastError() const; diff --git a/src/add-ons/print/transports/serial_port/SerialTransport.cpp b/src/add-ons/print/transports/serial_port/SerialTransport.cpp index ffcc3978b1..fa0df926b9 100644 --- a/src/add-ons/print/transports/serial_port/SerialTransport.cpp +++ b/src/add-ons/print/transports/serial_port/SerialTransport.cpp @@ -1,42 +1,23 @@ -/*****************************************************************************/ -// Serial port transport add-on. -// -// Author -// Michael Pfeiffer -// -// This application and all source files used in its construction, except -// where noted, are licensed under the MIT License, and have been written -// and are: -// -// Copyright (c) 2001-2003 OpenBeOS Project -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -/*****************************************************************************/ +/* + * Copyright 2001-2017 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Pfeiffer + * Adrien Destugues + */ + #include #include +#include #include #include #include "PrintTransportAddOn.h" + class SerialTransport : public BDataIO { public: SerialTransport(BDirectory* printer, BMessage* msg); @@ -51,18 +32,20 @@ private: int fFile; }; + // Impelmentation of SerialTransport -SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg) +SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg) : fFile(-1) { char address[80]; char device[B_PATH_NAME_LENGTH]; bool bidirectional = true; - unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); + unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, + address, sizeof(address)); if (size <= 0 || size >= sizeof(address)) return; address[size] = 0; // make sure string is 0-terminated - + strcat(strcpy(device, "/dev/ports/"), address); fFile = open(device, O_RDWR | O_EXCL, 0); if (fFile < 0) { @@ -74,9 +57,29 @@ SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg) if (fFile < 0) return; - if (! msg) + int32 baudrate; + size = printer->ReadAttr("transport_baudrate", B_INT32_TYPE, 0, + &baudrate, sizeof(baudrate)); + + struct termios options; + tcgetattr(fFile, &options); + + cfmakeraw(&options); + options.c_cc[VTIME] = 10; // wait for data at most for 1 second + options.c_cc[VMIN] = 0; // allow to return 0 chars + + if (size == sizeof(baudrate)) { + // Printer driver asked for a specific baudrate, configure it + cfsetispeed(&options, baudrate); + cfsetospeed(&options, baudrate); + } + + tcsetattr(fFile, TCSANOW, &options); + + if (msg == NULL) { // Caller don't care about transport init message output content... return; + } msg->what = 'okok'; msg->AddBool("bidirectional", bidirectional); @@ -84,23 +87,30 @@ SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg) } + SerialTransport::~SerialTransport() { if (InitCheck() == B_OK) close(fFile); } -ssize_t SerialTransport::Read(void* buffer, size_t size) + +ssize_t +SerialTransport::Read(void* buffer, size_t size) { return read(fFile, buffer, size); } -ssize_t SerialTransport::Write(const void* buffer, size_t size) + +ssize_t +SerialTransport::Write(const void* buffer, size_t size) { return write(fFile, buffer, size); } -BDataIO* instantiate_transport(BDirectory* printer, BMessage* msg) + +BDataIO* +instantiate_transport(BDirectory* printer, BMessage* msg) { SerialTransport* transport = new SerialTransport(printer, msg); if (transport->InitCheck() == B_OK) @@ -110,7 +120,9 @@ BDataIO* instantiate_transport(BDirectory* printer, BMessage* msg) return NULL; } -status_t list_transport_ports(BMessage* msg) + +status_t +list_transport_ports(BMessage* msg) { BDirectory dir("/dev/ports"); status_t rc; @@ -122,9 +134,8 @@ status_t list_transport_ports(BMessage* msg) return rc; entry_ref ref; - while(dir.GetNextRef(&ref) == B_OK) + while (dir.GetNextRef(&ref) == B_OK) msg->AddString("port_id", ref.name); return B_OK; } - diff --git a/src/libs/print/libprint/GraphicsDriver.cpp b/src/libs/print/libprint/GraphicsDriver.cpp index f530e21949..5d8b4a789e 100644 --- a/src/libs/print/libprint/GraphicsDriver.cpp +++ b/src/libs/print/libprint/GraphicsDriver.cpp @@ -756,7 +756,7 @@ GraphicsDriver::EndDocument(bool) } -void +void GraphicsDriver::WriteSpoolData(const void* buffer, size_t size) throw (TransportException) { @@ -766,7 +766,7 @@ GraphicsDriver::WriteSpoolData(const void* buffer, size_t size) } -void +void GraphicsDriver::WriteSpoolString(const char* format, ...) throw (TransportException) { @@ -782,7 +782,7 @@ GraphicsDriver::WriteSpoolString(const char* format, ...) } -void +void GraphicsDriver::WriteSpoolChar(char c) throw (TransportException) { @@ -793,6 +793,29 @@ GraphicsDriver::WriteSpoolChar(char c) } +void +GraphicsDriver::ReadSpoolData(void* buffer, size_t size) + throw (TransportException) +{ + if (fTransport == NULL) + return; + fTransport->Read(buffer, size); +} + + +int +GraphicsDriver::ReadSpoolChar() + throw (TransportException) +{ + if (fTransport == NULL) + return -1; + + char c; + fTransport->Read(&c, 1); + return c; +} + + bool GraphicsDriver::_NeedRotateBitmapBand() const { diff --git a/src/libs/print/libprint/Transport.cpp b/src/libs/print/libprint/Transport.cpp index 0b082dc329..2a047b9785 100644 --- a/src/libs/print/libprint/Transport.cpp +++ b/src/libs/print/libprint/Transport.cpp @@ -147,3 +147,16 @@ Transport::Write(const void* buffer, size_t size) throw(TransportException) } throw TransportException(LastError()); } + + +void +Transport::Read(void* buffer, size_t size) throw(TransportException) +{ + if (fDataStream) { + if (size == (size_t)fDataStream->Read(buffer, size)) { + return; + } + SetLastError("BDataIO::Read failed."); + } + throw TransportException(LastError()); +}