/* * CUPS Backend common code * * (c) 2013 Solomon Peachy * * The latest version of this program can be found at: * * http://git.shaftnet.org/git/gitweb.cgi?p=selphy_print.git * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * [http://www.gnu.org/licenses/gpl-3.0.html] * */ #include #define STR_LEN_MAX 64 #define DEBUG( ... ) fprintf(stderr, "DEBUG: " __VA_ARGS__ ) #define DEBUG2( ... ) fprintf(stderr, __VA_ARGS__ ) #define INFO( ... ) fprintf(stderr, "INFO: " __VA_ARGS__ ) #define ERROR( ... ) do { fprintf(stderr, "ERROR: " __VA_ARGS__ ); sleep(1); } while (0) #if (__BYTE_ORDER == __LITTLE_ENDIAN) #define le32_to_cpu(__x) __x #define le16_to_cpu(__x) __x #define be16_to_cpu(__x) ntohs(__x) #define be32_to_cpu(__x) ntohl(__x) #else #define le32_to_cpu(x) \ ({ \ uint32_t __x = (x); \ ((uint32_t)( \ (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \ (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \ (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \ (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \ }) #define le16_to_cpu(x) \ ({ \ uint16_t __x = (x); \ ((uint16_t)( \ (((uint16_t)(__x) & (uint16_t)0x00ff) << 8) | \ (((uint16_t)(__x) & (uint16_t)0xff00) >> 8) | \ }) #define be32_to_cpu(__x) __x #define be16_to_cpu(__x) __x #endif #define ID_BUF_SIZE 2048 static char *get_device_id(struct libusb_device_handle *dev) { int length; int claimed = 0; int iface = 0; char *buf = malloc(ID_BUF_SIZE + 1); claimed = libusb_kernel_driver_active(dev, iface); if (claimed) libusb_detach_kernel_driver(dev, iface); libusb_claim_interface(dev, iface); if (libusb_control_transfer(dev, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE, 0, 0, (iface << 8), (unsigned char *)buf, ID_BUF_SIZE, 5000) < 0) { *buf = '\0'; goto done; } /* length is the first two bytes, MSB first */ length = (((unsigned)buf[0] & 255) << 8) | ((unsigned)buf[1] & 255); /* Sanity checks */ if (length > ID_BUF_SIZE || length < 14) length = (((unsigned)buf[1] & 255) << 8) | ((unsigned)buf[0] & 255); if (length > ID_BUF_SIZE) length = ID_BUF_SIZE; if (length < 14) { *buf = '\0'; goto done; } /* Move, and terminate */ memmove(buf, buf + 2, length); buf[length] = '\0'; done: libusb_release_interface(dev, iface); if (claimed) libusb_attach_kernel_driver(dev, iface); return buf; } static int send_data(struct libusb_device_handle *dev, uint8_t endp, uint8_t *buf, uint16_t len) { int num; int ret = libusb_bulk_transfer(dev, endp, buf, len, &num, 10000); if (ret < 0) { ERROR("Failure to send data to printer (libusb error %d: (%d/%d to 0x%02x))\n", ret, num, len, endp); return ret; } return 0; } static int terminate = 0; void sigterm_handler(int signum) { terminate = 1; INFO("Job Cancelled"); }