|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "TUSBScannerIO.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include <iostream></iostream>
|
|
Shinya Kitaoka |
9eb50d |
#include <strstream></strstream>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#define HAS_LIBUSB
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Toshihiro Shimizu |
890ddd |
#include <usb.h></usb.h>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <errno.h></errno.h>
|
|
Toshihiro Shimizu |
890ddd |
using namespace std;
|
|
Shinya Kitaoka |
120a6e |
class TUSBScannerIOPD {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TUSBScannerIOPD();
|
|
Shinya Kitaoka |
120a6e |
struct usb_device *m_epson;
|
|
Shinya Kitaoka |
120a6e |
struct usb_dev_handle *m_handle;
|
|
Shinya Kitaoka |
120a6e |
int m_epR;
|
|
Shinya Kitaoka |
120a6e |
int m_epW;
|
|
Shinya Kitaoka |
120a6e |
bool m_trace;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static pthread_t T = 0;
|
|
Toshihiro Shimizu |
890ddd |
//#define TRACE cout << __PRETTY_FUNCTION__ << endl;
|
|
Toshihiro Shimizu |
890ddd |
#define TRACE
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TUSBScannerIOPD::TUSBScannerIOPD()
|
|
Shinya Kitaoka |
120a6e |
: m_epson(0), m_handle(0), m_epR(0), m_epW(0), m_trace(false) {
|
|
Shinya Kitaoka |
120a6e |
/*initialize libusb*/
|
|
Shinya Kitaoka |
120a6e |
TRACE
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (T == 0) T = pthread_self();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Shinya Kitaoka |
120a6e |
usb_set_debug(9);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
usb_init();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
usb_find_busses();
|
|
Shinya Kitaoka |
120a6e |
usb_find_devices();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
void buf2printable(const unsigned char *buffer, const int size,
|
|
Shinya Kitaoka |
120a6e |
ostrstream &os) {
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
if ((size == 2) && (buffer[0] == 0x1b)) {
|
|
Shinya Kitaoka |
120a6e |
os << "ESC ";
|
|
Shinya Kitaoka |
120a6e |
char c = buffer[1];
|
|
Shinya Kitaoka |
120a6e |
if (isprint(c)) os << c << " ";
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
os << std::hex;
|
|
Shinya Kitaoka |
120a6e |
for (; i < std::min(size, 0x40); ++i) {
|
|
Shinya Kitaoka |
120a6e |
char c = buffer[i];
|
|
Shinya Kitaoka |
120a6e |
os << "0x" << (unsigned int)c << " ";
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (i < size) os << "...";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUSBScannerIO::TUSBScannerIO() : m_data(new TUSBScannerIOPD()) { TRACE }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Shinya Kitaoka |
120a6e |
// looking for an Epson device
|
|
Shinya Kitaoka |
120a6e |
struct usb_device *doCheck(struct usb_device *dev, int level) {
|
|
Shinya Kitaoka |
120a6e |
if (!dev) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cout << "checking idVendor = " << std::hex << dev->descriptor.idVendor
|
|
Shinya Kitaoka |
120a6e |
<< endl;
|
|
Shinya Kitaoka |
120a6e |
if (dev->descriptor.idVendor == 0x04b8) return dev;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < dev->num_children; i++)
|
|
Shinya Kitaoka |
120a6e |
if (doCheck(dev->children[i], level + 1)) return dev->children[i];
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TUSBScannerIO::open() {
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Shinya Kitaoka |
120a6e |
for (struct usb_bus *bus = usb_busses; bus; bus = bus->next) {
|
|
Shinya Kitaoka |
120a6e |
if (bus->root_dev) {
|
|
Shinya Kitaoka |
120a6e |
m_data->m_epson = doCheck(bus->root_dev, 0);
|
|
Shinya Kitaoka |
120a6e |
if (m_data->m_epson) break;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
struct usb_device *dev;
|
|
Shinya Kitaoka |
120a6e |
for (dev = bus->devices; dev; dev = dev->next)
|
|
Shinya Kitaoka |
120a6e |
m_data->m_epson = doCheck(dev, 0);
|
|
Shinya Kitaoka |
120a6e |
if (m_data->m_epson) break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!m_data->m_epson) return false;
|
|
Shinya Kitaoka |
120a6e |
cout << "found" << endl;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_handle = usb_open(m_data->m_epson);
|
|
Shinya Kitaoka |
120a6e |
if (!m_data->m_handle) return false;
|
|
Shinya Kitaoka |
120a6e |
cout << "opened" << endl;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_epR = m_data->m_epson->config[0]
|
|
Shinya Kitaoka |
120a6e |
.interface[0]
|
|
Shinya Kitaoka |
120a6e |
.altsetting[0]
|
|
Shinya Kitaoka |
120a6e |
.endpoint[0]
|
|
Shinya Kitaoka |
120a6e |
.bEndpointAddress;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_epW = m_data->m_epson->config[0]
|
|
Shinya Kitaoka |
120a6e |
.interface[0]
|
|
Shinya Kitaoka |
120a6e |
.altsetting[0]
|
|
Shinya Kitaoka |
120a6e |
.endpoint[1]
|
|
Shinya Kitaoka |
120a6e |
.bEndpointAddress;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int rc;
|
|
Shinya Kitaoka |
120a6e |
rc = usb_set_configuration(m_data->m_handle,
|
|
Shinya Kitaoka |
120a6e |
m_data->m_epson->config[0].bConfigurationValue);
|
|
Shinya Kitaoka |
120a6e |
cout << "rc (config) = " << rc << endl;
|
|
Shinya Kitaoka |
120a6e |
int ifc = 0;
|
|
Shinya Kitaoka |
120a6e |
rc = usb_claim_interface(m_data->m_handle, ifc);
|
|
Shinya Kitaoka |
120a6e |
if ((rc == -EBUSY) || (rc == -ENOMEM)) return false;
|
|
Shinya Kitaoka |
120a6e |
cout << "rc (claim) = " << rc << endl;
|
|
Shinya Kitaoka |
120a6e |
cout << "gotit!" << endl;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TUSBScannerIO::close() {
|
|
Shinya Kitaoka |
120a6e |
TRACE
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Shinya Kitaoka |
120a6e |
if (m_data->m_handle) {
|
|
Shinya Kitaoka |
120a6e |
usb_release_interface(m_data->m_handle, 0);
|
|
Shinya Kitaoka |
120a6e |
usb_close(m_data->m_handle);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_data->m_handle = 0;
|
|
Shinya Kitaoka |
120a6e |
m_data->m_epson = 0;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TUSBScannerIO::receive(unsigned char *buffer, int size) {
|
|
Shinya Kitaoka |
120a6e |
TRACE
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int count;
|
|
Shinya Kitaoka |
120a6e |
count = usb_bulk_read(m_data->m_handle, m_data->m_epR, (char *)buffer, size,
|
|
Shinya Kitaoka |
120a6e |
30 * 1000);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_data->m_trace) {
|
|
Shinya Kitaoka |
120a6e |
ostrstream os;
|
|
Shinya Kitaoka |
120a6e |
os.freeze(false);
|
|
Shinya Kitaoka |
120a6e |
os << "receive: size=" << size << " got = " << count << " buf=";
|
|
Shinya Kitaoka |
120a6e |
buf2printable(buffer, count, os);
|
|
Shinya Kitaoka |
120a6e |
os << '\n' << '\0';
|
|
Shinya Kitaoka |
120a6e |
TSystem::outputDebug(os.str());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TUSBScannerIO::send(unsigned char *buffer, int size) {
|
|
Shinya Kitaoka |
120a6e |
TRACE
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(HAS_LIBUSB)
|
|
Shinya Kitaoka |
120a6e |
int count;
|
|
Shinya Kitaoka |
120a6e |
if (T != pthread_self()) {
|
|
Shinya Kitaoka |
120a6e |
cout << "called from another thead" << endl;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
count = usb_bulk_write(m_data->m_handle, m_data->m_epW, (char *)buffer, size,
|
|
Shinya Kitaoka |
120a6e |
30 * 1000);
|
|
Shinya Kitaoka |
120a6e |
if (m_data->m_trace) {
|
|
Shinya Kitaoka |
120a6e |
ostrstream os;
|
|
Shinya Kitaoka |
120a6e |
os.freeze(false);
|
|
Shinya Kitaoka |
120a6e |
os << "send: size=" << size << " wrote = " << count << " buf=";
|
|
Shinya Kitaoka |
120a6e |
buf2printable(buffer, size, os);
|
|
Shinya Kitaoka |
120a6e |
os << '\n' << '\0';
|
|
Shinya Kitaoka |
120a6e |
TSystem::outputDebug(os.str());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TUSBScannerIO::trace(bool on) {
|
|
Shinya Kitaoka |
120a6e |
TRACE
|
|
Shinya Kitaoka |
120a6e |
m_data->m_trace = on;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TUSBScannerIO::~TUSBScannerIO() { TRACE }
|