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
}