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