Blob Blame Raw


#include "TUSBScannerIO.h"
#include "tsystem.h"
#include <iostream>
#include <strstream>

//#define HAS_LIBUSB

#if defined(HAS_LIBUSB)
#include <USB.h>
#endif

#include <errno.h>
using namespace std;
class TUSBScannerIOPD
{
public:
	TUSBScannerIOPD();
	struct usb_device *m_epson;
	struct usb_dev_handle *m_handle;
	int m_epR;
	int m_epW;
	bool m_trace;
};

static pthread_t T = 0;
//#define TRACE cout << __PRETTY_FUNCTION__ << endl;
#define TRACE

TUSBScannerIOPD::TUSBScannerIOPD()
	: m_epson(0), m_handle(0), m_epR(0), m_epW(0), m_trace(false)
{
	/*initialize libusb*/
	TRACE

	if (T == 0)
		T = pthread_self();

#if defined(HAS_LIBUSB)
	usb_set_debug(9);

	usb_init();

	usb_find_busses();
	usb_find_devices();
#endif
}

namespace
{
void buf2printable(const unsigned char *buffer, const int size, ostrstream &os)
{
	int i = 0;
	if ((size == 2) && (buffer[0] == 0x1b)) {
		os << "ESC ";
		char c = buffer[1];
		if (isprint(c))
			os << c << " ";
		return;
	}
	os << std::hex;
	for (; i < std::min(size, 0x40); ++i) {
		char c = buffer[i];
		os << "0x" << (unsigned int)c << " ";
	}
	if (i < size)
		os << "...";
}
}
//-----------------------------------------------------------------------------

TUSBScannerIO::TUSBScannerIO()
	: m_data(new TUSBScannerIOPD())
{
	TRACE
}

//-----------------------------------------------------------------------------
namespace
{

#if defined(HAS_LIBUSB)
//looking for an Epson device
struct usb_device *doCheck(struct usb_device *dev, int level)
{
	if (!dev)
		return 0;

	cout << "checking idVendor = " << std::hex << dev->descriptor.idVendor << endl;
	if (dev->descriptor.idVendor == 0x04b8)
		return dev;
	for (int i = 0; i < dev->num_children; i++)
		if (doCheck(dev->children[i], level + 1))
			return dev->children[i];
	return 0;
}

#endif
};

bool TUSBScannerIO::open()
{
#if defined(HAS_LIBUSB)
	for (struct usb_bus *bus = usb_busses; bus; bus = bus->next) {
		if (bus->root_dev) {
			m_data->m_epson = doCheck(bus->root_dev, 0);
			if (m_data->m_epson)
				break;
		} else {
			struct usb_device *dev;
			for (dev = bus->devices; dev; dev = dev->next)
				m_data->m_epson = doCheck(dev, 0);
			if (m_data->m_epson)
				break;
		}
	}
	if (!m_data->m_epson)
		return false;
	cout << "found" << endl;
	m_data->m_handle = usb_open(m_data->m_epson);
	if (!m_data->m_handle)
		return false;
	cout << "opened" << endl;
	m_data->m_epR = m_data->m_epson->config[0].interface[0].altsetting[0].endpoint[0].bEndpointAddress;
	m_data->m_epW = m_data->m_epson->config[0].interface[0].altsetting[0].endpoint[1].bEndpointAddress;

	int rc;
	rc = usb_set_configuration(m_data->m_handle, m_data->m_epson->config[0].bConfigurationValue);
	cout << "rc (config) = " << rc << endl;
	int ifc = 0;
	rc = usb_claim_interface(m_data->m_handle, ifc);
	if ((rc == -EBUSY) || (rc == -ENOMEM))
		return false;
	cout << "rc (claim) = " << rc << endl;
	cout << "gotit!" << endl;
	return true;
#else
	return false;
#endif
}

//-----------------------------------------------------------------------------

void TUSBScannerIO::close()
{
	TRACE
#if defined(HAS_LIBUSB)
	if (m_data->m_handle) {
		usb_release_interface(m_data->m_handle, 0);
		usb_close(m_data->m_handle);
	}
	m_data->m_handle = 0;
	m_data->m_epson = 0;
#endif
}

//-----------------------------------------------------------------------------

int TUSBScannerIO::receive(unsigned char *buffer, int size)
{
	TRACE

#if defined(HAS_LIBUSB)

	int count;
	count = usb_bulk_read(m_data->m_handle, m_data->m_epR, (char *)buffer, size, 30 * 1000);

	if (m_data->m_trace) {
		ostrstream os;
		os.freeze(false);
		os << "receive: size=" << size << " got = " << count << " buf=";
		buf2printable(buffer, count, os);
		os << '\n' << '\0';
		TSystem::outputDebug(os.str());
	}
	return count;

#else
	return 0;
#endif
}

//-----------------------------------------------------------------------------

int TUSBScannerIO::send(unsigned char *buffer, int size)
{
	TRACE

#if defined(HAS_LIBUSB)
	int count;
	if (T != pthread_self()) {
		cout << "called from another thead" << endl;
		return 0;
	}

	count = usb_bulk_write(m_data->m_handle, m_data->m_epW, (char *)buffer, size, 30 * 1000);
	if (m_data->m_trace) {
		ostrstream os;
		os.freeze(false);
		os << "send: size=" << size << " wrote = " << count << " buf=";
		buf2printable(buffer, size, os);
		os << '\n' << '\0';
		TSystem::outputDebug(os.str());
	}
	return count;
#else
	return 0;
#endif
}

//-----------------------------------------------------------------------------

void TUSBScannerIO::trace(bool on)
{
	TRACE
	m_data->m_trace = on;
}

//-----------------------------------------------------------------------------

TUSBScannerIO::~TUSBScannerIO()
{
	TRACE
}