| |
| |
| #include "TUSBScannerIO.h" |
| #include "tsystem.h" |
| #include <iostream> |
| #include <strstream> |
| |
| |
| |
| #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 |
| |
| TUSBScannerIOPD::TUSBScannerIOPD() |
| : m_epson(0), m_handle(0), m_epR(0), m_epW(0), m_trace(false) { |
| |
| 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) |
| |
| 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 } |
| |