1 /*
2  *   CUPS Backend common code
3  *
4  *   (c) 2013-2019 Solomon Peachy <pizza@shaftnet.org>
5  *
6  *   The latest version of this program can be found at:
7  *
8  *     http://git.shaftnet.org/cgit/selphy_print.git
9  *
10  *   This program is free software; you can redistribute it and/or modify it
11  *   under the terms of the GNU General Public License as published by the Free
12  *   Software Foundation; either version 2 of the License, or (at your option)
13  *   any later version.
14  *
15  *   This program is distributed in the hope that it will be useful, but
16  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18  *   for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
22  *
23  *          [http://www.gnu.org/licenses/gpl-2.0.html]
24  *
25  *   SPDX-License-Identifier: GPL-2.0+
26  *
27  */
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <signal.h>
38 
39 #include <libusb.h>
40 #include <arpa/inet.h>
41 
42 #ifndef __BACKEND_COMMON_H
43 #define __BACKEND_COMMON_H
44 
45 #define STR_LEN_MAX 64
46 #define STATE( ... ) do { if (!quiet) fprintf(stderr, "STATE: " __VA_ARGS__ ); } while(0)
47 #define ATTR( ... ) do { if (!quiet) fprintf(stderr, "ATTR: " __VA_ARGS__ ); } while(0)
48 #define PAGE( ... ) do { if (!quiet) fprintf(stderr, "PAGE: " __VA_ARGS__ ); } while(0)
49 #define DEBUG( ... ) do { if (!quiet) fprintf(stderr, "DEBUG: " __VA_ARGS__ ); } while(0)
50 #define DEBUG2( ... ) do { if (!quiet) fprintf(stderr, __VA_ARGS__ ); } while(0)
51 #define INFO( ... )  do { if (!quiet) fprintf(stderr, "INFO: " __VA_ARGS__ ); } while(0)
52 #define WARNING( ... )  do { fprintf(stderr, "WARNING: " __VA_ARGS__ ); } while(0)
53 #define ERROR( ... ) do { fprintf(stderr, "ERROR: " __VA_ARGS__ ); sleep(1); } while (0)
54 
55 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
56 #define le64_to_cpu(__x) __x
57 #define le32_to_cpu(__x) __x
58 #define le16_to_cpu(__x) __x
59 #define be16_to_cpu(__x) ntohs(__x)
60 #define be32_to_cpu(__x) ntohl(__x)
61 #define be64_to_cpu(__x) ((__uint64_t)(                         \
62         (((__uint64_t)(__x) & (__uint64_t)0x00000000000000ffULL) << 56) |   \
63         (((__uint64_t)(__x) & (__uint64_t)0x000000000000ff00ULL) << 40) |   \
64         (((__uint64_t)(__x) & (__uint64_t)0x0000000000ff0000ULL) << 24) |   \
65         (((__uint64_t)(__x) & (__uint64_t)0x00000000ff000000ULL) <<  8) |   \
66         (((__uint64_t)(__x) & (__uint64_t)0x000000ff00000000ULL) >>  8) |   \
67         (((__uint64_t)(__x) & (__uint64_t)0x0000ff0000000000ULL) >> 24) |   \
68         (((__uint64_t)(__x) & (__uint64_t)0x00ff000000000000ULL) >> 40) |   \
69         (((__uint64_t)(__x) & (__uint64_t)0xff00000000000000ULL) >> 56)))
70 #else
71 #define le64_to_cpu(__x) ((__uint64_t)(                         \
72         (((__uint64_t)(__x) & (__uint64_t)0x00000000000000ffULL) << 56) |   \
73         (((__uint64_t)(__x) & (__uint64_t)0x000000000000ff00ULL) << 40) |   \
74         (((__uint64_t)(__x) & (__uint64_t)0x0000000000ff0000ULL) << 24) |   \
75         (((__uint64_t)(__x) & (__uint64_t)0x00000000ff000000ULL) <<  8) |   \
76         (((__uint64_t)(__x) & (__uint64_t)0x000000ff00000000ULL) >>  8) |   \
77         (((__uint64_t)(__x) & (__uint64_t)0x0000ff0000000000ULL) >> 24) |   \
78         (((__uint64_t)(__x) & (__uint64_t)0x00ff000000000000ULL) >> 40) |   \
79         (((__uint64_t)(__x) & (__uint64_t)0xff00000000000000ULL) >> 56)))
80 #define le32_to_cpu(x)							\
81 	({								\
82 		uint32_t __x = (x);					\
83 		((uint32_t)(						\
84 			(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
85 			(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
86 			(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
87 			(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
88 	})
89 #define le16_to_cpu(x)							\
90 	({								\
91 		uint16_t __x = (x);					\
92 		((uint16_t)(						\
93 			(((uint16_t)(__x) & (uint16_t)0x00ff) <<  8) | \
94 			(((uint16_t)(__x) & (uint16_t)0xff00) >>  8))); \
95 	})
96 #define be64_to_cpu(__x) __x
97 #define be32_to_cpu(__x) __x
98 #define be16_to_cpu(__x) __x
99 #endif
100 
101 #define cpu_to_le16 le16_to_cpu
102 #define cpu_to_le32 le32_to_cpu
103 #define cpu_to_be16 be16_to_cpu
104 #define cpu_to_be32 be32_to_cpu
105 
106 /* To cheat the compiler */
107 #define UNUSED(expr) do { (void)(expr); } while (0)
108 
109 /* To enumerate supported devices */
110 enum {
111 	P_UNKNOWN = 0,
112 	P_CP_XXX = 1,
113 	P_CP10 = 2,
114 	P_CP790 = 3,
115 	P_CP900 = 4,
116 	P_CP910 = 5,
117 	P_ES1 = 6,
118 	P_ES2_20 = 7,
119 	P_ES3_30 = 8,
120 	P_ES40 = 9,
121 	P_KODAK_1400_805 = 10,
122 	P_KODAK_6800 = 11,
123 	P_KODAK_6850 = 12,
124 	P_KODAK_305 = 13,
125 	P_KODAK_605 = 14,
126 	P_SHINKO_S1245 = 15,
127 	P_SHINKO_S2145 = 16,
128 	P_SHINKO_S6145 = 17,
129 	P_SHINKO_S6145D = 18,
130 	P_SHINKO_S6245 = 19,
131 	P_SONY_UPCR10 = 20,
132 	P_SONY_UPDR150 = 21,
133 	P_MITSU_9550 = 22,
134 	P_MITSU_9550S = 23,
135 	P_MITSU_9600 = 24,
136 	P_MITSU_9800 = 25,
137 	P_MITSU_9800S = 26,
138 	P_MITSU_9810 = 27,
139 	P_MITSU_D70X = 28,
140 	P_MITSU_D80 = 29,
141 	P_MITSU_D90 = 30,
142 	P_MITSU_K60 = 31,
143 	P_MITSU_P93D = 32,
144 	P_MITSU_P95D = 33,
145 	P_CITIZEN_CW01 = 34,
146 	P_CITIZEN_OP900II = 35,
147 	P_DNP_DS40 = 36,
148 	P_DNP_DS620 = 37,
149 	P_DNP_DS80 = 38,
150 	P_DNP_DS80D = 39,
151 	P_DNP_DS820 = 40,
152 	P_DNP_DSRX1 = 41,
153 	P_FUJI_ASK300 = 42,
154 	P_MAGICARD = 43,
155 	P_SONY_UPD895 = 44,
156 	P_SONY_UPD897 = 45,
157 	P_SONY_UPD898 = 46,
158 	P_SONY_UPCR20L = 47,
159 	P_SONY_UPDR80 = 48,
160 	P_KODAK_8810 = 49,
161 	P_KODAK_7000 = 50,
162 	P_KODAK_701X = 51,
163 	P_KODAK_6900 = 52,
164 	P_SHINKO_S2245 = 53,
165 	P_END,
166 };
167 
168 struct device_id {
169 	uint16_t vid;
170 	uint16_t pid;
171 	int type;  /* P_** */
172 	char *manuf_str;
173 	char *prefix;
174 };
175 
176 struct marker {
177 	const char *color;  /* Eg "#00FFFF" */
178 	const char *name;   /* Eg "CK9015 (4x6)" */
179 	int levelmax; /* Max media count, eg '600', or '-1' */
180 	int levelnow; /* Remaining media, -3, -2, -1, 0..N.  See CUPS. */
181 };
182 
183 #define BACKEND_FLAG_JOBLIST 0x00000001
184 
185 /* Backend Functions */
186 struct dyesub_backend {
187 	const char *name;
188 	const char *version;
189 	const char **uri_prefixes;
190 	uint32_t flags;
191 	void (*cmdline_usage)(void);  /* Optional */
192 	void *(*init)(void);
193 	int  (*attach)(void *ctx, struct libusb_device_handle *dev, int type,
194 		       uint8_t endp_up, uint8_t endp_down, uint8_t jobid);
195 	void (*teardown)(void *ctx);
196 	int  (*cmdline_arg)(void *ctx, int argc, char **argv);
197 	int  (*read_parse)(void *ctx, const void **job, int data_fd, int copies);
198 	void (*cleanup_job)(const void *job);
199 	int  (*main_loop)(void *ctx, const void *job);
200 	int  (*query_serno)(struct libusb_device_handle *dev, uint8_t endp_up, uint8_t endp_down, char *buf, int buf_len); /* Optional */
201 	int  (*query_markers)(void *ctx, struct marker **markers, int *count);
202 	const struct device_id devices[];
203 };
204 
205 #define DYESUB_MAX_JOB_ENTRIES 2
206 
207 struct dyesub_joblist {
208 	// TODO: mutex/lock
209 	struct dyesub_backend *backend;
210 	void *ctx;
211 	int num_entries;
212 	int copies;
213 	const void *entries[DYESUB_MAX_JOB_ENTRIES];
214 };
215 
216 /* Exported functions */
217 int send_data(struct libusb_device_handle *dev, uint8_t endp,
218 	      const uint8_t *buf, int len);
219 int read_data(struct libusb_device_handle *dev, uint8_t endp,
220 	      uint8_t *buf, int buflen, int *readlen);
221 
222 void dump_markers(struct marker *markers, int marker_count, int full);
223 
224 void print_license_blurb(void);
225 void print_help(char *argv0, struct dyesub_backend *backend);
226 
227 int dyesub_read_file(char *filename, void *databuf, int datalen,
228 		     int *actual_len);
229 
230 uint16_t uint16_to_packed_bcd(uint16_t val);
231 uint32_t packed_bcd_to_uint32(char *in, int len);
232 
233 void generic_teardown(void *vctx);
234 
235 /* USB enumeration and attachment */
236 #define NUM_CLAIM_ATTEMPTS 10
237 int backend_claim_interface(struct libusb_device_handle *dev, int iface,
238 			    int num_claim_attempts);
239 
240 /* Job list manipulation */
241 struct dyesub_joblist *dyesub_joblist_create(struct dyesub_backend *backend, void *ctx);
242 int dyesub_joblist_addjob(struct dyesub_joblist *list, const void *job);
243 void dyesub_joblist_cleanup(const struct dyesub_joblist *list);
244 int dyesub_joblist_print(const struct dyesub_joblist *list);
245 
246 /* Global data */
247 extern int terminate;
248 extern int dyesub_debug;
249 extern int fast_return;
250 extern int extra_vid;
251 extern int extra_pid;
252 extern int extra_type;
253 extern int ncopies;
254 extern int collate;
255 extern int test_mode;
256 extern int quiet;
257 
258 enum {
259 	TEST_MODE_NONE = 0,
260 	TEST_MODE_NOPRINT,
261 	TEST_MODE_NOATTACH,
262 	TEST_MODE_MAX,
263 };
264 
265 #if defined(BACKEND)
266 extern struct dyesub_backend BACKEND;
267 #endif
268 
269 /* CUPS compatibility */
270 #define CUPS_BACKEND_OK            0 /* Success */
271 #define CUPS_BACKEND_FAILED        1 /* Failed to print use CUPS policy */
272 #define CUPS_BACKEND_AUTH_REQUIRED 2 /* Auth required */
273 #define CUPS_BACKEND_HOLD          3 /* Hold this job only */
274 #define CUPS_BACKEND_STOP          4 /* Stop the entire queue */
275 #define CUPS_BACKEND_CANCEL        5 /* Cancel print job */
276 #define CUPS_BACKEND_RETRY         6 /* Retry later */
277 #define CUPS_BACKEND_RETRY_CURRENT 7 /* Retry immediately */
278 
279 /* Argument processing */
280 #define GETOPT_LIST_GLOBAL "d:DfGhv"
281 #define GETOPT_PROCESS_GLOBAL \
282 			case 'd': \
283 				ncopies = atoi(optarg); \
284 				break; \
285 			case 'D': \
286 				dyesub_debug++; \
287 				break; \
288 			case 'f': \
289 				fast_return++; \
290 				break; \
291 			case 'G': \
292 				print_license_blurb(); \
293 				exit(0); \
294 			case 'h': \
295 				print_help(argv[0], &BACKEND); \
296 				exit(0); \
297 			case 'v': \
298 				quiet++; \
299 				break;
300 
301 #endif /* __BACKEND_COMMON_H */
302