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