xref: /haiku/src/add-ons/print/transports/parallel_port/ParallelTransport.cpp (revision 830f67ef991407f287dbc1238aa5f5906d90c991)
1 /*****************************************************************************/
2 // Parallel 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,2002 Haiku 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 ParallelTransport : public BDataIO {
41 public:
42 	ParallelTransport(BDirectory* printer, BMessage* msg);
43 	~ParallelTransport();
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 // Implementation of ParallelTransport
55 ParallelTransport::ParallelTransport(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/parallel/"), 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("_parallel/DeviceName", device);
84 }
85 
86 ParallelTransport::~ParallelTransport()
87 {
88 	if (InitCheck() == B_OK)
89 		close(fFile);
90 }
91 
92 ssize_t ParallelTransport::Read(void* buffer, size_t size)
93 {
94 	return read(fFile, buffer, size);
95 }
96 
97 ssize_t ParallelTransport::Write(const void* buffer, size_t size)
98 {
99 	return write(fFile, buffer, size);
100 }
101 
102 BDataIO* instantiate_transport(BDirectory* printer, BMessage* msg)
103 {
104 	ParallelTransport* transport = new ParallelTransport(printer, msg);
105 	if (transport->InitCheck() == B_OK)
106 		return transport;
107 
108 	delete transport;
109 	return NULL;
110 }
111 
112 status_t list_transport_ports(BMessage* msg)
113 {
114 	BDirectory dir("/dev/parallel");
115 	status_t rc;
116 
117 	if ((rc=dir.InitCheck()) != B_OK)
118 		return rc;
119 
120 	if ((rc=dir.Rewind()) != B_OK)
121 		return rc;
122 
123 	entry_ref ref;
124 	while(dir.GetNextRef(&ref) == B_OK)
125 		msg->AddString("port_id", ref.name);
126 
127 	return B_OK;
128 }
129 
130