2013-06-27 23:02:34 -04:00
|
|
|
/*
|
|
|
|
* CUPS Backend common code
|
|
|
|
*
|
|
|
|
* (c) 2013 Solomon Peachy <pizza@shaftnet.org>
|
|
|
|
*
|
|
|
|
* 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 <libusb-1.0/libusb.h>
|
|
|
|
|
|
|
|
#define STR_LEN_MAX 64
|
|
|
|
#define DEBUG( ... ) fprintf(stderr, "DEBUG: " __VA_ARGS__ )
|
2013-06-28 07:50:24 -04:00
|
|
|
#define DEBUG2( ... ) fprintf(stderr, __VA_ARGS__ )
|
2013-06-27 23:02:34 -04:00
|
|
|
#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");
|
|
|
|
}
|