xref: /haiku/src/add-ons/print/transports/usb_port/USBTransport.cpp (revision 89755088d790ff4fe36f8aa77dacb2bd15507108)
1 /*****************************************************************************/
2 // USB port transport add-on,
3 // changes by Andreas Benzler, Philippe Houdoin
4 //
5 // Original from Parallel
6 // port transport add-on.
7 //
8 // Author
9 //   Michael Pfeiffer
10 //
11 // This application and all source files used in its construction, except
12 // where noted, are licensed under the MIT License, and have been written
13 // and are:
14 //
15 // Copyright (c) 2001-2004 OpenBeOS Project
16 //
17 // Permission is hereby granted, free of charge, to any person obtaining a
18 // copy of this software and associated documentation files (the "Software"),
19 // to deal in the Software without restriction, including without limitation
20 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 // and/or sell copies of the Software, and to permit persons to whom the
22 // Software is furnished to do so, subject to the following conditions:
23 //
24 // The above copyright notice and this permission notice shall be included
25 // in all copies or substantial portions of the Software.
26 //
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
28 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33 // DEALINGS IN THE SOFTWARE.
34 /*****************************************************************************/
35 
36 
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <string.h>
40 
41 #include <StorageKit.h>
42 #include <SupportKit.h>
43 
44 #include <USB_printer.h>
45 
46 #include "PrintTransportAddOn.h"
47 
48 
49 class USBTransport : public BDataIO
50 {
51 public:
52 	USBTransport(BDirectory *printer, BMessage *msg);
53 	~USBTransport();
54 
55 	status_t InitCheck() { return fFile > -1 ? B_OK : B_ERROR; };
56 
57 	ssize_t Read(void *buffer, size_t size);
58 	ssize_t Write(const void *buffer, size_t size);
59 
60 private:
61 	int fFile;
62 };
63 
64 
65 // Implementation of transport add-on interface
66 
67 BDataIO *
68 instantiate_transport(BDirectory *printer, BMessage *msg)
69 {
70 	USBTransport * transport = new USBTransport(printer, msg);
71 	if (transport->InitCheck() == B_OK)
72 		return transport;
73 
74 	delete transport;
75 	return NULL;
76 }
77 
78 status_t list_transport_ports(BMessage* msg)
79 {
80 	BDirectory dir("/dev/printer/usb");
81 	status_t rc;
82 
83 	if ((rc=dir.InitCheck()) != B_OK)
84 		return rc;
85 
86 	if ((rc=dir.Rewind()) != B_OK)
87 		return rc;
88 
89 	entry_ref ref;
90 	while(dir.GetNextRef(&ref) == B_OK)
91 		msg->AddString("port_id", ref.name);
92 
93 	return B_OK;
94 }
95 
96 
97 // Implementation of USBTransport
98 
99 USBTransport::USBTransport(BDirectory *printer, BMessage *msg)
100 	: fFile(-1)
101 {
102 	char device_id[USB_PRINTER_DEVICE_ID_LENGTH + 1];
103 	char name[USB_PRINTER_DEVICE_ID_LENGTH + 1];
104 	char *desc;
105 	char *value;
106 	int ret;
107 	bool bidirectional = true;
108 	char *next_token;
109 
110 	// We support only one USB printer, so does BeOS R5.
111 	fFile = open("/dev/printer/usb/0", O_RDWR | O_EXCL | O_BINARY, 0);
112 	if (fFile < 0) {
113 		// Try unidirectional access mode
114 		bidirectional = false;
115 		fFile = open("/dev/printer/usb/0", O_WRONLY | O_EXCL | O_BINARY, 0);
116 	}
117 
118 	if (fFile < 0)
119 		return;
120 
121 	// Get printer's DEVICE ID string
122 	ret = ioctl(fFile, USB_PRINTER_GET_DEVICE_ID, device_id, sizeof(device_id));
123 	if (ret < 0) {
124 		close(fFile);
125 		fFile = -1;
126 		return;
127 	}
128 
129 	if (! msg)
130 		// Caller don't care about transport init message output content...
131 		return;
132 
133 	// Fill up the message
134 	msg->what = 'okok';
135 
136 	msg->AddBool("bidirectional", bidirectional);
137 	msg->AddString("device_id", device_id);
138 
139 	// parse and split the device_id string into separate parameters
140 	desc = strtok_r(device_id, ":", &next_token);
141 	while (desc) {
142 		snprintf(name, sizeof(name), "DEVID:%s", desc);
143 		value = strtok_r(NULL, ";", &next_token);
144 		if (!value)
145 			break;
146 		msg->AddString(name, value);
147 
148 		// next device descriptor
149 		desc = strtok_r(NULL, ":", &next_token);
150 	}
151 }
152 
153 
154 USBTransport::~USBTransport()
155 {
156 	if (fFile > -1)
157 		close(fFile);
158 }
159 
160 
161 ssize_t
162 USBTransport::Read(void *buffer, size_t size)
163 {
164 	return read(fFile, buffer, size);
165 }
166 
167 
168 ssize_t
169 USBTransport::Write(const void *buffer, size_t size)
170 {
171 	return write(fFile, buffer, size);
172 }
173 
174