xref: /haiku/src/add-ons/print/transports/serial_port/SerialTransport.cpp (revision 83b1a68c52ba3e0e8796282759f694b7fdddf06d)
1 /*****************************************************************************/
2 // Serial port transport add-on.
3 //
4 // Author
5 //   Michael Pfeiffer
6 //
7 // This application and all source files used in its construction, except
8 // where noted, are licensed under the MIT License, and have been written
9 // and are:
10 //
11 // Copyright (c) 2001-2003 OpenBeOS Project
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 /*****************************************************************************/
31 
32 #include <unistd.h>
33 #include <stdio.h>
34 
35 #include <StorageKit.h>
36 #include <SupportKit.h>
37 
38 #include "PrintTransportAddOn.h"
39 
40 class SerialTransport : public BDataIO {
41 public:
42 	SerialTransport(BDirectory* printer, BMessage* msg);
43 	~SerialTransport();
44 
45 	status_t InitCheck() { return fFile > -1 ? B_OK : B_ERROR; }
46 
47 	ssize_t Read(void* buffer, size_t size);
48 	ssize_t Write(const void* buffer, size_t size);
49 
50 private:
51 	int fFile;
52 };
53 
54 // Impelmentation of SerialTransport
55 SerialTransport::SerialTransport(BDirectory* printer, BMessage* msg)
56 	: fFile(-1)
57 {
58 	char address[80];
59 	char device[B_PATH_NAME_LENGTH];
60 	bool bidirectional = true;
61 
62 	unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address));
63 	if (size <= 0 || size >= sizeof(address)) return;
64 	address[size] = 0; // make sure string is 0-terminated
65 
66 	strcat(strcpy(device, "/dev/ports/"), address);
67 	fFile = open(device, O_RDWR | O_EXCL, 0);
68 	if (fFile < 0) {
69 		// Try unidirectional access mode
70 		bidirectional = false;
71 		fFile = open(device, O_WRONLY | O_EXCL, 0);
72 	}
73 
74 	if (fFile < 0)
75 		return;
76 
77 	if (! msg)
78 		// Caller don't care about transport init message output content...
79 		return;
80 
81 	msg->what = 'okok';
82 	msg->AddBool("bidirectional", bidirectional);
83 	msg->AddString("_serial/DeviceName", device);
84 
85 }
86 
87 SerialTransport::~SerialTransport()
88 {
89 	if (InitCheck() == B_OK)
90 		close(fFile);
91 }
92 
93 ssize_t SerialTransport::Read(void* buffer, size_t size)
94 {
95 	return read(fFile, buffer, size);
96 }
97 
98 ssize_t SerialTransport::Write(const void* buffer, size_t size)
99 {
100 	return write(fFile, buffer, size);
101 }
102 
103 BDataIO* instantiate_transport(BDirectory* printer, BMessage* msg)
104 {
105 	SerialTransport* transport = new SerialTransport(printer, msg);
106 	if (transport->InitCheck() == B_OK)
107 		return transport;
108 
109 	delete transport;
110 	return NULL;
111 }
112 
113 status_t list_transport_ports(BMessage* msg)
114 {
115 	BDirectory dir("/dev/ports");
116 	status_t rc;
117 
118 	if ((rc=dir.InitCheck()) != B_OK)
119 		return rc;
120 
121 	if ((rc=dir.Rewind()) != B_OK)
122 		return rc;
123 
124 	entry_ref ref;
125 	while(dir.GetNextRef(&ref) == B_OK)
126 		msg->AddString("port_id", ref.name);
127 
128 	return B_OK;
129 }
130 
131