int cyusb_interrupt_transfer(cyusb_handle *h, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout) { return ( libusb_interrupt_transfer(h, endpoint, data, length, transferred, timeout) ); }
static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in) { int r, size, descriptor_size; uint8_t hid_report_descriptor[256]; uint8_t *report_buffer; FILE *fd; printf("\nReading HID Report Descriptors:\n"); descriptor_size = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_STANDARD|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, LIBUSB_DT_REPORT<<8, 0, hid_report_descriptor, sizeof(hid_report_descriptor), 1000); if (descriptor_size < 0) { printf(" Failed\n"); return -1; } display_buffer_hex(hid_report_descriptor, descriptor_size); if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) { if (fwrite(hid_report_descriptor, 1, descriptor_size, fd) != descriptor_size) { printf(" Error writing descriptor to file\n"); } fclose(fd); } size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_FEATURE); if (size <= 0) { printf("\nSkipping Feature Report readout (None detected)\n"); } else { report_buffer = (uint8_t*) calloc(size, 1); if (report_buffer == NULL) { return -1; } printf("\nReading Feature Report (length %d)...\n", size); r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer, (uint16_t)size, 5000); if (r >= 0) { display_buffer_hex(report_buffer, size); } else { switch(r) { case LIBUSB_ERROR_NOT_FOUND: printf(" No Feature Report available for this device\n"); break; case LIBUSB_ERROR_PIPE: printf(" Detected stall - resetting pipe...\n"); libusb_clear_halt(handle, 0); break; default: printf(" Error: %s\n", libusb_error_name(r)); break; } } free(report_buffer); } size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT); if (size <= 0) { printf("\nSkipping Input Report readout (None detected)\n"); } else { report_buffer = (uint8_t*) calloc(size, 1); if (report_buffer == NULL) { return -1; } printf("\nReading Input Report (length %d)...\n", size); r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, report_buffer, (uint16_t)size, 5000); if (r >= 0) { display_buffer_hex(report_buffer, size); } else { switch(r) { case LIBUSB_ERROR_TIMEOUT: printf(" Timeout! Please make sure you act on the device within the 5 seconds allocated...\n"); break; case LIBUSB_ERROR_PIPE: printf(" Detected stall - resetting pipe...\n"); libusb_clear_halt(handle, 0); break; default: printf(" Error: %s\n", libusb_error_name(r)); break; } } // Attempt a bulk read from endpoint 0 (this should just return a raw input report) printf("\nTesting interrupt read using endpoint %02X...\n", endpoint_in); r = libusb_interrupt_transfer(handle, endpoint_in, report_buffer, size, &size, 5000); if (r >= 0) { display_buffer_hex(report_buffer, size); } else { printf(" %s\n", libusb_error_name(r)); } free(report_buffer); } return 0; }
static unsigned long LJUSB_DoTransfer(HANDLE hDevice, unsigned char endpoint, BYTE *pBuff, unsigned long count, unsigned int timeout, bool isBulk) { int r = 0; int transferred = 0; #if LJ_DEBUG fprintf(stderr, "Calling LJUSB_DoTransfer with endpoint = 0x%x, count = %lu, and isBulk = %d.\n", endpoint, count, isBulk); #endif if (LJUSB_isNullHandle(hDevice)) { #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: returning 0. hDevice is NULL.\n"); #endif return 0; } if (isBulk && endpoint != 1 && endpoint < 0x81 ) { fprintf(stderr, "LJUSB_DoTransfer warning: Got endpoint = %d, however this not a known endpoint. Please verify you are using the header file provided in /usr/local/include/labjackusb.h and not an older header file.\n", endpoint); } if (isBulk) { r = libusb_bulk_transfer(hDevice, endpoint, pBuff, (int)count, &transferred, timeout); } else { if (endpoint == 0) { //HID feature request. r = libusb_control_transfer(hDevice, 0xa1 , 0x01, 0x0300, 0x0000, pBuff, count, timeout); if (r < 0) { LJUSB_libusbError(r); return 0; } #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: returning control transferred = %d.\n", r); #endif return r; } else { r = libusb_interrupt_transfer(hDevice, endpoint, pBuff, count, &transferred, timeout); } } if (r == LIBUSB_ERROR_TIMEOUT) { //Timeout occured but may have received partial data. Setting errno but //returning the number of bytes transferred which may be > 0. #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: Transfer timed out. Returning.\n"); #endif errno = ETIMEDOUT; return transferred; } else if (r != 0) { LJUSB_libusbError(r); return 0; } #if LJ_DEBUG fprintf(stderr, "LJUSB_DoTransfer: returning transferred = %d.\n", transferred); #endif return transferred; }
int exchange_input_and_output_reports_via_interrupt_transfers(libusb_device_handle *devh) { // Assumes interrupt endpoint 2 IN and OUT: static const int INTERRUPT_IN_ENDPOINT = 0x81; static const int INTERRUPT_OUT_ENDPOINT = 0x01; // With firmware support, transfers can be > the endpoint's max packet size. static const int MAX_INTERRUPT_IN_TRANSFER_SIZE = 2; static const int MAX_INTERRUPT_OUT_TRANSFER_SIZE = 2; int bytes_transferred; int i = 0; int result = 0;; unsigned char data_in[MAX_INTERRUPT_IN_TRANSFER_SIZE]; unsigned char data_out[MAX_INTERRUPT_OUT_TRANSFER_SIZE]; // Store data in a buffer for sending. for (i=0;i < MAX_INTERRUPT_OUT_TRANSFER_SIZE; i++) { data_out[i]=0x40+i; } // // Write data to the device. // // result = libusb_interrupt_transfer( // devh, // INTERRUPT_OUT_ENDPOINT, // data_out, // MAX_INTERRUPT_OUT_TRANSFER_SIZE, // &bytes_transferred, // TIMEOUT_MS); // // if (result >= 0) // { // printf("Data sent via interrupt transfer:\n"); // for(i = 0; i < bytes_transferred; i++) // { // printf("%02x ",data_out[i]); // } // printf("\n"); // // Read data from the device. printf("Read data from the device\n\n"); result = libusb_interrupt_transfer( devh, INTERRUPT_IN_ENDPOINT, data_in, MAX_INTERRUPT_OUT_TRANSFER_SIZE, &bytes_transferred, TIMEOUT_MS); if (result >= 0) { if (bytes_transferred > 0) { printf("Data received via interrupt transfer:\n"); for(i = 0; i < bytes_transferred; i++) { printf("%02x ",data_in[i]); } printf("\n"); } else { fprintf(stderr, "No data received in interrupt transfer (%d)\n", result); return -1; } } else { fprintf(stderr, "Error receiving data via interrupt transfer %d\n", result); return result; } // } // else // { // fprintf(stderr, "Error sending data via interrupt transfer %d\n", result); // return result; // } return 0; }
static pwr_tStatus IoCardRead( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp) { io_sLocal_K8055 *local = (io_sLocal_K8055 *)cp->Local; pwr_sClass_Velleman_K8055_Board *op = (pwr_sClass_Velleman_K8055_Board *)cp->op; unsigned char data[9]; char endpoint = 0x81; int size = 8; int tsize; unsigned char m; int sts; int i; pwr_tUInt32 error_count = op->Super.ErrorCount; // You have to read twice to get the latest ????? sts = libusb_interrupt_transfer( local->libusb_device, endpoint, data, 8, &tsize, 100); sts = libusb_interrupt_transfer( local->libusb_device, endpoint, data, 8, &tsize, 100); if ( sts != 0 || tsize != size) { op->Super.ErrorCount++; if ( sts != 0 && sts != last_usblib_sts) { errh_Error( "K8055 libusb transfer error %d", sts); last_usblib_sts = sts; } return IO__SUCCESS; } else { // Handle Ai for ( i = 0; i < 2; i++) { if ( cp->chanlist[i].sop) { io_sChannel *chanp = &cp->chanlist[i]; pwr_sClass_ChanAi *cop = (pwr_sClass_ChanAi *)chanp->cop; pwr_sClass_Ai *sop = (pwr_sClass_Ai *)chanp->sop; pwr_tFloat32 actvalue; int ivalue = data[i+2]; if ( cop->CalculateNewCoef) // Request to calculate new coefficients io_AiRangeToCoef( chanp); io_ConvertAi( cop, ivalue, &actvalue); // Filter if ( sop->FilterType == 1 && sop->FilterAttribute[0] > 0 && sop->FilterAttribute[0] > ctx->ScanTime) { actvalue = *(pwr_tFloat32 *)chanp->vbp + ctx->ScanTime / sop->FilterAttribute[0] * (actvalue - *(pwr_tFloat32 *)chanp->vbp); } *(pwr_tFloat32 *)chanp->vbp = actvalue; sop->SigValue = cop->SigValPolyCoef1 * ivalue + cop->SigValPolyCoef0; sop->RawValue = ivalue; } } // Handle Di for ( i = 0; i < 5; i++) { switch ( i) { case 0: m = 16; break; case 1: m = 32; break; case 2: m = 1; break; case 3: m = 64; break; case 4: m = 128; break; } if ( cp->chanlist[i+2].sop) *(pwr_tBoolean *)cp->chanlist[i+2].vbp = ((data[0] & m) != 0); } } if ( op->Super.ErrorCount >= op->Super.ErrorSoftLimit && error_count < op->Super.ErrorSoftLimit) { errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name); } if ( op->Super.ErrorCount >= op->Super.ErrorHardLimit) { errh_Error( "IO Card ErrorHardLimit reached '%s', IO stopped", cp->Name); ctx->Node->EmergBreakTrue = 1; return IO__ERRDEVICE; } return IO__SUCCESS; }
static pwr_tStatus IoCardWrite( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp) { io_sLocal_K8055 *local = (io_sLocal_K8055 *)cp->Local; pwr_sClass_Velleman_K8055_Board *op = (pwr_sClass_Velleman_K8055_Board *)cp->op; unsigned char data[9]; char endpoint = 0x1; int size = 8; int tsize; unsigned char m; int i; int sts; pwr_tUInt32 error_count = op->Super.ErrorCount; memset( data, 0, sizeof(data)); data[0] = 0x5; // Handle Do m = 1; unsigned char do_value = 0; for ( i = 0; i < 8; i++) { if ( cp->chanlist[i+9].sop) { if ( *(pwr_tBoolean *)cp->chanlist[i+9].vbp) do_value |= m; } m = m << 1; } data[1] = do_value; // Handle Ao for ( i = 0; i < 2; i++) { if ( cp->chanlist[i+7].sop) { io_sChannel *chanp = &cp->chanlist[i+7]; pwr_sClass_ChanAo *cop = (pwr_sClass_ChanAo *)chanp->cop; if ( cop->CalculateNewCoef) // Request to calculate new coefficients io_AoRangeToCoef( chanp); float fvalue = *(pwr_tFloat32 *)chanp->vbp * cop->OutPolyCoef1 + cop->OutPolyCoef0; int ivalue = (int)fvalue; if ( ivalue < 0) ivalue = 0; else if (ivalue > 255) ivalue = 255; data[i+2] = ivalue; } } sts = libusb_interrupt_transfer( local->libusb_device, endpoint, data, size, &tsize, 100); if ( sts != 0 || tsize != size) { op->Super.ErrorCount++; if ( sts != 0 && sts != last_usblib_sts) { errh_Error( "K8055 libusb transfer error %d", sts); last_usblib_sts = sts; } return IO__SUCCESS; } if ( op->Super.ErrorCount >= op->Super.ErrorSoftLimit && error_count < op->Super.ErrorSoftLimit) { errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name); } if ( op->Super.ErrorCount >= op->Super.ErrorHardLimit) { errh_Error( "IO Card ErrorHardLimit reached '%s', IO stopped", cp->Name); ctx->Node->EmergBreakTrue = 1; return IO__ERRDEVICE; } return IO__SUCCESS; }
bool ReadBlock(libusb_device_handle *hPortalHandle, unsigned int block, unsigned char data[0x10], bool isNEWskylander) { RWBlock req, res; bool running = true; bool gotData; unsigned char ovlr[OVERLAP_SIZE]; unsigned short err; unsigned char followup; printf("ReadBlock\n"); if(block >= 0x40) { return false; } printf("."); for(int retries = 0; retries < 3; retries++) { // Send query request memset(req.buf, 0, rw_buf_size); req.buf[1] = 'Q'; if(isNEWskylander) { followup = 0x11; if(block == 0) { req.buf[2] = 0x21; } else { req.buf[2] = followup; } } else { followup = 0x10; if(block == 0) { req.buf[2] = 0x20; } else { req.buf[2] = followup; } } req.buf[3] = (unsigned char)block; memset(&(res.buf), 0, rw_buf_size); // Must set the Offset and OffsetHigh members of the OVERLAPPED structure to zero. // memset(&ovlr, 0, sizeof(ovlr)); // ovlr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // read event int i=0; gotData = false; Write(hPortalHandle, &req); // Don't wait. Start polling for result immediately for(; i<40; ++i) // try up to 40 reads { int b; // bool b = ReadFile(hPortalHandle, res.buf, rw_buf_size, &(res.dwBytesTransferred), &ovlr); b = libusb_interrupt_transfer (hPortalHandle, 0x81, res.buf, rw_buf_size, &(res.dwBytesTransferred), 30000); if (b>=0) fprinthex(stdout,res.buf,res.dwBytesTransferred); if(b<0) { printf("error reading from usb handle: %s\n",libusb_error(b)); /* failed to get data immediately*/ // err = GetLastError(); if(b == 0) { /* wait for data */ // b = GetOverlappedResult(hPortalHandle, &ovlr, &res.dwBytesTransferred, TRUE); if(!b) { /* wait failed */ break; } } else { /* some other error */ break; } } if(res.dwBytesTransferred > 0) { /* has data */ if(res.buf[1] == 'Q' && res.buf[3] == (unsigned char)block) { // Got our query back if(res.buf[2] == followup) { /* got the query back with no error */ gotData = true; break; } } res.buf[0] = 0; // make sure we are using report 0 } } /* read loop */ // CloseHandle(ovlr.hEvent); if(gotData) { break; } } // retries if(gotData) { memcpy(data, res.buf + 4, 0x10); } return gotData; }
int emokit_read_data(emokit_device* dev) { int trans; int ret = libusb_interrupt_transfer(dev->_device, EMOKIT_IN_ENDPT, dev->raw_frame, 32, &trans, 1000); return trans; }
/** Outgoing USB interrupt transfer. */ inline int JacoArm::_usb_out(usb_packet_t &p, int &transferred) { return libusb_interrupt_transfer(__devh, EP_OUT, p.data, INTR_LENGTH, &transferred, INTR_TIMEOUT); }
int main(int argc, char** argv) { int option; int port= 0; int hub_id = 1; int buf_len = 0; int err; enum action action = YKUSH_NONE; bool usb_init = false, dev_list = false, hub_open = false, claimed = false; while ((option = getopt(argc, argv, "lh:d:u:")) != -1) { switch (option) { case 'd': action = YKUSH_DOWN; if (!strcmp("a", optarg)) { port = YKUSH_ALL_PORTS; } else { port = atoi(optarg); } break; case 'u': action = YKUSH_UP; if (!strcmp("a", optarg)) { port = YKUSH_ALL_PORTS; } else { port = atoi(optarg); } break; case 'l': action = YKUSH_LIST; break; case 'h': hub_id = atoi(optarg); break; default: printf("Unknown option %c\n", option); print_usage(); err = EXIT_FAILURE; goto cleanup; } } if (!(action == YKUSH_DOWN || action == YKUSH_UP || action == YKUSH_LIST)) { print_usage(); err = EXIT_FAILURE; goto cleanup; } if (action != YKUSH_LIST && (port != YKUSH_ALL_PORTS && (port < 1 && port > YKUSH_PORTS))) { print_usage(); err = EXIT_FAILURE; goto cleanup; } err = libusb_init(&ctx); if (err < 0) { fprintf(stderr, "Failed to initialize USB: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } usb_init= true; libusb_device **list = NULL; ssize_t size = libusb_get_device_list(ctx, &list); if (size < 0) { fprintf(stderr, "Failed to enumerate devices: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } dev_list = true; libusb_device_handle *hub = NULL; int devices = 0; for (int i = 0; i < size; i++) { struct libusb_device_descriptor desc; err = libusb_get_device_descriptor(list[i], &desc); if (err < 0) { fprintf(stderr, "Failed to enumerate devices: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } if (desc.idVendor == YKUSH_USB_VENDOR_ID && (desc.idProduct == YKUSH_USB_PRODUCT_ID_1 || desc.idProduct == YKUSH_USB_PRODUCT_ID_2)) { devices++; if (action == YKUSH_LIST) { printf("%i: %04x:%04x\n", devices, desc.idVendor, desc.idProduct); } err = libusb_open(list[i], &hub); if (err < 0) { fprintf(stderr, "Unable to open device: %s\n", libusb_error_name(err)); } else { hub_open = true; unsigned char serial[64]; unsigned char product[64]; unsigned char manufacturer[64]; err = libusb_get_string_descriptor_ascii(hub, desc.iSerialNumber, serial, sizeof(serial)); if (err < 0) { fprintf(stderr, "Unable to query device: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } err = libusb_get_string_descriptor_ascii(hub, desc.iProduct, product, sizeof(product)); if (err < 0) { fprintf(stderr, "Unable to query device: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } err = libusb_get_string_descriptor_ascii(hub, desc.iManufacturer, manufacturer, sizeof(manufacturer)); if (err < 0) { fprintf(stderr, "Unable to query device: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } if (action == YKUSH_LIST) { printf(" %s / %s / %s\n", manufacturer, product, serial); } else if (devices == hub_id || (serial[0] == 'Y' && serial[1] == 'K' && atoi((const char*)&serial[2]) == hub_id)) { buf_len = (desc.idProduct == YKUSH_USB_PRODUCT_ID_1) ? 6 : 64; break; // hub remains open } libusb_close(hub); hub = NULL; hub_open = false; } } } if (action != YKUSH_LIST) { if (hub == NULL) { fprintf(stderr, "No hub with ID %i found.\n", hub_id); err = EXIT_FAILURE; goto cleanup; } err = libusb_detach_kernel_driver(hub, 0); if (err < 0 && err != LIBUSB_ERROR_NOT_FOUND) { fprintf(stderr, "Failed to detach kernel: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } err = libusb_set_configuration(hub, 1); if (err < 0) { fprintf(stderr, "Failed to set configuration: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } err = libusb_claim_interface(hub, 0); if (err < 0) { fprintf(stderr, "Failed to claim interface: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } claimed = true; unsigned char buf[64]; buf[0] = (action == YKUSH_UP ? 0x10 : 0x00) | port; buf[1] = buf[0]; /* Upstream does this. */ int transferred; err = libusb_interrupt_transfer(hub, YKUSH_ENDPOINT_INT_OUT, buf, buf_len, &transferred, TIMEOUT); if (err < 0) { fprintf(stderr, "Failed to send command: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } err = libusb_interrupt_transfer(hub, YKUSH_ENDPOINT_INT_IN, buf, buf_len, &transferred, TIMEOUT); if (err < 0) { fprintf(stderr, "Failed to receive response: %s\n", libusb_error_name(err)); err = EXIT_FAILURE; goto cleanup; } if (transferred < sizeof(buf)) { fprintf(stderr, "Short read from device.\n"); err = EXIT_FAILURE; goto cleanup; } } cleanup: if (claimed) { libusb_release_interface(hub, 0); } if (hub_open) { assert(hub != NULL); libusb_reset_device(hub); libusb_close(hub); } if (dev_list) { libusb_free_device_list(list, 1); } if (usb_init) { libusb_exit(ctx); } return err; }
/** * PicoLCD Write Interrupt Function * * Does an interrupt write to the OUT Endpoint on the LcdDevice. * @param lcdDevice Pointer to the LcdDevice structure * @param data Pointer to data to be sent to the LcdDevice * @param len Length of the data * @return returns the number of bytes transferred to the LcdDevice */ int lcd_write_interrupt(MyLcdDevice *lcdDevice,unsigned char *data,int len) { int transferred; libusb_interrupt_transfer(lcdDevice->lcdHandle, LIBUSB_ENDPOINT_OUT + 1, (char *) data, len, &transferred,1000); return transferred; }
/*----------------------------------------------------------------------*/ int main(int argc, char*argv[]) { int res = 0; /* return codes from libusb functions */ libusb_device_handle* handle = 0; /* handle for USB device */ int kernelDriverDetached = 0; /* Set to 1 if kernel driver detached */ int numBytes = 0; /* Actual bytes transferred. */ uint8_t buffer[64]; /* 64 byte transfer buffer */ int repeat = 0; /* Initialise libusb. */ res = libusb_init(0); if (res != 0) { fprintf(stderr, "Error initialising libusb.\n"); return 1; } /* Get the first device with the matching Vendor ID and Product ID. If * intending to allow multiple demo boards to be connected at once, you * will need to use libusb_get_device_list() instead. Refer to the libusb * documentation for details. */ handle = libusb_open_device_with_vid_pid(0, 0x04d8, 0x0070); if (!handle) { fprintf(stderr, "Unable to open device.\n"); return 1; } /* Check whether a kernel driver is attached to interface #0. If so, we'll * need to detach it. */ if (libusb_kernel_driver_active(handle, 0)) { res = libusb_detach_kernel_driver(handle, 0); if (res == 0) { kernelDriverDetached = 1; } else { fprintf(stderr, "Error detaching kernel driver.\n"); return 1; } } /* Claim interface #0. */ res = libusb_claim_interface(handle, 0); if (res != 0) { fprintf(stderr, "Error claiming interface.\n"); return 1; } printf("Disabling masks and filters\n"); /* Set to normal mode and read the speed setting */ memset(buffer, 0, 64); //buffer[58] = 0x00; /* Normal mode */ buffer[60] = 0x02; /* SPI write */ buffer[61] = 0x60; /* Register rxb0 cntrl */ buffer[62] = 0x60; res = libusb_interrupt_transfer(handle, 1, buffer, 64, &numBytes, 100); if (res == 0) { // printf("Setting CNF1\n"); } else { fprintf(stderr, "Error\n"); } /* Listen for a message. Note that for a normal application you'll need * to use asynchronous mode because we can't predict when messages will be * available. This involves setting up a callback function to handle incoming * messages - refer to libusb documentation. */ /* Wait up to 5 seconds for a message to arrive on endpoint 0x81. */ // res = libusb_interrupt_transfer(handle, 0x81, buffer, 64, &numBytes, 5000); //if (0 == res) //{ //if (numBytes == 64) // { // processMessage(buffer); //} // else // { // printf("Received %d bytes, expected 64.\n", numBytes); // } //} //else //{ // fprintf(stderr, "Error receiving message.\n"); //} /* Set to normal mode and read the speed setting */ memset(buffer, 0, 64); //buffer[58] = 0x00; /* Normal mode */ buffer[60] = 0x02; /* SPI write */ buffer[61] = 0x70; /* Register rxb1CNTRL */ buffer[62] = 0x60; res = libusb_interrupt_transfer(handle, 1, buffer, 64, &numBytes, 100); if (res == 0) { //printf("Setting CNF2\n"); } else { fprintf(stderr, "Error\n"); } /* Listen for a message. Note that for a normal application you'll need * to use asynchronous mode because we can't predict when messages will be * available. This involves setting up a callback function to handle incoming * messages - refer to libusb documentation. */ /* Wait up to 5 seconds for a message to arrive on endpoint 0x81. */ // res = libusb_interrupt_transfer(handle, 0x81, buffer, 64, &numBytes, 5000); //if (0 == res) //{ //if (numBytes == 64) // { // processMessage(buffer); //} // else // { // printf("Received %d bytes, expected 64.\n", numBytes); // } //} //else // { // fprintf(stderr, "Error receiving message.\n"); // } /* Release interface #0. */ res = libusb_release_interface(handle, 0); if (0 != res) { fprintf(stderr, "Error releasing interface.\n"); } /* If we detached a kernel driver from interface #0 earlier, we'll now * need to attach it again. */ if (kernelDriverDetached) { libusb_attach_kernel_driver(handle, 0); } /* Shutdown libusb. */ libusb_exit(0); return 0; }
void init() { static unsigned char init1[] = {0x80, 0x01, 0x00, 0x20, 0x14}; static unsigned char init2[] = {0x80, 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20}; int transferred = 0; libusb_interrupt_transfer(m_usbdevicehandle, outEP.bEndpointAddress, init1, sizeof(init1), &transferred, 1000); if (transferred!=sizeof(init1)) printf(__FILE__": Init string 1 failed\n"); libusb_interrupt_transfer(m_usbdevicehandle, outEP.bEndpointAddress, init2, sizeof(init2), &transferred, 1000); if (transferred!=sizeof(init2)) printf(__FILE__": Init string 2 failed\n"); transfer = libusb_alloc_transfer(0); if (transfer == 0) printf(__FILE__": libusb_alloc_transfer failed\n"); libusb_fill_interrupt_transfer(transfer, m_usbdevicehandle, inEP.bEndpointAddress | LIBUSB_ENDPOINT_IN, buffer, LIRI_KEYCODE_LENGTH, receive, 0, 0); if (libusb_submit_transfer(transfer) != 0) printf(__FILE__": Reading failed\n"); /* int maxfds = 0; struct epoll_event ev; const libusb_pollfd** fds =libusb_get_pollfds(0); int kdpfd = epoll_create(10); struct epoll_event * events = (struct epoll_event *)malloc(sizeof(struct epoll_event)*10); while (1) { maxfds = 1; for (int r = 0 ; fds[r] ; r++) { //printf("Watch: %u, events %i, %i\n", fds[r]->fd, fds[r]->events == POLLIN, fds[r]->events == POLLOUT); if (fds[r]->fd + 1 > maxfds) maxfds = fds[r]->fd+1; if (fds[r]->events == POLLIN) ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; else ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP; ev.data.fd = fds[r]->fd; const int res = epoll_ctl(kdpfd, EPOLL_CTL_ADD, fds[r]->fd, &ev); } printf("non blocking..\n"); int nfds = epoll_wait(kdpfd, events, 10, -1); printf("blocking..\n"); if (nfds<0) { printf("error21\n"); exit(1); } // if input on stdin break loop libusb_handle_events(context); } dd; free (fds);*/ }
int sendApduHid(libusb_device_handle *handle, const unsigned char ledger, const unsigned char *apdu, size_t apduLength, unsigned char *out, size_t outLength, int *sw) { unsigned char buffer[400]; unsigned char paddingBuffer[MAX_BLOCK]; int result; int length; int swOffset; int remaining = apduLength; int offset = 0; if (ledger) { result = wrapCommandAPDU(DEFAULT_LEDGER_CHANNEL, apdu, apduLength, LEDGER_HID_PACKET_SIZE, buffer, sizeof(buffer)); if (result < 0) { return result; } remaining = result; } else { memcpy(buffer, apdu, apduLength); remaining = apduLength; } while (remaining > 0) { int blockSize = (remaining > MAX_BLOCK ? MAX_BLOCK : remaining); memset(paddingBuffer, 0, MAX_BLOCK); memcpy(paddingBuffer, buffer + offset, blockSize); result = libusb_interrupt_transfer(handle, 0x02, paddingBuffer, blockSize, &length, TIMEOUT); if (result < 0) { return result; } offset += blockSize; remaining -= blockSize; } result = libusb_interrupt_transfer(handle, 0x82, buffer, MAX_BLOCK, &length, TIMEOUT); if (result < 0) { return result; } offset = MAX_BLOCK; if (!ledger) { if (buffer[0] == SW1_DATA) { int dummy; length = buffer[1]; length += 2; if (length > (MAX_BLOCK - 2)) { remaining = length - (MAX_BLOCK - 2); while (remaining != 0) { int blockSize; if (remaining > MAX_BLOCK) { blockSize = MAX_BLOCK; } else { blockSize = remaining; } result = libusb_interrupt_transfer(handle, 0x82, buffer + offset, MAX_BLOCK, &dummy, TIMEOUT); if (result < 0) { return result; } offset += blockSize; remaining -= blockSize; } } length -= 2; memcpy(out, buffer + 2, length); swOffset = 2 + length; } else { length = 0; swOffset = 0; } if (sw != NULL) { *sw = (buffer[swOffset] << 8) | buffer[swOffset + 1]; } } else { for (;;) { int dummy; result = unwrapReponseAPDU(DEFAULT_LEDGER_CHANNEL, buffer, offset, LEDGER_HID_PACKET_SIZE, out, outLength); if (result < 0) { return result; } if (result != 0) { length = result - 2; swOffset = result - 2; break; } result = libusb_interrupt_transfer(handle, 0x82, buffer + offset, MAX_BLOCK, &dummy, TIMEOUT); if (result < 0) { return result; } offset += MAX_BLOCK; } if (sw != NULL) { *sw = (out[swOffset] << 8) | out[swOffset + 1]; } } return length; }
// // main // ---- // int main(void) { libusb_device **devs; int r; // holds return codes ssize_t cnt; libusb_device* dev; libusb_device_handle* handle; int weigh_count = WEIGH_COUNT -1; // // We first try to init libusb. // r = libusb_init(NULL); // // If `libusb_init` errored, then we quit immediately. // if (r < 0) return r; #ifdef DEBUG libusb_set_debug(NULL, 3); #endif // // Next, we try to get a list of USB devices on this computer. cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) return (int) cnt; // // Once we have the list, we use **find_scale** to loop through and match // every device against the scales.h list. **find_scale** will return the // first device that matches, or 0 if none of them matched. // dev = find_scale(devs); if(dev == 0) { fprintf(stderr, "No USB scale found on this computer.\n"); return -1; } // // Once we have a pointer to the USB scale in question, we open it. // r = libusb_open(dev, &handle); // // Note that this requires that we have permission to access this device. // If you get the "permission denied" error, check your udev rules. // if(r < 0) { if(r == LIBUSB_ERROR_ACCESS) { fprintf(stderr, "Permission denied to scale.\n"); } else if(r == LIBUSB_ERROR_NO_DEVICE) { fprintf(stderr, "Scale has been disconnected.\n"); } return -1; } // // On Linux, we typically need to detach the kernel driver so that we can // handle this USB device. We are a userspace tool, after all. // #ifdef __linux__ libusb_detach_kernel_driver(handle, 0); #endif // // Finally, we can claim the interface to this device and begin I/O. // libusb_claim_interface(handle, 0); /* * Try to transfer data about status * * http://rowsandcolumns.blogspot.com/2011/02/read-from-magtek-card-swipe-reader-in.html */ unsigned char data[WEIGH_REPORT_SIZE]; int len; int scale_result = -1; // // For some reason, we get old data the first time, so let's just get that // out of the way now. It can't hurt to grab another packet from the scale. // r = libusb_interrupt_transfer( handle, //bmRequestType => direction: in, type: class, // recipient: interface LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, data, WEIGH_REPORT_SIZE, // length of data &len, 10000 //timeout => 10 sec ); // // We read data from the scale in an infinite loop, stopping when // **print_scale_data** tells us that it's successfully gotten the weight // from the scale, or if the scale or transmissions indicates an error. // for(;;) { // // A `libusb_interrupt_transfer` of 6 bytes from the scale is the // typical scale data packet, and the usage is laid out in *HID Point // of Sale Usage Tables*, version 1.02. // r = libusb_interrupt_transfer( handle, //bmRequestType => direction: in, type: class, // recipient: interface LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, data, WEIGH_REPORT_SIZE, // length of data &len, 10000 //timeout => 10 sec ); // // If the data transfer succeeded, then we pass along the data we // received tot **print_scale_data**. // if(r == 0) { #ifdef DEBUG int i; for(i = 0; i < WEIGH_REPORT_SIZE; i++) { printf("%x\n", data[i]); } #endif if (weigh_count < 1) { scale_result = print_scale_data(data); if(scale_result != 1) break; } weigh_count--; } else { fprintf(stderr, "Error in USB transfer\n"); scale_result = -1; break; } } // // At the end, we make sure that we reattach the kernel driver that we // detached earlier, close the handle to the device, free the device list // that we retrieved, and exit libusb. // #ifdef __linux__ libusb_attach_kernel_driver(handle, 0); #endif libusb_close(handle); libusb_free_device_list(devs, 1); libusb_exit(NULL); // // The return code will be 0 for success or -1 for errors (see // `libusb_init` above if it's neither 0 nor -1). // return scale_result; }
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { int bytes_read = -1; #if 0 int transferred; int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); LOG("transferred: %d\n", transferred); return transferred; #endif pthread_mutex_lock(&dev->mutex); pthread_cleanup_push(&cleanup_mutex, dev); /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ bytes_read = return_data(dev, data, length); goto ret; } if (dev->shutdown_thread) { /* This means the device has been disconnected. An error code of -1 should be returned. */ bytes_read = -1; goto ret; } if (milliseconds == -1) { /* Blocking */ while (!dev->input_reports && !dev->shutdown_thread) { pthread_cond_wait(&dev->condition, &dev->mutex); } if (dev->input_reports) { bytes_read = return_data(dev, data, length); } } else if (milliseconds > 0) { /* Non-blocking, but called with timeout. */ int res; struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += milliseconds / 1000; ts.tv_nsec += (milliseconds % 1000) * 1000000; if (ts.tv_nsec >= 1000000000L) { ts.tv_sec++; ts.tv_nsec -= 1000000000L; } while (!dev->input_reports && !dev->shutdown_thread) { res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts); if (res == 0) { if (dev->input_reports) { bytes_read = return_data(dev, data, length); break; } /* If we're here, there was a spurious wake up or the read thread was shutdown. Run the loop again (ie: don't break). */ } else if (res == ETIMEDOUT) { /* Timed out. */ bytes_read = 0; break; } else { /* Error. */ bytes_read = -1; break; } } } else { /* Purely non-blocking */ bytes_read = 0; } ret: pthread_mutex_unlock(&dev->mutex); pthread_cleanup_pop(0); return bytes_read; }
int epoc_read_data(epoc_device* dev, uint8_t* input_report) { int trans; int ret = libusb_interrupt_transfer(dev->_device, EPOC_IN_ENDPT, input_report, 32, &trans, 1000); return trans; }