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
This commit is contained in:
Adrien Destugues
2018-06-05 21:44:14 +00:00
committed by waddlesplash
parent 4f059c1fc5
commit 1407e6d7b1
5 changed files with 97 additions and 43 deletions
@@ -54,6 +54,11 @@ protected:
void WriteSpoolChar(char c) void WriteSpoolChar(char c)
throw (TransportException); 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, static void ConvertToRGB24(const void* src, void* dst, int width,
color_space cs); color_space cs);
static void ConvertToGray(const void* src, void* dst, int width, static void ConvertToGray(const void* src, void* dst, int width,
+2
View File
@@ -39,6 +39,8 @@ public:
void Write(const void *buffer, size_t size) void Write(const void *buffer, size_t size)
throw (TransportException); throw (TransportException);
void Read(void *buffer, size_t size)
throw (TransportException);
bool CheckAbort() const; bool CheckAbort() const;
bool IsPrintToFileCanceled() const; bool IsPrintToFileCanceled() const;
const string& LastError() const; const string& LastError() const;
@@ -1,42 +1,23 @@
/*****************************************************************************/ /*
// Serial port transport add-on. * Copyright 2001-2017 Haiku Inc. All rights reserved.
// * Distributed under the terms of the MIT License.
// Author *
// Michael Pfeiffer * Authors:
// * Michael Pfeiffer
// This application and all source files used in its construction, except * Adrien Destugues <[email protected]>
// 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.
/*****************************************************************************/
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <termios.h>
#include <StorageKit.h> #include <StorageKit.h>
#include <SupportKit.h> #include <SupportKit.h>
#include "PrintTransportAddOn.h" #include "PrintTransportAddOn.h"
class SerialTransport : public BDataIO { class SerialTransport : public BDataIO {
public: public:
SerialTransport(BDirectory* printer, BMessage* msg); SerialTransport(BDirectory* printer, BMessage* msg);
@@ -51,18 +32,20 @@ private:
int fFile; int fFile;
}; };
// Impelmentation of SerialTransport // Impelmentation of SerialTransport
SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg) SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg)
: fFile(-1) : fFile(-1)
{ {
char address[80]; char address[80];
char device[B_PATH_NAME_LENGTH]; char device[B_PATH_NAME_LENGTH];
bool bidirectional = true; 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; if (size <= 0 || size >= sizeof(address)) return;
address[size] = 0; // make sure string is 0-terminated address[size] = 0; // make sure string is 0-terminated
strcat(strcpy(device, "/dev/ports/"), address); strcat(strcpy(device, "/dev/ports/"), address);
fFile = open(device, O_RDWR | O_EXCL, 0); fFile = open(device, O_RDWR | O_EXCL, 0);
if (fFile < 0) { if (fFile < 0) {
@@ -74,9 +57,29 @@ SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg)
if (fFile < 0) if (fFile < 0)
return; 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... // Caller don't care about transport init message output content...
return; return;
}
msg->what = 'okok'; msg->what = 'okok';
msg->AddBool("bidirectional", bidirectional); msg->AddBool("bidirectional", bidirectional);
@@ -84,23 +87,30 @@ SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg)
} }
SerialTransport::~SerialTransport() SerialTransport::~SerialTransport()
{ {
if (InitCheck() == B_OK) if (InitCheck() == B_OK)
close(fFile); 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); 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); 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); SerialTransport* transport = new SerialTransport(printer, msg);
if (transport->InitCheck() == B_OK) if (transport->InitCheck() == B_OK)
@@ -110,7 +120,9 @@ BDataIO* instantiate_transport(BDirectory* printer, BMessage* msg)
return NULL; return NULL;
} }
status_t list_transport_ports(BMessage* msg)
status_t
list_transport_ports(BMessage* msg)
{ {
BDirectory dir("/dev/ports"); BDirectory dir("/dev/ports");
status_t rc; status_t rc;
@@ -122,9 +134,8 @@ status_t list_transport_ports(BMessage* msg)
return rc; return rc;
entry_ref ref; entry_ref ref;
while(dir.GetNextRef(&ref) == B_OK) while (dir.GetNextRef(&ref) == B_OK)
msg->AddString("port_id", ref.name); msg->AddString("port_id", ref.name);
return B_OK; return B_OK;
} }
+26 -3
View File
@@ -756,7 +756,7 @@ GraphicsDriver::EndDocument(bool)
} }
void void
GraphicsDriver::WriteSpoolData(const void* buffer, size_t size) GraphicsDriver::WriteSpoolData(const void* buffer, size_t size)
throw (TransportException) throw (TransportException)
{ {
@@ -766,7 +766,7 @@ GraphicsDriver::WriteSpoolData(const void* buffer, size_t size)
} }
void void
GraphicsDriver::WriteSpoolString(const char* format, ...) GraphicsDriver::WriteSpoolString(const char* format, ...)
throw (TransportException) throw (TransportException)
{ {
@@ -782,7 +782,7 @@ GraphicsDriver::WriteSpoolString(const char* format, ...)
} }
void void
GraphicsDriver::WriteSpoolChar(char c) GraphicsDriver::WriteSpoolChar(char c)
throw (TransportException) 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 bool
GraphicsDriver::_NeedRotateBitmapBand() const GraphicsDriver::_NeedRotateBitmapBand() const
{ {
+13
View File
@@ -147,3 +147,16 @@ Transport::Write(const void* buffer, size_t size) throw(TransportException)
} }
throw TransportException(LastError()); 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());
}