#include "TUSBScannerIO.h" #include "tsystem.h" #include #include //#define HAS_LIBUSB #if defined(HAS_LIBUSB) #include #endif #include 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 }