//-- private morpheus commands --- static bool morpheus_open_usb_device( MorpheusUSBContext *morpheus_context) { bool bSuccess = true; if (libusb_init(&morpheus_context->usb_context) == LIBUSB_SUCCESS) { libusb_set_debug(morpheus_context->usb_context, 3); } else { SERVER_LOG_ERROR("morpeus_open_usb_device") << "libusb context initialization failed!"; bSuccess = false; } if (bSuccess) { morpheus_context->usb_device_handle = libusb_open_device_with_vid_pid( morpheus_context->usb_context, MORPHEUS_VENDOR_ID, MORPHEUS_PRODUCT_ID); if (morpheus_context->usb_device_handle == nullptr) { SERVER_LOG_ERROR("morpeus_open_usb_device") << "Morpheus USB device not found!"; bSuccess = false; } } if (bSuccess) { libusb_device *device = libusb_get_device(morpheus_context->usb_device_handle); int result = libusb_get_config_descriptor_by_value( device, MORPHEUS_CONFIGURATION_PSVR, &morpheus_context->usb_device_descriptor); if (result != LIBUSB_SUCCESS) { SERVER_LOG_ERROR("morpeus_open_usb_device") << "Failed to retrieve Morpheus usb config descriptor"; bSuccess = false; } } for (int interface_index = 0; bSuccess && interface_index < morpheus_context->usb_device_descriptor->bNumInterfaces; interface_index++) { int mask = 1 << interface_index; if (MORPHEUS_USB_INTERFACES_MASK_TO_CLAIM & mask) { int result = 0; #ifndef _WIN32 result = libusb_kernel_driver_active(morpheus_context->usb_device_handle, interface_index); if (result < 0) { SERVER_LOG_ERROR("morpeus_open_usb_device") << "USB Interface #"<< interface_index <<" driver status failed"; bSuccess = false; } if (bSuccess && result == 1) { SERVER_LOG_ERROR("morpeus_open_usb_device") << "Detach kernel driver on interface #" << interface_index; result = libusb_detach_kernel_driver(morpheus_context->usb_device_handle, interface_index); if (result != LIBUSB_SUCCESS) { SERVER_LOG_ERROR("morpeus_open_usb_device") << "Interface #" << interface_index << " detach failed"; bSuccess = false; } } #endif //_WIN32 result = libusb_claim_interface(morpheus_context->usb_device_handle, interface_index); if (result == LIBUSB_SUCCESS) { morpheus_context->usb_claimed_interface_mask |= mask; } else { SERVER_LOG_ERROR("morpeus_open_usb_device") << "Interface #" << interface_index << " claim failed"; bSuccess = false; } } } if (!bSuccess) { morpheus_close_usb_device(morpheus_context); } return bSuccess; }
int test_init(struct test_state *state) { int i, ret; ssize_t cnt; libusb_device **list; state->found = NULL; state->ctx = NULL; state->handle = NULL; state->attached = 0; ret = libusb_init(&state->ctx); if (ret) { printf("cannot init libusb: %s\n", libusb_error_name(ret)); return 1; } cnt = libusb_get_device_list(state->ctx, &list); if (cnt <= 0) { printf("no devices found\n"); goto error1; } for (i = 0; i < cnt; ++i) { libusb_device *dev = list[i]; struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(dev, &desc); if (ret) { printf("unable to get device descriptor: %s\n", libusb_error_name(ret)); goto error2; } if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) { state->found = dev; break; } } if (!state->found) { printf("no devices found\n"); goto error2; } ret = libusb_open(state->found, &state->handle); if (ret) { printf("cannot open device: %s\n", libusb_error_name(ret)); goto error2; } if (libusb_claim_interface(state->handle, 0)) { ret = libusb_detach_kernel_driver(state->handle, 0); if (ret) { printf("unable to detach kernel driver: %s\n", libusb_error_name(ret)); goto error3; } state->attached = 1; ret = libusb_claim_interface(state->handle, 0); if (ret) { printf("cannot claim interface: %s\n", libusb_error_name(ret)); goto error4; } } return 0; error4: if (state->attached == 1) libusb_attach_kernel_driver(state->handle, 0); error3: libusb_close(state->handle); error2: libusb_free_device_list(list, 1); error1: libusb_exit(state->ctx); return 1; }
int setup_usb(void){ int status; //Holds status value for functions ssize_t dev_cnt; //Holds number of devices found //////////////////-Create libusb session status = libusb_init(&ctx); //Create a libusb session if(status < 0){ cout<<"Cannot create libusb session. Error: "<<status<<endl; exit(-2); } libusb_set_debug(ctx,3); //Set verbosity to lvl 3 ////////////////// //////////////////-Available USB devices dev_cnt = libusb_get_device_list(ctx, &dev); //Get list of USB devices #ifdef USB_DEBUG if(dev_cnt < 0 ){ cout<<"No USB devices found"<<endl; } ssize_t i; //Search through device list for(i = 0; i < dev_cnt; i++){ status = libusb_get_device_descriptor(dev[i], &desc); if(status < 0){ cout<<"Failed to get device descriptor"<<endl; exit(-2); } if(desc.idVendor == SCROD_USB_VID && desc.idProduct == SCROD_USB_PID){ cout<<"Found SCROD USB Device"<<endl; printdev(dev[i]); list_endpoints(dev[i]); break; } } if(i == dev_cnt){ cout<<"Could not find SCROD USB Device"<<endl; exit(-2); } #endif ////////////////// //////////////////-Open USB device dev_handle = libusb_open_device_with_vid_pid(ctx,SCROD_USB_VID,SCROD_USB_PID); //Open SCROD USB Device if(dev_handle == NULL){ cout<<"Could not open SCROD USB Device"<<endl; exit(-2); } else{ cout<<"SCROD USB Device Opened"<<endl; } libusb_free_device_list(dev,1); //Unreferencing devices in device list as suggested in documentation ////////////////// //////////////////-Check kernel status status = libusb_kernel_driver_active(dev_handle,0); if(status == 1){ cout<<"Kernel driver active"<<endl; cout<<"Trying to detach driver..."<<endl; status = libusb_detach_kernel_driver(dev_handle,0); if(status == 0){ cout<<"Kernel driver detached"<<endl; } else{ cout<<"Kernel driver cannot be detached"<<endl; exit(-3); } } ////////////////// //////////////////-Claim an interface status = libusb_claim_interface(dev_handle,0); if(status < 0){ cout<<"Could not claim an interface"<<endl; exit(-3); } else{ cout<<"Interface claimed"<<endl; } ////////////////// }
/** * Wraps a CDB mass storage command in the appropriate gunk to get it down * @param handle * @param endpoint * @param cdb * @param cdb_length * @param lun * @param flags * @param expected_rx_size * @return */ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, uint8_t *cdb, uint8_t cdb_length, uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); dump_CDB_command(cdb, cdb_length); static uint32_t tag; if (tag == 0) { tag = 1; } int try = 0; int ret = 0; int real_transferred; int i = 0; uint8_t c_buf[STLINK_SG_SIZE]; // tag is allegedly ignored... TODO - verify c_buf[i++] = 'U'; c_buf[i++] = 'S'; c_buf[i++] = 'B'; c_buf[i++] = 'C'; write_uint32(&c_buf[i], tag); uint32_t this_tag = tag++; write_uint32(&c_buf[i+4], expected_rx_size); i+= 8; c_buf[i++] = flags; c_buf[i++] = lun; c_buf[i++] = cdb_length; // Now the actual CDB request assert(cdb_length <= CDB_SL); memcpy(&(c_buf[i]), cdb, cdb_length); int sending_length = STLINK_SG_SIZE; // send.... do { ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length, &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); if (ret != LIBUSB_SUCCESS) { WLOG("sending failed: %d\n", ret); return -1; } return this_tag; } /** * Straight from stm8 stlink code... * @param handle * @param endpoint_in * @param endpoint_out */ static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { DLOG("Fetching sense...\n"); uint8_t cdb[16]; memset(cdb, 0, sizeof(cdb)); #define REQUEST_SENSE 0x03 #define REQUEST_SENSE_LENGTH 18 cdb[0] = REQUEST_SENSE; cdb[4] = REQUEST_SENSE_LENGTH; uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0, LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); if (tag == 0) { WLOG("refusing to send request sense with tag 0\n"); return; } unsigned char sense[REQUEST_SENSE_LENGTH]; int transferred; int ret; int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense), &transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_in); } try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); if (ret != LIBUSB_SUCCESS) { WLOG("receiving sense failed: %d\n", ret); return; } if (transferred != sizeof(sense)) { WLOG("received unexpected amount of sense: %d != %d\n", transferred, sizeof(sense)); } uint32_t received_tag; int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); if (status != 0) { WLOG("receiving sense failed with status: %02x\n", status); return; } if (sense[0] != 0x70 && sense[0] != 0x71) { WLOG("No sense data\n"); } else { WLOG("Sense KCQ: %02X %02X %02X\n", sense[2] & 0x0f, sense[12], sense[13]); } } /** * Just send a buffer on an endpoint, no questions asked. * Handles repeats, and time outs. Also handles reading status reports and sense * @param handle libusb device * * @param endpoint_out sends * @param endpoint_in used to read status reports back in * @param cbuf what to send * @param length how much to send * @return number of bytes actually sent, or -1 for failures. */ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { int ret; int real_transferred; int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); if (ret != LIBUSB_SUCCESS) { WLOG("sending failed: %d\n", ret); return -1; } // now, swallow up the status, so that things behave nicely... uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag); if (status < 0) { WLOG("receiving status failed: %d\n", status); return -1; } if (status != 0) { WLOG("receiving status not passed :(: %02x\n", status); } if (status == 1) { get_sense(handle, endpoint_in, endpoint_out); return -1; } return real_transferred; } int stlink_q(stlink_t *sl) { struct stlink_libsg* sg = sl->backend_data; //uint8_t cdb_len = 6; // FIXME varies!!! uint8_t cdb_len = 10; // FIXME varies!!! uint8_t lun = 0; // always zero... uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); // now wait for our response... // length copied from stlink-usb... int rx_length = sl->q_len; int try = 0; int real_transferred; int ret; if (rx_length > 0) { do { ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(sg->usb_handle, sg->ep_req); } try++; } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3)); if (ret != LIBUSB_SUCCESS) { WLOG("Receiving failed: %d\n", ret); return -1; } if (real_transferred != rx_length) { WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length); } } uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag); if (status < 0) { WLOG("receiving status failed: %d\n", status); return -1; } if (status != 0) { WLOG("receiving status not passed :(: %02x\n", status); } if (status == 1) { get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req); return -1; } if (received_tag != tag) { WLOG("received tag %d but expected %d\n", received_tag, tag); //return -1; } if (rx_length > 0 && real_transferred != rx_length) { return -1; } return 0; } // TODO thinking, cleanup void stlink_stat(stlink_t *stl, char *txt) { if (stl->q_len <= 0) return; stlink_print_data(stl); switch (stl->q_buf[0]) { case STLINK_OK: DLOG(" %s: ok\n", txt); return; case STLINK_FALSE: DLOG(" %s: false\n", txt); return; default: DLOG(" %s: unknown\n", txt); } } void _stlink_sg_version(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_VERSION; stl->q_len = 6; sl->q_addr = 0; stlink_q(stl); } // Get stlink mode: // STLINK_DEV_DFU_MODE || STLINK_DEV_MASS_MODE || STLINK_DEV_DEBUG_MODE // usb dfu || usb mass || jtag or swd int _stlink_sg_current_mode(stlink_t *stl) { struct stlink_libsg *sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE; stl->q_len = 2; sl->q_addr = 0; stlink_q(stl); return stl->q_buf[0]; } // Exit the mass mode and enter the swd debug mode. void _stlink_sg_enter_swd_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD; sl->q_len = 0; // >0 -> aboard stlink_q(sl); } // Exit the mass mode and enter the jtag debug mode. // (jtag is disabled in the discovery's stlink firmware) void _stlink_sg_enter_jtag_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_enter_jtag_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER; sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG; sl->q_len = 0; stlink_q(sl); } // XXX kernel driver performs reset, the device temporally disappears // Suspect this is no longer the case when we have ignore on? RECHECK void _stlink_sg_exit_dfu_mode(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_exit_dfu_mode ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND; sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT; sl->q_len = 0; // ?? stlink_q(sl); /* [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00 [135121.844584] end_request: I/O error, dev sdb, sector 4096 [135121.844590] Buffer I/O error on device sdb, logical block 512 [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7 [135130.274551] usb 6-1: device firmware changed [135130.274618] usb 6-1: USB disconnect, address 7 [135130.275186] VFS: busy inodes on changed media or resized disk sdb [135130.275424] VFS: busy inodes on changed media or resized disk sdb [135130.286758] VFS: busy inodes on changed media or resized disk sdb [135130.292796] VFS: busy inodes on changed media or resized disk sdb [135130.301481] VFS: busy inodes on changed media or resized disk sdb [135130.304316] VFS: busy inodes on changed media or resized disk sdb [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8 [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1 [135130.629492] scsi20 : usb-storage 6-1:1.0 [135131.625600] scsi 20:0:0:0: Direct-Access STM32 PQ: 0 ANSI: 0 [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0 [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB) [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through [135131.640609] sdb: [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 [135131.671570] end_request: I/O error, dev sdb, sector 63872 [135131.671575] Buffer I/O error on device sdb, logical block 7984 [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 [135131.678551] end_request: I/O error, dev sdb, sector 63872 ... [135131.853565] end_request: I/O error, dev sdb, sector 4096 */ } void _stlink_sg_core_id(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READCOREID; sl->q_len = 4; sg->q_addr = 0; stlink_q(sl); sl->core_id = read_uint32(sl->q_buf, 0); } // Arm-core reset -> halted state. void _stlink_sg_reset(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS; sl->q_len = 2; sg->q_addr = 0; stlink_q(sl); stlink_stat(sl, "core reset"); } // Arm-core reset -> halted state. void _stlink_sg_jtag_reset(stlink_t *sl, int value) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST; sg->cdb_cmd_blk[2] = (value)?0:1; sl->q_len = 3; sg->q_addr = 2; stlink_q(sl); stlink_stat(sl, "core reset"); } // Arm-core status: halted or running. void _stlink_sg_status(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS; sl->q_len = 2; sg->q_addr = 0; stlink_q(sl); } // Force the core into the debug mode -> halted state. void _stlink_sg_force_debug(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG; sl->q_len = 2; sg->q_addr = 0; stlink_q(sl); stlink_stat(sl, "force debug"); } // Read all arm-core registers. void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS; sl->q_len = 84; sg->q_addr = 0; stlink_q(sl); stlink_print_data(sl); // TODO - most of this should be re-extracted up.... // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 for (int i = 0; i < 16; i++) { regp->r[i] = read_uint32(sl->q_buf, 4 * i); if (sl->verbose > 1) DLOG("r%2d = 0x%08x\n", i, regp->r[i]); } regp->xpsr = read_uint32(sl->q_buf, 64); regp->main_sp = read_uint32(sl->q_buf, 68); regp->process_sp = read_uint32(sl->q_buf, 72); regp->rw = read_uint32(sl->q_buf, 76); regp->rw2 = read_uint32(sl->q_buf, 80); if (sl->verbose < 2) return; DLOG("xpsr = 0x%08x\n", regp->xpsr); DLOG("main_sp = 0x%08x\n", regp->main_sp); DLOG("process_sp = 0x%08x\n", regp->process_sp); DLOG("rw = 0x%08x\n", regp->rw); DLOG("rw2 = 0x%08x\n", regp->rw2); } // Read an arm-core register, the index must be in the range 0..20. // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG; sg->cdb_cmd_blk[2] = r_idx; sl->q_len = 4; sg->q_addr = 0; stlink_q(sl); // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 stlink_print_data(sl); uint32_t r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { case 16: regp->xpsr = r; break; case 17: regp->main_sp = r; break; case 18: regp->process_sp = r; break; case 19: regp->rw = r; //XXX ?(primask, basemask etc.) break; case 20: regp->rw2 = r; //XXX ?(primask, basemask etc.) break; default: regp->r[r_idx] = r; } } // Write an arm-core register. Index: // 0 | 1 | ... | 15 | 16 | 17 | 18 | 19 | 20 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG; // 2: reg index // 3-6: reg content sg->cdb_cmd_blk[2] = idx; write_uint32(sg->cdb_cmd_blk + 3, reg); sl->q_len = 2; sg->q_addr = 0; stlink_q(sl); stlink_stat(sl, "write reg"); } // Write a register of the debug module of the core. // XXX ?(atomic writes) // TODO test void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_write_dreg ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG; // 2-5: address of reg of the debug module // 6-9: reg content write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, reg); sl->q_len = 2; sg->q_addr = addr; stlink_q(sl); stlink_stat(sl, "write debug reg"); } // Force the core exit the debug mode. void _stlink_sg_run(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; sg->q_addr = 0; stlink_q(sl); stlink_stat(sl, "run core"); } // Step the arm-core. void _stlink_sg_step(stlink_t *sl) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE; sl->q_len = 2; sg->q_addr = 0; stlink_q(sl); stlink_stat(sl, "step core"); } // TODO test // see Cortex-M3 Technical Reference Manual // TODO make delegate! void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) { DLOG("\n*** stlink_set_hw_bp ***\n"); struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP; // 2:The number of the flash patch used to set the breakpoint // 3-6: Address of the breakpoint (LSB) // 7: FP_ALL (0x02) / FP_UPPER (0x01) / FP_LOWER (0x00) sl->q_buf[2] = fp_nr; write_uint32(sl->q_buf, addr); sl->q_buf[7] = fp; sl->q_len = 2; stlink_q(sl); stlink_stat(sl, "set flash breakpoint"); } // TODO test // TODO make delegate! void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) { struct stlink_libsg *sg = sl->backend_data; DLOG("\n*** stlink_clr_hw_bp ***\n"); clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP; sg->cdb_cmd_blk[2] = fp_nr; sl->q_len = 2; stlink_q(sl); stlink_stat(sl, "clear flash breakpoint"); } // Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes) void _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_READMEM_32BIT; // 2-5: addr // 6-7: len write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint16(sg->cdb_cmd_blk + 6, len); // data_in 0-0x40-len // !!! len _and_ q_len must be max 6k, // i.e. >1024 * 6 = 6144 -> aboard) // !!! if len < q_len: 64*k, 1024*n, n=1..5 -> aboard // (broken residue issue) sl->q_len = len; sg->q_addr = addr; stlink_q(sl); stlink_print_data(sl); } // Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes. void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_8BIT; // 2-5: addr // 6-7: len (>0x40 (64) -> aboard) write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint16(sg->cdb_cmd_blk + 6, len); // this sends the command... send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); // This sends the data... send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); stlink_print_data(sl); } // Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes. void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_32BIT; // 2-5: addr // 6-7: len "unlimited" write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint16(sg->cdb_cmd_blk + 6, len); // this sends the command... send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0); // This sends the data... send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len); stlink_print_data(sl); } // Write one DWORD data to memory void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT; // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); write_uint32(sg->cdb_cmd_blk + 6, data); sl->q_len = 2; stlink_q(sl); } // Read one DWORD data from memory uint32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr) { struct stlink_libsg *sg = sl->backend_data; clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT; // 2-5: addr write_uint32(sg->cdb_cmd_blk + 2, addr); sl->q_len = 8; stlink_q(sl); return read_uint32(sl->q_buf, 4); } // Exit the jtag or swd mode and enter the mass mode. void _stlink_sg_exit_debug_mode(stlink_t *stl) { if (stl) { struct stlink_libsg* sl = stl->backend_data; clear_cdb(sl); sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT; stl->q_len = 0; // >0 -> aboard stlink_q(stl); } } // 1) open a sg device, switch the stlink from dfu to mass mode // 2) wait 5s until the kernel driver stops reseting the broken device // 3) reopen the device // 4) the device driver is now ready for a switch to jtag/swd mode // TODO thinking, better error handling, wait until the kernel driver stops reseting the plugged-in device stlink_backend_t _stlink_sg_backend = { _stlink_sg_close, _stlink_sg_exit_debug_mode, _stlink_sg_enter_swd_mode, _stlink_sg_enter_jtag_mode, _stlink_sg_exit_dfu_mode, _stlink_sg_core_id, _stlink_sg_reset, _stlink_sg_jtag_reset, _stlink_sg_run, _stlink_sg_status, _stlink_sg_version, _stlink_sg_read_debug32, _stlink_sg_read_mem32, _stlink_sg_write_debug32, _stlink_sg_write_mem32, _stlink_sg_write_mem8, _stlink_sg_read_all_regs, _stlink_sg_read_reg, NULL, /* read_all_unsupported_regs */ NULL, /* read_unsupported_regs */ NULL, /* write_unsupported_regs */ _stlink_sg_write_reg, _stlink_sg_step, _stlink_sg_current_mode, _stlink_sg_force_debug, NULL }; static stlink_t* stlink_open(const int verbose) { stlink_t *sl = malloc(sizeof (stlink_t)); memset(sl, 0, sizeof(stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); if (sl == NULL || slsg == NULL) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); return NULL; } if (libusb_init(&(slsg->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); free(sl); free(slsg); return NULL; } libusb_set_debug(slsg->libusb_ctx, 3); slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; } // TODO // Could read the interface config descriptor, and assert lots of the assumptions // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); if (r < 0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; } DLOG("Kernel driver was successfully detached\n"); } int config; if (libusb_get_configuration(slsg->usb_handle, &config)) { /* this may fail for a previous configured device */ WLOG("libusb_get_configuration()\n"); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; } // assumption: bConfigurationValue is always 1 if (config != 1) { WLOG("Your stlink got into a real weird configuration, trying to fix it!\n"); DLOG("setting new configuration (%d -> 1)\n", config); if (libusb_set_configuration(slsg->usb_handle, 1)) { /* this may fail for a previous configured device */ WLOG("libusb_set_configuration() failed\n"); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; } } if (libusb_claim_interface(slsg->usb_handle, 0)) { WLOG("libusb_claim_interface() failed\n"); libusb_close(slsg->usb_handle); libusb_exit(slsg->libusb_ctx); free(sl); free(slsg); return NULL; } // assumption: endpoint config is fixed mang. really. slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; DLOG("Successfully opened stlinkv1 by libusb :)\n"); sl->verbose = verbose; sl->backend_data = slsg; sl->backend = &_stlink_sg_backend; sl->core_stat = STLINK_CORE_STAT_UNKNOWN; slsg->q_addr = 0; return sl; }
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) { libusb_device **devs; libusb_device *dev; libusb_device_handle *handle; ssize_t num_devs; int i = 0; struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; if(hid_init() < 0) return NULL; num_devs = libusb_get_device_list(usb_context, &devs); if (num_devs < 0) return NULL; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; struct libusb_config_descriptor *conf_desc = NULL; int j, k; int interface_num = 0; int res = libusb_get_device_descriptor(dev, &desc); unsigned short dev_vid = desc.idVendor; unsigned short dev_pid = desc.idProduct; res = libusb_get_active_config_descriptor(dev, &conf_desc); if (res < 0) libusb_get_config_descriptor(dev, 0, &conf_desc); if (conf_desc) { for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { const struct libusb_interface_descriptor *intf_desc; intf_desc = &intf->altsetting[k]; if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { interface_num = intf_desc->bInterfaceNumber; /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 || vendor_id == dev_vid) && (product_id == 0x0 || product_id == dev_pid)) { struct hid_device_info *tmp; /* VID/PID match. Create the record. */ tmp = calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; /* Fill out the record */ cur_dev->next = NULL; cur_dev->path = make_path(dev, interface_num); res = libusb_open(dev, &handle); if (res >= 0) { /* Serial Number */ if (desc.iSerialNumber > 0) cur_dev->serial_number = get_usb_string(handle, desc.iSerialNumber); /* Manufacturer and Product strings */ if (desc.iManufacturer > 0) cur_dev->manufacturer_string = get_usb_string(handle, desc.iManufacturer); if (desc.iProduct > 0) cur_dev->product_string = get_usb_string(handle, desc.iProduct); #ifdef INVASIVE_GET_USAGE { /* This section is removed because it is too invasive on the system. Getting a Usage Page and Usage requires parsing the HID Report descriptor. Getting a HID Report descriptor involves claiming the interface. Claiming the interface involves detaching the kernel driver. Detaching the kernel driver is hard on the system because it will unclaim interfaces (if another app has them claimed) and the re-attachment of the driver will sometimes change /dev entry names. It is for these reasons that this section is #if 0. For composite devices, use the interface field in the hid_device_info struct to distinguish between interfaces. */ unsigned char data[256]; #ifdef DETACH_KERNEL_DRIVER int detached = 0; /* Usage Page and Usage */ res = libusb_kernel_driver_active(handle, interface_num); if (res == 1) { res = libusb_detach_kernel_driver(handle, interface_num); if (res < 0) LOG("Couldn't detach kernel driver, even though a kernel driver was attached."); else detached = 1; } #endif res = libusb_claim_interface(handle, interface_num); if (res >= 0) { /* Get the HID Report Descriptor. */ res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000); if (res >= 0) { unsigned short page=0, usage=0; /* Parse the usage and usage page out of the report descriptor. */ get_usage(data, res, &page, &usage); cur_dev->usage_page = page; cur_dev->usage = usage; } else LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res); /* Release the interface */ res = libusb_release_interface(handle, interface_num); if (res < 0) LOG("Can't release the interface.\n"); } else LOG("Can't claim interface %d\n", res); #ifdef DETACH_KERNEL_DRIVER /* Re-attach kernel driver if necessary. */ if (detached) { res = libusb_attach_kernel_driver(handle, interface_num); if (res < 0) LOG("Couldn't re-attach kernel driver.\n"); } #endif } #endif /* INVASIVE_GET_USAGE */ libusb_close(handle); } /* VID/PID */ cur_dev->vendor_id = dev_vid; cur_dev->product_id = dev_pid; /* Release Number */ cur_dev->release_number = desc.bcdDevice; /* Interface Number */ cur_dev->interface_number = interface_num; } } } /* altsettings */ } /* interfaces */ libusb_free_config_descriptor(conf_desc); } } libusb_free_device_list(devs, 1); return root; }
FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index) { freenect_context *ctx = dev->parent; dev->usb_cam.parent = dev; dev->usb_cam.dev = NULL; dev->usb_motor.parent = dev; dev->usb_motor.dev = NULL; #ifdef BUILD_AUDIO dev->usb_audio.parent = dev; dev->usb_audio.dev = NULL; #endif libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices ssize_t cnt = libusb_get_device_list (dev->parent->usb.ctx, &devs); //get the list of devices if (cnt < 0) return -1; int i = 0, nr_cam = 0, nr_mot = 0; #ifdef BUILD_AUDIO int nr_audio = 0; #endif int res; struct libusb_device_descriptor desc; for (i = 0; i < cnt; i++) { int r = libusb_get_device_descriptor (devs[i], &desc); if (r < 0) continue; if (desc.idVendor != VID_MICROSOFT) continue; res = 0; // Search for the camera if ((ctx->enabled_subdevices & FREENECT_DEVICE_CAMERA) && !dev->usb_cam.dev && (desc.idProduct == PID_NUI_CAMERA || desc.idProduct == PID_K4W_CAMERA)) { // If the index given by the user matches our camera index if (nr_cam == index) { res = libusb_open (devs[i], &dev->usb_cam.dev); if (res < 0 || !dev->usb_cam.dev) { FN_ERROR("Could not open camera: %d\n", res); dev->usb_cam.dev = NULL; break; } if(desc.idProduct == PID_K4W_CAMERA || desc.bcdDevice != fn_le32(267)){ /* Not the old kinect so we only set up the camera*/ ctx->enabled_subdevices = FREENECT_DEVICE_CAMERA; ctx->zero_plane_res = 334; }else{ /* The good old kinect that tilts and tweets */ ctx->zero_plane_res = 322; } #ifndef _WIN32 // Detach an existing kernel driver for the device res = libusb_kernel_driver_active(dev->usb_cam.dev, 0); if (res == 1) { res = libusb_detach_kernel_driver(dev->usb_cam.dev, 0); if (res < 0) { FN_ERROR("Could not detach kernel driver for camera: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } } #endif res = libusb_claim_interface (dev->usb_cam.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on camera: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } if(desc.idProduct == PID_K4W_CAMERA){ res = libusb_set_interface_alt_setting(dev->usb_cam.dev, 0, 1); if (res != 0) { FN_ERROR("Failed to set alternate interface #1 for K4W: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } } } else { nr_cam++; } } } if(ctx->enabled_subdevices == FREENECT_DEVICE_CAMERA || res < 0) cnt = 0; // Search for the motor for (i = 0; i < cnt; i++) { int r = libusb_get_device_descriptor (devs[i], &desc); if (r < 0) continue; if (desc.idVendor != VID_MICROSOFT) continue; if ((ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR) && !dev->usb_motor.dev && desc.idProduct == PID_NUI_MOTOR) { // If the index given by the user matches our camera index if (nr_mot == index) { res = libusb_open (devs[i], &dev->usb_motor.dev); if (res < 0 || !dev->usb_motor.dev) { FN_ERROR("Could not open motor: %d\n", res); dev->usb_motor.dev = NULL; break; } res = libusb_claim_interface (dev->usb_motor.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on motor: %d\n", res); libusb_close(dev->usb_motor.dev); dev->usb_motor.dev = NULL; break; } } else { nr_mot++; } } #ifdef BUILD_AUDIO // TODO: check that the firmware has already been loaded; if not, upload firmware. // Search for the audio if ((ctx->enabled_subdevices & FREENECT_DEVICE_AUDIO) && !dev->usb_audio.dev && (desc.idProduct == PID_NUI_AUDIO || desc.idProduct == PID_K4W_AUDIO)) { // If the index given by the user matches our audio index if (nr_audio == index) { res = libusb_open (devs[i], &dev->usb_audio.dev); if (res < 0 || !dev->usb_audio.dev) { FN_ERROR("Could not open audio: %d\n", res); dev->usb_audio.dev = NULL; break; } res = libusb_claim_interface (dev->usb_audio.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on audio: %d\n", res); libusb_close(dev->usb_audio.dev); dev->usb_audio.dev = NULL; break; } // Using the device handle that we've claimed, see if this // device has already uploaded firmware (has 2 interfaces). If // not, save the serial number (by reading the appropriate // descriptor), upload the firmware, and then enter a loop // waiting for a device with the same serial number to // reappear. int num_interfaces = fnusb_num_interfaces(&dev->usb_audio); if (num_interfaces == 1) { // Read the serial number from the string descriptor and save it. unsigned char string_desc[256]; // String descriptors are at most 256 bytes res = libusb_get_string_descriptor_ascii(dev->usb_audio.dev, desc.iSerialNumber, string_desc, 256); if (res < 0) { FN_ERROR("Failed to retrieve serial number for audio device in bootloader state\n"); break; } char* audio_serial = strdup((char*)string_desc); FN_SPEW("Uploading firmware to audio device in bootloader state.\n"); res = upload_firmware(&dev->usb_audio); if (res < 0) { FN_ERROR("upload_firmware failed: %d\n", res); break; } libusb_close(dev->usb_audio.dev); dev->usb_audio.dev = NULL; // Wait for the device to reappear. int loops = 0; for (loops = 0; loops < 10; loops++) { // Loop for at most 10 tries. FN_SPEW("Try %d: Looking for new audio device matching serial %s\n", loops, audio_serial); // Scan devices. libusb_device **new_dev_list; int dev_index; ssize_t num_new_devs = libusb_get_device_list(ctx->usb.ctx, &new_dev_list); for (dev_index = 0; dev_index < num_new_devs; ++dev_index) { struct libusb_device_descriptor new_dev_desc; int r; r = libusb_get_device_descriptor (new_dev_list[dev_index], &new_dev_desc); if (r < 0) continue; // If this dev is a Kinect audio device, open device, read serial, and compare. if (new_dev_desc.idVendor == VID_MICROSOFT && new_dev_desc.idProduct == PID_NUI_AUDIO) { FN_SPEW("Matched VID/PID!\n"); libusb_device_handle* new_dev_handle; // Open device r = libusb_open(new_dev_list[dev_index], &new_dev_handle); if (r < 0) continue; // Read serial r = libusb_get_string_descriptor_ascii(new_dev_handle, new_dev_desc.iSerialNumber, string_desc, 256); if (r < 0) { FN_SPEW("Lost new audio device while fetching serial number.\n"); libusb_close(new_dev_handle); continue; } // Compare to expected serial if (r == strlen(audio_serial) && strcmp((char*)string_desc, audio_serial) == 0) { // We found it! r = libusb_claim_interface(new_dev_handle, 0); if (r != 0) { // Ouch, found the device but couldn't claim the interface. FN_SPEW("Device with serial %s reappeared but couldn't claim interface 0\n", audio_serial); libusb_close(new_dev_handle); continue; } // Save the device handle. dev->usb_audio.dev = new_dev_handle; // Verify that we've actually found a device running the right firmware. if (fnusb_num_interfaces(&dev->usb_audio) != 2) { FN_SPEW("Opened audio with matching serial but too few interfaces.\n"); dev->usb_audio.dev = NULL; libusb_close(new_dev_handle); continue; } break; } else { FN_SPEW("Got serial %s, expected serial %s\n", (char*)string_desc, audio_serial); } } } libusb_free_device_list(new_dev_list, 1); // If we found the right device, break out of this loop. if (dev->usb_audio.dev) break; // Sleep for a second to give the device more time to reenumerate. sleep(1); } free(audio_serial); } } else { nr_audio++; } } #endif } libusb_free_device_list (devs, 1); // free the list, unref the devices in it // Check that each subdevice is either opened or not enabled. if ( (dev->usb_cam.dev || !(ctx->enabled_subdevices & FREENECT_DEVICE_CAMERA)) && (dev->usb_motor.dev || !(ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR)) #ifdef BUILD_AUDIO && (dev->usb_audio.dev || !(ctx->enabled_subdevices & FREENECT_DEVICE_AUDIO)) #endif ) { return 0; } else { if (dev->usb_cam.dev) { libusb_release_interface(dev->usb_cam.dev, 0); libusb_close(dev->usb_cam.dev); } if (dev->usb_motor.dev) { libusb_release_interface(dev->usb_motor.dev, 0); libusb_close(dev->usb_motor.dev); } #ifdef BUILD_AUDIO if (dev->usb_audio.dev) { libusb_release_interface(dev->usb_audio.dev, 0); libusb_close(dev->usb_audio.dev); } #endif return -1; } }
static int handle_device (libusb_device *dev, struct libusb_config_descriptor *cfg, int itfnum, const struct libusb_interface_descriptor *alt) { libusb_device_handle *devh; int res, retval; retval = -1; if (libusb_open (dev, &devh) < 0) { g_warning ("Can't open device"); goto bail; } libusb_detach_kernel_driver (devh, itfnum); res = libusb_claim_interface (devh, itfnum); if (res < 0) { g_warning ("Can't claim interface %d", itfnum); goto bail; } if (option_get_master != FALSE) { if (show_master (devh, itfnum) == FALSE) goto bail; retval = 0; } if (option_master != NULL) { if (strcmp (option_master, "auto") == 0) { g_free (option_master); option_master = get_host_bdaddr (); if (option_master == NULL) { g_warning ("Can't get bdaddr from default device"); retval = -1; goto bail; } } } else { option_master = get_host_bdaddr (); if (option_master == NULL) { g_warning ("Can't get bdaddr from default device"); retval = -1; goto bail; } } if (option_store_info != FALSE) { sdp_record_t *rec; char *device; bdaddr_t dst, src; device = get_bdaddr (devh, itfnum); if (device == NULL) { retval = -1; goto bail; } rec = record_from_string (PS3_PNP_RECORD); store_record(option_master, device, rec); write_trust(option_master, device, "[all]", TRUE); store_device_id(option_master, device, 0xffff, 0x054c, 0x0268, 0); str2ba(option_master, &src); str2ba(device, &dst); write_device_profiles(&src, &dst, ""); write_device_name(&src, &dst, "PLAYSTATION(R)3 Controller"); sdp_record_free(rec); if (set_master_bdaddr (devh, itfnum, option_master) == FALSE) { retval = -1; goto bail; } } bail: libusb_release_interface (devh, itfnum); res = libusb_attach_kernel_driver(devh, itfnum); if (res < 0) { //FIXME sometimes the kernel tells us ENOENT, but succeeds anyway... g_warning ("Reattaching the driver failed: %d", res); } if (devh != NULL) libusb_close (devh); return retval; }
void UsbWrap::Connect(const int vid, const int pid) throw (UsbWrapException) { if (!_isInitialized) { throw UsbWrapException("USB driver not initialized"); } if (_isConnected) { throw UsbWrapException("USB device already connected"); } int returnedValue = -1; /// \todo Jeżeli chcemy mieć precyzyjny wybór urządzenia z listy // returnedValue = libusb_get_device_list(_context, &_devices);int // if (returnedValue < 0) // pobieramy listę urządzeń // { // throw UsbWrapException(libusb_error_name(returnedValue)); // } _handleDevice = libusb_open_device_with_vid_pid(_context, vid, pid); if (_handleDevice == NULL) { throw UsbWrapException("Open device failed"); } /// \todo Jeżeli chcemy mieć precyzyjny wybór urządzenia z listy // libusb_free_device_list(_devices, 1); // zwalniamy listę urządzeń returnedValue = libusb_reset_device(_handleDevice); if (returnedValue < 0) { throw UsbWrapException(libusb_error_name(returnedValue)); } for (int i = 0; i < 1; ++i) { if (libusb_kernel_driver_active(_handleDevice, 0) == 1) // dowiedz się, czy sterownik jędra jest załączony { // Sterownik jadra jest aktywny if (libusb_detach_kernel_driver(_handleDevice, 0) != 0) // odłącz go { throw UsbWrapException("Detach kernel driver failed"); } } // returnedValue = libusb_claim_interface(_handleDevice, i); // uzyskaj interfejs 0 (pierwszy) urządzenia // if (returnedValue < 0) // { // throw UsbWrapException(libusb_error_name(returnedValue)); // } } // returnedValue = libusb_clear_halt(_handleDevice, EpBulkIn); // if (returnedValue != 0) // { // throw new UsbWrapException(libusb_error_name(returnedValue)); // }; // returnedValue = libusb_clear_halt(_handleDevice, EpBulkOut); // if (returnedValue != 0) // { // throw new UsbWrapException(libusb_error_name(returnedValue)); // }; // returnedValue = libusb_clear_halt(_handleDevice, 0x83); // if (returnedValue != 0) // { // throw new UsbWrapException(libusb_error_name(returnedValue)); // }; _isConnected = true; }
int main (int argc, char **argv) { bool daemonize = false; while (true) { int c; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {"daemon", no_argument, NULL, 'd'}, {"fork", no_argument, NULL, 'f'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "hvd", long_options, NULL); if (c == -1) break; switch (c) { case 'h': print_usage(argv[0]); exit(EXIT_SUCCESS); case 'v': msg("HAMA MCE remote event client v%s for XBMC\n", VERSION); exit(EXIT_SUCCESS); case 'd': daemonize = true; break; default: print_usage(argv[0]); exit(EXIT_FAILURE); } } if (optind < (argc - 1)) { err("%s: too many arguments\n", argv[0]); exit(EXIT_FAILURE); } struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_handler = handle_exit; PCHK(sigaction(SIGINT, &sa, NULL)); PCHK(sigaction(SIGTERM, &sa, NULL)); libusb_context *ctx; libusb_device_handle *dev; struct libusb_transfer *transfer0x81 = libusb_alloc_transfer(0); struct libusb_transfer *transfer0x82 = libusb_alloc_transfer(0); unsigned char buf0x81 [8]; unsigned char buf0x82 [5]; UCHK(libusb_init(&ctx)); if (!(dev = libusb_open_device_with_vid_pid(ctx, 0x05a4, 0x9881))) { err("%s: No HAMA MCE remote control found.\n", argv[0]); exit(EXIT_FAILURE); } int exit_code = EXIT_SUCCESS; if (libusb_kernel_driver_active(dev, 0)) UCHK(libusb_detach_kernel_driver(dev, 0)); if (libusb_kernel_driver_active(dev, 1)) UCHK(libusb_detach_kernel_driver(dev, 1)); UCHK(libusb_claim_interface(dev, 0)); UCHK(libusb_claim_interface(dev, 1)); libusb_fill_interrupt_transfer(transfer0x81, dev, 0x81, buf0x81, sizeof(buf0x81), transfer0x81_cb, NULL, 215); UCHK(libusb_submit_transfer(transfer0x81)); libusb_fill_interrupt_transfer(transfer0x82, dev, 0x82, buf0x82, sizeof(buf0x82), transfer0x82_cb, NULL, 200); UCHK(libusb_submit_transfer(transfer0x82)); msg("Connected HAMA MCE Remote\n"); xbmc.SendHELO("HAMA MCE Remote", ICON_NONE); if (daemonize) { if (daemon(0,0) == -1) { err("Failed to fork\n"); perror(argv[0]); exit_code = EXIT_FAILURE; goto exit; } } while (!(disconnected || quit)) { UCHK(libusb_handle_events(ctx)); } exit: if (disconnected) { msg("Disconnected HAMA MCE Remote\n"); xbmc.SendNOTIFICATION("Disconnected", "HAMA MCE Remote", ICON_NONE); } else { msg("Closing HAMA MCE Remote\n"); xbmc.SendNOTIFICATION("Closing", "HAMA MCE Remote", ICON_NONE); } libusb_free_transfer(transfer0x81); libusb_free_transfer(transfer0x82); if (!disconnected) { // Release the remote back to the system UCHK(libusb_release_interface(dev, 0)); UCHK(libusb_release_interface(dev, 1)); UCHK(libusb_attach_kernel_driver(dev, 0)); UCHK(libusb_attach_kernel_driver(dev, 1)); } libusb_close(dev); libusb_exit(ctx); exit(exit_code); }
int main(int argc, char * argv[]) { libusb_device_handle * handle; int i, ret; unsigned int level; unsigned char command[1], buf[8], channel; char param; //Arg Control if (argc == 1) { printf("Using: %s -help\n", argv[0]); return -1; } if (argc >= 2) { if(strcmp (argv[1],"-api")){ //first arg "-api" needed if (strcmp (argv[1],"-help")==0) { printf("Using %s -api -<command> <channel> [<level>]\n", argv[0]); printf(" <command> may be:\n"); printf(" -on_ch - Turn channel ON\n"); printf(" -off_ch - Turn channel OFF\n"); printf(" -sw_ch - Switch channel ON/OFF\n"); printf(" -set_ch - Set level for channel\n"); printf(" -bind_ch - Bind channel\n"); printf(" -unbind_ch - Unbind channel\n"); printf(" -preset - Activate preset\n"); printf(" <channel> must be [1..8]\n"); printf(" <level> must be [0..100] - using for -set_ch\n"); return -1; } printf("Неверно указан режим\nИспользование: %s -api -<command> <channel> [<level>]\n", argv[0]); return -1; } } else { printf("Не указан параметр API\r\nИспользование: %s -api -<command> <channel> [<level>]\n", argv[0]); return -1; } if (argc >= 3) { if (strcmp (argv[2],"-on_ch")==0) //Set cnannel ON { COMMAND_ACTION[1] = 2; } else if (strcmp(argv[2],"-off_ch")==0) //Set channel OFF { COMMAND_ACTION[1] = 0; } else if (strcmp(argv[2],"-sw_ch")==0) //Switch channel ON/OFF { COMMAND_ACTION[1] = 4; } else if (strcmp(argv[2],"-set_ch")==0) //Set level on channel - needed arg "level" { COMMAND_ACTION[1] = 6; } else if (strcmp(argv[2],"-bind_ch")==0) //Привязать канал { COMMAND_ACTION[1] = 15; } else if (strcmp(argv[2],"-unbind_ch")==0) //отвязать канал { COMMAND_ACTION[1] = 9; } else if (strcmp(argv[2],"-preset")==0) //Вызвать сценарий { COMMAND_ACTION[1] = 7; } else { printf("Command unknown\n"); return -1; } } else { printf("Не указана команда\nИспользование: %s -api -<command> <channel> [<level>]\n", argv[0]); return -1; } if (argc >= 4) { channel = atoi(argv[3]); channel--; if ((channel>7)||(channel<0)) { printf("Неверно указан канал (1-8)\nИспользование: %s -api -<command> <channel> [<level>]\n", argv[0]); return -1; } COMMAND_ACTION[4] = channel; } else { printf("Не указан канал\nИспользование: %s -api -<command> <channel> [<level>]\n", argv[0]); return -1; } if (COMMAND_ACTION[1]==6) { if (argc >= 5) { level = atoi(argv[4]); if (level>100) { level=100; } if (level<0) { level=0; } level=(int)(34+(float)level*1.23); COMMAND_ACTION[5]= level; COMMAND_ACTION[2]= 1; } else { printf("Не указан уровень \nИспользование: %s -api -<command> <channel> [<level>]\n", argv[0]); return -1; } } //Prepare Command string libusb_init(NULL); libusb_set_debug(NULL, 3); handle = libusb_open_device_with_vid_pid(NULL, DEV_VID, DEV_PID); if (handle == NULL) { printf("Не удалось найти устройство\n"); libusb_exit(NULL); return 0; } if (libusb_kernel_driver_active(handle,DEV_INTF)) libusb_detach_kernel_driver(handle, DEV_INTF); if ((ret = libusb_set_configuration(handle, DEV_CONFIG)) < 0) { printf("Ошибка конфигурации\n"); libusb_close(handle); libusb_exit(NULL); if (ret == LIBUSB_ERROR_BUSY) printf("B\n"); printf("ret:%i\n", ret); return 0; } if (libusb_claim_interface(handle, DEV_INTF) < 0) { printf("Ошибка интерфейса\n"); libusb_close(handle); libusb_exit(NULL); return 0; } //0x9 - номер запроса //0x300 - значение запроса - их надо получить из мониторинга ret = libusb_control_transfer(handle, LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 0x9, 0x300, 0, COMMAND_ACTION, 8, 100); libusb_attach_kernel_driver(handle, DEV_INTF); libusb_close(handle); libusb_exit(NULL); return 0; }
int main(int argc, char **argv) { reset_wacom_inkling(); const struct libusb_version *version = libusb_get_version(); printf("Using libusb v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano); int r=1; r = libusb_init(NULL); if (r < 0) { fprintf(stderr, "Failed to initialise libusb\n"); return 1; } // discover devices libusb_device **list; libusb_device *found = NULL; libusb_context *ctx = NULL; int attached = 0; ssize_t cnt = libusb_get_device_list(ctx, &list); ssize_t i = 0; int err = 0; if (cnt < 0){ printf( "no usb devices found\n" ); goto out; } // find our device for(i = 0; i < cnt; i++){ libusb_device *device = list[i]; struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor( device, &desc ); if( desc.idVendor == VENDOR_ID && desc.idProduct == PRODUCT_ID ){ found=device; } } if (found == NULL){ printf("Unable to find usb device\n"); goto out; } libusb_device_handle *devh; err = libusb_open(found, &devh); if (err){ printf("Unable to open usb device\n"); goto out; } printf("Successfully find device\n"); //#ifdef LINUX if (libusb_kernel_driver_active(devh,0)==1){ printf("Device busy...detaching...\n"); attached = 1; libusb_detach_kernel_driver(devh, 0); } //#endif err = libusb_claim_interface( devh, 0 ); if (err){ printf( "Failed to claim interface. " ); switch( err ){ case LIBUSB_ERROR_NOT_FOUND: printf( "not found\n" ); break; case LIBUSB_ERROR_BUSY: printf( "busy\n" ); break; case LIBUSB_ERROR_NO_DEVICE: printf( "no device\n" ); break; default: printf( "other\n" ); break; } goto out; } printf( "interface claimed\n" ); {//important to enable device, buf[4]=1 will enable output while 2 will disable //seems only 1 and 2 are valid from reading function char buf[]={0x80,0x01,0x02,0x01,0x02}; send_control_transfer(devh,buf,sizeof(buf)); } {//I guess it is setting ID. 01 is mouse and 02 are digitizer, //04 is undefined but looks like raw data we want. 08 has too many data that crash RPi, won't listen to 128 int report_id_setting=4; char buf[]={0x80,0x01,0x03,0x01,report_id_setting}; send_control_transfer(devh,buf,sizeof(buf)); } {//read back report id settings char buf[]={0x80,0x01,0x0A,0x01,0x01,0x03,0x01}; send_control_transfer(devh,buf,sizeof(buf)); } receive_control_transfer(devh); {//not sure what this is but seems important char buf[]={0x80,0x01,0x0B,0x01}; send_control_transfer(devh,buf,sizeof(buf)); } {//re-enable output char buf[]={0x80,0x01,0x02,0x01,0x01}; send_control_transfer(devh,buf,sizeof(buf)); } printf("Yeah\n"); int bytes_transferred; while(1){ r = libusb_bulk_transfer(devh,0x83,data_in,16,&bytes_transferred,TIMEOUT_MS); switch(r){ case 0: //success { if (data_in[0]==2){ int x=data_in[1]+data_in[2]*256; int y=data_in[3]+data_in[4]*256; int button=data_in[5]; int pressure=data_in[6]+data_in[7]*256; int x_tilt=(signed char)data_in[8]; int y_tilt=(signed char)data_in[9]; printf("x:%d\ty:%d\tb:%d\tp:%d\txt:%d\tyt:%d\n",x,y,button,pressure,x_tilt,y_tilt); }else if (data_in[0]==4){ int x=data_in[3]+data_in[2]*256; //ignore the 3rd byte if (x>32767) x=x-65536; int y=data_in[6]+data_in[5]*256; int button=data_in[7]; int pressure=data_in[8]+data_in[9]*256; int x_tilt=(signed char)data_in[10]; int y_tilt=(signed char)data_in[11]; static int button_last=0; if (debug_output){ printf("x:%d\ty:%d\tb:%d\tp:%d\txt:%d\tyt:%d\n",x,y,button,pressure,x_tilt,y_tilt); }else{ if (button!=0){ printf("d:%d %d\n",x,y); }else{ if (button_last!=0){ printf("u:\n"); fflush(stdout); } } } button_last=button; }else{ if (debug_output){ for(i = 0; i < bytes_transferred; i++){ printf("%02x ",data_in[i]); } printf("\n"); } } } break; case LIBUSB_ERROR_TIMEOUT : printf( "LIBUSB_ERROR_TIMEOUT (Don't worry)\n" ); break; case LIBUSB_ERROR_PIPE : printf( "LIBUSB_ERROR_PIPE \n" ); break; case LIBUSB_ERROR_OVERFLOW : printf( "no LIBUSB_ERROR_OVERFLOW \n" ); break; case LIBUSB_ERROR_NO_DEVICE : printf( "no LIBUSB_ERROR_NO_DEVICE \n" ); break; default: printf( "other\n" ); break; } } out: //libusb_reset_device(devh); libusb_close(devh); libusb_exit(NULL); return 0; }
/** * @brief --- * @param --- * @retval Error Code. See HT6022_ErrorTypeDef */ HT6022_ErrorTypeDef HT6022_DeviceOpen (HT6022_DeviceTypeDef *Device) { struct libusb_device_descriptor desc; libusb_device **DeviceList; libusb_device_handle *DeviceHandle; int DeviceCount; int DeviceIterator; int r; unsigned char Address; if (Device == NULL) return HT6022_ERROR_INVALID_PARAM; Device->Address = 0; Device->DeviceHandle = NULL; /* Get device list */ DeviceCount = libusb_get_device_list(NULL, &DeviceList); if (DeviceCount <= 0) return HT6022_ERROR_OTHER; for(DeviceIterator = 0; DeviceIterator < DeviceCount; DeviceIterator++) { Address = libusb_get_device_address (DeviceList[DeviceIterator]); if (HT6022_AddressList[Address] == 0) /* Get device descriptor*/ if (libusb_get_device_descriptor(DeviceList[DeviceIterator], &desc) == 0) /* Check VID and PID*/ if ((desc.idVendor == HT6022_VENDOR_ID)&&(desc.idProduct == HT6022_MODEL)) break; } if (DeviceIterator == DeviceCount) { libusb_free_device_list(DeviceList, 1); return HT6022_ERROR_NO_DEVICE; } r = libusb_open(DeviceList[DeviceIterator], &DeviceHandle); libusb_free_device_list(DeviceList, 1); if (r != 0) { if (r != HT6022_ERROR_NO_MEM && r != HT6022_ERROR_ACCESS) r = HT6022_ERROR_OTHER; return r; } if(libusb_kernel_driver_active(DeviceHandle, 0) == 1) if(libusb_detach_kernel_driver(DeviceHandle, 0) != 0) { libusb_close(DeviceHandle); return HT6022_ERROR_OTHER; } if(libusb_claim_interface(DeviceHandle, 0) != 0) { libusb_close(DeviceHandle); return HT6022_ERROR_OTHER; } HT6022_AddressList [Address] = 0x01; Device->Address = Address; Device->DeviceHandle = DeviceHandle; return HT6022_SUCCESS; }
libusb_device_handle * open_usb_device_handle(libusb_context * context, gboolean (*is_device)(libusb_device * device), int * iface_num, int num_ifaces){ //todo: handle cleanup on errors better. Dare I try goto? libusb_device **list = NULL; libusb_device *found = NULL; ssize_t num_usb_dev = 0; ssize_t i = 0; libusb_device_handle *handle = NULL; int retErr = libusb_get_device_list(context, &list); if(retErr < 0){ print_libusb_error(retErr, "open_usb_device_handle libusb_get_device_list"); return NULL; }else{ num_usb_dev = retErr; } for(i = 0; i < num_usb_dev; ++i){ libusb_device *device = list[i]; if(is_device(device) == TRUE){ found = device; break; } } if(found){ retErr = libusb_open(found, &handle); if(retErr){ print_libusb_error(retErr, "open_usb_device_handle libusb_open"); libusb_free_device_list(list, 1); return NULL; } for(i=0; i < num_ifaces; ++i){ retErr = libusb_kernel_driver_active(handle, iface_num[i]); if(retErr < 0){ print_libusb_error(retErr, "open_usb_device_handle libusb_kernel_driver_active"); libusb_close(handle); libusb_free_device_list(list, 1); return NULL; }else if(retErr > 0){ retErr = libusb_detach_kernel_driver(handle, iface_num[i]); if(retErr){ print_libusb_error(retErr, "open_usb_device_handle libusb_detach_kernel_driver"); libusb_close(handle); libusb_free_device_list(list, 1); return NULL; } } retErr = libusb_claim_interface(handle, iface_num[i]); if(retErr){ print_libusb_error(retErr, "open_usb_device_handle libusb_claim_interface"); libusb_attach_kernel_driver(handle, iface_num[i]); libusb_close(handle); libusb_free_device_list(list, 1); return NULL; } } }else{ fprintf(stderr, "Device not found\n"); } libusb_free_device_list(list, 1); return handle; }
int main(int argc, char *argv[]) { libusb_context *ctx; libusb_device **devs; libusb_device *dev; libusb_device_handle *handle; struct rocket_launcher *rl = NULL; ssize_t cnt; uint8_t bus, addr; int err = 0; int retval; unsigned char cmd = 0, next_cmd = 0; err = libusb_init(&ctx); if (err) { fprintf(stderr, "%s\n", libusb_error_name(err)); return EXIT_FAILURE; } cnt = libusb_get_device_list(ctx, &devs); dev = get_device(devs, cnt); if (!dev) { fprintf(stderr, "Error: Unable to detect device\n"); retval = EXIT_FAILURE; goto err_free; } bus = libusb_get_bus_number(dev); addr = libusb_get_device_address(dev); fprintf(stdout, "Bus %03d Device %03d\n", bus, addr); err = libusb_open(dev, &handle); if (err) { fprintf(stderr, "%s\n", libusb_error_name(err)); retval = EXIT_FAILURE; goto err_free; } err = libusb_kernel_driver_active(handle, 0); if (err) { err = libusb_detach_kernel_driver(handle, 0); if (err) { fprintf(stderr, "%s\n", libusb_error_name(err)); retval = EXIT_FAILURE; goto err_close; } } initscr(); noecho(); rl = malloc(sizeof(struct rocket_launcher)); /* FIXME: Only Winbond device supported at the moment */ init_winbond(rl, handle); while (1) { next_cmd = (unsigned char)getch(); switch (next_cmd) { case UP: if (rl->last_cmd == rl->cmd_down) cmd = rl->cmd_hold; else cmd = rl->cmd_up; break; case DOWN: if (rl->last_cmd == rl->cmd_up) cmd = rl->cmd_hold; else cmd = rl->cmd_down; break; case LEFT: if (rl->last_cmd == rl->cmd_right) cmd = rl->cmd_hold; else cmd = rl->cmd_left; break; case RIGHT: if (rl->last_cmd == rl->cmd_left) cmd = rl->cmd_hold; else cmd = rl->cmd_right; break; case FIRE: cmd = rl->cmd_fire; break; } rl->last_cmd = cmd; rl->control(rl, cmd); } retval = EXIT_SUCCESS; err_close: libusb_close(handle); err_free: libusb_free_device_list(devs, 1); libusb_exit(ctx); free(rl); return retval; }
static int add_adapter(void *data, struct libusb_device *dev) { int rc; struct libusb_device_descriptor desc; const char *device_name = NULL; struct libusb_adapter *old_head = NULL; struct libusb_hid *hid = (struct libusb_hid*)data; struct libusb_adapter *adapter = (struct libusb_adapter*) calloc(1, sizeof(struct libusb_adapter)); if (!adapter) return -1; if (!hid) { free(adapter); RARCH_ERR("Allocation of adapter failed.\n"); return -1; } rc = libusb_get_device_descriptor(dev, &desc); if (rc != LIBUSB_SUCCESS) { RARCH_ERR("Error getting device descriptor.\n"); goto error; } adapter->device = dev; libusb_get_description(adapter->device, adapter); if (adapter->endpoint_in == 0) { RARCH_ERR("Could not find HID config for device.\n"); goto error; } rc = libusb_open (adapter->device, &adapter->handle); if (rc != LIBUSB_SUCCESS) { RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n", (void*)adapter->device, desc.idVendor, desc.idProduct); goto error; } if (desc.iManufacturer) { libusb_get_string_descriptor_ascii(adapter->handle, desc.iManufacturer, adapter->manufacturer_name, sizeof(adapter->manufacturer_name)); #if 0 RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name); #endif } if (desc.iProduct) { libusb_get_string_descriptor_ascii(adapter->handle, desc.iProduct, adapter->name, sizeof(adapter->name)); #if 0 RARCH_ERR(" Adapter name: %s\n", adapter->name); #endif } device_name = (const char*)adapter->name; if (string_is_empty((const char*)adapter->name)) goto error; adapter->send_control_lock = slock_new(); adapter->send_control_buffer = fifo_new(4096); if (!adapter->send_control_lock || !adapter->send_control_buffer) { RARCH_ERR("Error creating send control buffer.\n"); goto error; } adapter->slot = pad_connection_pad_init(hid->slots, device_name, desc.idVendor, desc.idProduct, adapter, &libusb_hid_device_send_control); if (adapter->slot == -1) goto error; if (!pad_connection_has_interface(hid->slots, adapter->slot)) { RARCH_ERR(" Interface not found (%s).\n", adapter->name); goto error; } RARCH_LOG("Interface found: [%s].\n", adapter->name); if (libusb_kernel_driver_active(adapter->handle, 0) == 1 && libusb_detach_kernel_driver(adapter->handle, 0)) { RARCH_ERR("Error detaching handle 0x%p from kernel.\n", adapter->handle); goto error; } rc = libusb_claim_interface(adapter->handle, adapter->interface_number); if (rc != LIBUSB_SUCCESS) { RARCH_ERR("Error claiming interface %d .\n", adapter->interface_number); goto error; } RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n", adapter->device, desc.idVendor, desc.idProduct); libusb_hid_device_add_autodetect(adapter->slot, device_name, libusb_hid.ident, desc.idVendor, desc.idProduct); adapter->hid = hid; adapter->thread = sthread_create(adapter_thread, adapter); if (!adapter->thread) { RARCH_ERR("Error initializing adapter thread.\n"); goto error; } old_head = adapters.next; adapters.next = adapter; adapter->next = old_head; return 0; error: if (adapter->thread) sthread_join(adapter->thread); if (adapter->send_control_lock) slock_free(adapter->send_control_lock); if (adapter->send_control_buffer) fifo_free(adapter->send_control_buffer); if (adapter) free(adapter); return -1; }
static int gp_libusb1_open (GPPort *port) { int ret; GP_LOG_D ("()"); C_PARAMS (port); if (!port->pl->d) { gp_libusb1_find_path_lib(port); C_PARAMS (port->pl->d); } C_LIBUSB (libusb_open (port->pl->d, &port->pl->dh), GP_ERROR_IO); if (!port->pl->dh) { int saved_errno = errno; gp_port_set_error (port, _("Could not open USB device (%s)."), strerror(saved_errno)); return GP_ERROR_IO; } ret = libusb_kernel_driver_active (port->pl->dh, port->settings.usb.interface); #if 0 if (strstr(name,"usbfs") || strstr(name,"storage")) { /* other gphoto instance most likely */ gp_port_set_error (port, _("Camera is already in use.")); return GP_ERROR_IO_LOCK; } #endif switch (ret) { case 1: GP_LOG_D ("Device has a kernel driver attached (%d), detaching it now.", ret); ret = libusb_detach_kernel_driver (port->pl->dh, port->settings.usb.interface); if (ret < 0) gp_port_set_error (port, _("Could not detach kernel driver of camera device.")); else port->pl->detached = 1; case 0: /* not detached */ break; default: gp_port_set_error (port, _("Could not query kernel driver of device.")); break; } GP_LOG_D ("claiming interface %d", port->settings.usb.interface); if (LOG_ON_LIBUSB_E (libusb_claim_interface (port->pl->dh, port->settings.usb.interface))) { int saved_errno = errno; gp_port_set_error (port, _("Could not claim interface %d (%s). " "Make sure no other program (%s) " "or kernel module (such as %s) " "is using the device and you have " "read/write access to the device."), port->settings.usb.interface, strerror(saved_errno), #ifdef __linux__ "gvfs-gphoto2-volume-monitor", #else #if defined(__APPLE__) _("MacOS PTPCamera service"), #else _("unknown libgphoto2 using program"), #endif #endif "sdc2xx, stv680, spca50x"); return GP_ERROR_IO_USB_CLAIM; } gp_libusb1_queue_interrupt_urbs (port); return GP_OK; }
API_EXPORTED int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface) { return libusb_detach_kernel_driver(dev->handle, interface); }
RESPONSECODE IFDHCreateChannel ( DWORD Lun, DWORD Channel ) { //RESPONSECODE IO_Create_Channel ( DWORD Channel ) { //DWORD Lun = 0; /* Lun - Logical Unit Number, use this for multiple card slots or multiple readers. 0xXXXXYYYY - XXXX multiple readers, YYYY multiple slots. The resource manager will set these automatically. By default the resource manager loads a new instance of the driver so if your reader does not have more than one smartcard slot then ignore the Lun in all the functions. Future versions of PC/SC might support loading multiple readers through one instance of the driver in which XXXX would be important to implement if you want this. */ /* Channel - Channel ID. This is denoted by the following: 0x000001 - /dev/pcsc/1 0x000002 - /dev/pcsc/2 0x000003 - /dev/pcsc/3 USB readers may choose to ignore this parameter and query the bus for the particular reader. */ /* This function is required to open a communications channel to the port listed by Channel. For example, the first serial reader on COM1 would link to /dev/pcsc/1 which would be a sym link to /dev/ttyS0 on some machines This is used to help with intermachine independance. Once the channel is opened the reader must be in a state in which it is possible to query IFDHICCPresence() for card status. returns: IFD_SUCCESS IFD_COMMUNICATION_ERROR */ syslog(LOG_INFO, "This is the Myson driver"); srand(time(0)); int readerNum = (Lun & 0xFFFF0000) >> 16; libusb_context *context; if(libusb_init(&context) != 0) //unable to initialize libusb { syslog(LOG_INFO, "Unable to initialize libusb"); return IFD_COMMUNICATION_ERROR; } rd[readerNum].context = context; rd[readerNum].handle = libusb_open_device_with_vid_pid(context, 0x04cf, 0x9920); syslog(LOG_INFO, "Success"); if(rd[readerNum].handle == NULL) { syslog(LOG_INFO, "Did you connect the Myson?"); return IFD_COMMUNICATION_ERROR; } libusb_device* dev = libusb_get_device(rd[readerNum].handle); //avoid conflict with an existing mass storage driver //this function, although it is in the documentation, is absent from libusb.h... //libusb_set_auto_detach_kernel_driver(rd[readerNum].handle,1); //we will claim the interface if(libusb_kernel_driver_active(rd[readerNum].handle,0) == 1) //then we free it { if(libusb_detach_kernel_driver(rd[readerNum].handle,0) != 0) //error when freeing? { syslog(LOG_INFO, "Unable to detach interface from kernel driver"); libusb_close(rd[readerNum].handle); libusb_exit(context); return IFD_COMMUNICATION_ERROR; } } if(libusb_claim_interface(rd[readerNum].handle, 0) != 0) { syslog(LOG_INFO, "Unable to claim interface"); libusb_close(rd[readerNum].handle); libusb_exit(context); return IFD_COMMUNICATION_ERROR; } syslog(LOG_INFO, "Myson successfully initialized"); int maxsize = libusb_get_max_packet_size(dev, IN_ENDPOINT); printf("Max IN packet size: %d\n", maxsize); maxsize = libusb_get_max_packet_size(dev, OUT_ENDPOINT); printf("Max OUT packet size: %d\n", maxsize); return IFD_SUCCESS; }
int omron_open(omron_device* s, int device_vid, int device_pid, unsigned int device_index) { int ret; struct libusb_device **devs; struct libusb_device *found = NULL; struct libusb_device *dev; size_t i = 0; unsigned int count = 0; ssize_t device_error_code = 0; if (!s->device._is_inited) { return E_NPUTIL_NOT_INITED; } if ((device_error_code = libusb_get_device_list(s->device._context, &devs)) < 0) { return E_NPUTIL_DRIVER_ERROR; } while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; device_error_code = libusb_get_device_descriptor(dev, &desc); if (device_error_code < 0) { libusb_free_device_list(devs, 1); return E_NPUTIL_NOT_INITED; } if (desc.idVendor == device_vid && desc.idProduct == device_pid) { if(count == device_index) { found = dev; break; } ++count; } } if (found) { device_error_code = libusb_open(found, &s->device._device); if (device_error_code < 0) { libusb_free_device_list(devs, 1); return E_NPUTIL_NOT_INITED; } } else { return E_NPUTIL_NOT_INITED; } s->device._is_open = 1; if(libusb_kernel_driver_active(s->device._device, 0)) { libusb_detach_kernel_driver(s->device._device, 0); } ret = libusb_claim_interface(s->device._device, 0); return ret; }
int initialize(void){ int r=1; int i=0; int cnt=0; /* libusb initialize*/ if ((r = libusb_init(&ctx)) < 0) { perror("libusb_init\n"); exit(1); } else { libusb_set_debug(ctx,3); Dprintf("init done\n"); } /* confirm powerusb device */ /* list up all usb devices */ if((libusb_get_device_list(ctx,&devs)) < 0) { perror("no usb device found"); exit(1); } /* check every usb devices */ while((dev =devs[i++]) != NULL) { struct libusb_device_descriptor desc; if (libusb_get_device_descriptor(dev,&desc) < 0) { perror("failed to get device descriptor\n"); return 1; } /* count how many PowerUSB device connected */ if (desc.idVendor == USB_VENDOR_ID && desc.idProduct == USB_PRODUCT_ID) { cnt++; Dprintf("PowerUSB device found\n"); } } /* no PowerUSB found*/ if (cnt == 0) { fprintf(stderr, "Power USB device not connected\n"); exit(1); } /* multi-PowerUSB device found: return error*/ if (cnt > 1) { /* FIXME */ fprintf(stderr, "multi PowerUSB is not implemented yet\n"); exit(1); } /* open powerusb device */ if ((devh = libusb_open_device_with_vid_pid(ctx,USB_VENDOR_ID, USB_PRODUCT_ID)) < 0 ) { perror("can't find PowerUSB device\n"); finalize(); exit(1); } else { Dprintf("PowerUSB device opened\n"); } /* detach kernel driver if attached. */ /* is kernel driver active?*/ r = libusb_kernel_driver_active(devh,0); if (r == 1) { /*detaching kernel driver*/ r = libusb_detach_kernel_driver(devh,0); if (r != 0) { perror("detaching kernel driver failed"); exit(1); } } return 0; }
static int dev_open(struct sr_dev_inst *sdi) { struct sr_dev_driver *di = sdi->driver; struct drv_context *drvc; struct dev_context *devc; struct sr_usb_dev_inst *usb; uint8_t buffer[PACKET_LENGTH]; int ret; if (!(drvc = di->context)) { sr_err("Driver was not initialized."); return SR_ERR; } usb = sdi->conn; devc = sdi->priv; if (sr_usb_open(drvc->sr_ctx->libusb_ctx, usb) != SR_OK) return SR_ERR; /* * Determine if a kernel driver is active on this interface and, if so, * detach it. */ if (libusb_kernel_driver_active(usb->devhdl, USB_INTERFACE) == 1) { ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE); if (ret < 0) { sr_err("Failed to detach kernel driver: %s.", libusb_error_name(ret)); return SR_ERR; } } if ((ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE)) < 0) { sr_err("Failed to claim interface: %s.", libusb_error_name(ret)); return SR_ERR; } libusb_fill_control_transfer(devc->xfer_in, usb->devhdl, devc->xfer_buf_in, sl2_receive_transfer_in, sdi, USB_TIMEOUT_MS); libusb_fill_control_transfer(devc->xfer_out, usb->devhdl, devc->xfer_buf_out, sl2_receive_transfer_out, sdi, USB_TIMEOUT_MS); memset(buffer, 0, sizeof(buffer)); buffer[0] = CMD_RESET; if ((ret = sl2_transfer_out(usb->devhdl, buffer)) != PACKET_LENGTH) { sr_err("Device reset failed: %s.", libusb_error_name(ret)); return SR_ERR; } /* * Set the device to idle state. If the device is not in idle state it * possibly will reset itself after a few seconds without being used * and thereby close the connection. */ buffer[0] = CMD_IDLE; if ((ret = sl2_transfer_out(usb->devhdl, buffer)) != PACKET_LENGTH) { sr_err("Failed to set device in idle state: %s.", libusb_error_name(ret)); return SR_ERR; } sdi->status = SR_ST_ACTIVE; return SR_OK; }
int main(int argc, char **argv) { struct sigaction sigact; int r = 1; parse_args(argc, argv); sigact.sa_handler = sighandler_exit; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigact.sa_handler = sighandler_wait_child; sigaction(SIGCHLD, &sigact, NULL); if (logfile != NULL) { set_wmlogger(argv[0], WMLOGGER_FILE, logfile); } else if (daemonize) { set_wmlogger(argv[0], WMLOGGER_SYSLOG, NULL); } else { set_wmlogger(argv[0], WMLOGGER_FILE, stderr); } if (daemonize) { daemon(0, 0); } r = libusb_init(&ctx); if (r < 0) { wmlog_msg(0, "failed to initialise libusb"); exit_release_resources(1); } devh = find_wimax_device(); if (devh == NULL) { wmlog_msg(0, "Could not find/open device"); exit_release_resources(1); } wmlog_msg(0, "Device found"); if (detach_dvd && libusb_kernel_driver_active(devh, IF_DVD) == 1) { r = libusb_detach_kernel_driver(devh, IF_DVD); if (r < 0) { wmlog_msg(0, "kernel driver detach error %d", r); } else { wmlog_msg(0, "detached pseudo-DVD kernel driver"); } } if (libusb_kernel_driver_active(devh, IF_MODEM) == 1) { kernel_driver_active = 1; r = libusb_detach_kernel_driver(devh, IF_MODEM); if (r < 0) { wmlog_msg(0, "kernel driver detach error %d", r); } else { wmlog_msg(0, "detached modem kernel driver"); } } r = libusb_claim_interface(devh, IF_MODEM); if (r < 0) { wmlog_msg(0, "Claim usb interface error %d", r); exit_release_resources(1); } wmlog_msg(0, "Claimed interface"); alloc_fds(); libusb_set_pollfd_notifiers(ctx, cb_add_pollfd, cb_remove_pollfd, NULL); r = init(); if (r < 0) { wmlog_msg(0, "init error %d", r); exit_release_resources(1); } if_create(); cb_add_pollfd(tap_fd, POLLIN, NULL); r = scan_loop(); if (r < 0) { wmlog_msg(0, "scan_loop error %d", r); exit_release_resources(1); } exit_release_resources(0); return 0; }
/* * search_for_device() - Search for AOA support device in the all USB devices * @args * ctx : libusb_context * idVendor : return buffer for USB Vendor ID * idProduc : return buffer for USB Product ID * * @ret * -1 : AOA device not found * >0 : AOA Version */ int AndrOA::search_for_device(libusb_context *context, uint16_t *idVendor, uint16_t *idProduct) { int tmpRes = -1; int i; libusb_device **devices; libusb_device *device; struct libusb_device_descriptor desc; ssize_t device_count; *idVendor = *idProduct = 0; // Get the list of all ot the connected devices. device_count = libusb_get_device_list(context, &devices); if(device_count < 0){ printf("Get device error.\n"); return -1; } //Go thorugh and enumerate devices /* *New devices presented by the libusb_get_device_list() function all have a reference count of 1. You can increase and decrease reference count using libusb_ref_device() and libusb_unref_device(). A device is destroyed when its reference count reaches 0. With the above information in mind, the process of opening a device can be viewed as follows: *****Discover devices using libusb_get_device_list(). *****Choose the device that you want to operate, and call libusb_open(). *****Unref all devices in the discovered device list. *****Free the discovered device list. */ for(i=0; i<device_count; i++){ device = devices[i]; libusb_get_device_descriptor(device, &desc); #ifdef DEBUG printf("VID:%04X, PID:%04X Class:%02X\n", desc.idVendor, desc.idProduct, desc.bDeviceClass); #endif //Ignore non target device if( desc.bDeviceClass != 0 ){ continue; } //Already Android accessory mode ? if(desc.idVendor == USB_AOA_VENDOR_ID && (desc.idProduct >= USB_AOA_PRODUCT_ID && desc.idProduct <= USB_AOA_AUDIO_ADB_PRODUCT_ID) ){ #ifdef DEBUG printf("already in accessory mode.\n"); #endif tmpRes = 0; break; } //Checking the android accessory capability. if((device_handle = libusb_open_device_with_vid_pid(context, desc.idVendor, desc.idProduct)) == NULL) { printf("Device open error.\n"); } else { /* Check if the device is claimed by the kernel */ if(libusb_kernel_driver_active(device_handle, 0) == 1) { //find out if kernel driver is attached printf("Kernel Driver Active\n"); if(libusb_detach_kernel_driver(device_handle, 0) == 0) //detach it printf("Kernel Driver Detached!\n"); } libusb_claim_interface(device_handle, 0); // Claim interface 0 tmpRes = get_protocol(); libusb_release_interface (device_handle, 0); libusb_close(device_handle); device_handle = NULL; if( tmpRes != -1 ){ #ifdef DEBUG printf("Android accessory protocol version: %d\n", versionProtocol); #endif /* TODO Free devices and then device list */ libusb_free_device_list(devices, 1); break; // The andrid accessory was successfully found. } } } // Find the usb endpint to connect to if( find_end_point(device) < 0 ){ printf("Endpoint not found.\n"); tmpRes = -1; } *idVendor = desc.idVendor; *idProduct = desc.idProduct; #ifdef DEBUG printf("VID:%04X, PID:%04X\n", *idVendor, *idProduct); #endif return tmpRes; }
int main(int argc, char **argv) { libusb_context *c; libusb_device_handle *h; int offset = 0, size = 0; char action; NEXT; if (!argc) usage(); action = **argv; NEXT; switch(action) { case 'b': if (argc) usage(); break; case 'e': case 'r': case 'w': if (argc!=2) usage(); offset = strtoul(argv[0], NULL, 0); size = strtoul(argv[1], NULL, 0); break; case 'v': case 'V': printf("rkflashtool version %d.%d\n", RKFLASHTOOL_VER_MAJOR, RKFLASHTOOL_VER_MINOR); exit(0); break; default: usage(); } if (libusb_init(&c)) fatal("cannot init libusb\n"); libusb_set_debug(c, 3); if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x290a))) if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x281a))) if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x300a))) if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x310b))) fatal("cannot open device\n"); if (libusb_kernel_driver_active(h, 0) == 1) { info("kernel driver active\n"); if (!libusb_detach_kernel_driver(h, 0)) info("driver detached\n"); } if (libusb_claim_interface(h, 0)<0) fatal("cannot claim interface\n"); info("interface claimed\n"); send_cmd(h, 2, 0x80, 0x00060000, 0x00000000, 0x00); /* INIT */ recv_res(h, 1); usleep(20*1000); switch(action) { case 'b': info("rebooting device...\n"); send_cmd(h, 2, 0x00, 0x0006ff00, 0x00000000, 0x00); recv_res(h, 1); break; case 'r': while (size>0) { if (offset % RKFT_DISPLAY == 0) info("reading flash memory at offset 0x%08x\r", offset); send_cmd(h, 2, 0x80, 0x000a1400, offset, RKFT_OFF_INCR); recv_buf(h, 1, RKFT_BLOCKSIZE); recv_res(h, 1); /* check for write() errors to catch disk-full, no-perms, etc. */ if (write(1, buf, RKFT_BLOCKSIZE) < 0) fatal("error writing buffer to stdout: %s\n", strerror(errno)); offset += RKFT_OFF_INCR; size -= RKFT_OFF_INCR; } fprintf(stderr, "\n"); break; case 'w': while (size>0) { if (offset % RKFT_DISPLAY == 0) info("writing flash memory at offset 0x%08x\r", offset); memset(buf, 0, RKFT_BLOCKSIZE); /* we ignore here read() errors and pad up to given size */ if (read(0, buf, RKFT_BLOCKSIZE) < 0) {}; send_cmd(h, 2, 0x80, 0x000a1500, offset, RKFT_OFF_INCR); send_buf(h, 2, RKFT_BLOCKSIZE); recv_res(h, 1); offset += RKFT_OFF_INCR; size -= RKFT_OFF_INCR; } fprintf(stderr, "\n"); break; case 'e': memset(buf, RKFT_FILLBYTE, RKFT_BLOCKSIZE); while (size>0) { if (offset % RKFT_DISPLAY == 0) info("erasing flash memory at offset 0x%08x\r", offset); send_cmd(h, 2, 0x80, 0x000a1500, offset, RKFT_OFF_INCR); send_buf(h, 2, RKFT_BLOCKSIZE); recv_res(h, 1); offset += RKFT_OFF_INCR; size -= RKFT_OFF_INCR; } fprintf(stderr, "\n"); break; default: break; } libusb_release_interface(h, 0); libusb_close(h); libusb_exit(c); return 0; }
hid_device * HID_API_EXPORT hid_open_path(const char *path) { hid_device *dev = NULL; libusb_device **devs; libusb_device *usb_dev; int res; int d = 0; int good_open = 0; dev = new_hid_device(); if(hid_init() < 0) return NULL; libusb_get_device_list(usb_context, &devs); while ((usb_dev = devs[d++]) != NULL) { struct libusb_device_descriptor desc; struct libusb_config_descriptor *conf_desc = NULL; int i,j,k; libusb_get_device_descriptor(usb_dev, &desc); if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0) continue; for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { const struct libusb_interface_descriptor *intf_desc; intf_desc = &intf->altsetting[k]; if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber); if (!strcmp(dev_path, path)) { /* Matched Paths. Open this device */ /* OPEN HERE */ res = libusb_open(usb_dev, &dev->device_handle); if (res < 0) { LOG("can't open device\n"); free(dev_path); break; } good_open = 1; #ifdef DETACH_KERNEL_DRIVER /* Detach the kernel driver, but only if the device is managed by the kernel */ if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) { res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber); if (res < 0) { libusb_close(dev->device_handle); LOG("Unable to detach Kernel Driver\n"); free(dev_path); good_open = 0; break; } } #endif res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber); if (res < 0) { LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); free(dev_path); libusb_close(dev->device_handle); good_open = 0; break; } /* Store off the string descriptor indexes */ dev->manufacturer_index = desc.iManufacturer; dev->product_index = desc.iProduct; dev->serial_index = desc.iSerialNumber; /* Store off the interface number */ dev->interface = intf_desc->bInterfaceNumber; /* Find the INPUT and OUTPUT endpoints. An OUTPUT endpoint is not required. */ for (i = 0; i < intf_desc->bNumEndpoints; i++) { const struct libusb_endpoint_descriptor *ep = &intf_desc->endpoint[i]; /* Determine the type and direction of this endpoint. */ int is_interrupt = (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_INTERRUPT; int is_output = (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT; int is_input = (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN; /* Decide whether to use it for intput or output. */ if (dev->input_endpoint == 0 && is_interrupt && is_input) { /* Use this endpoint for INPUT */ dev->input_endpoint = ep->bEndpointAddress; dev->input_ep_max_packet_size = ep->wMaxPacketSize; } if (dev->output_endpoint == 0 && is_interrupt && is_output) { /* Use this endpoint for OUTPUT */ dev->output_endpoint = ep->bEndpointAddress; } } pthread_create(&dev->thread, NULL, read_thread, dev); /* Wait here for the read thread to be initialized. */ pthread_barrier_wait(&dev->barrier); } free(dev_path); } } } libusb_free_config_descriptor(conf_desc); } libusb_free_device_list(devs, 1); /* If we have a good handle, return it. */ if (good_open) { return dev; } else { /* Unable to open any devices. */ free_hid_device(dev); return NULL; } }
// // 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; }
static int prepare_device(libusb_device_handle * aHandle){ int r; int kernel_driver_detached = 0; // Detach OS driver (not possible for OS X and WIN32) #if !defined(__APPLE__) && !defined(_WIN32) r = libusb_kernel_driver_active(aHandle, 0); if (r < 0) { log_error("libusb_kernel_driver_active error %d", r); libusb_close(aHandle); return r; } if (r == 1) { r = libusb_detach_kernel_driver(aHandle, 0); if (r < 0) { log_error("libusb_detach_kernel_driver error %d", r); libusb_close(aHandle); return r; } kernel_driver_detached = 1; } log_info("libusb_detach_kernel_driver"); #endif const int configuration = 1; log_info("setting configuration %d...", configuration); r = libusb_set_configuration(aHandle, configuration); if (r < 0) { log_error("Error libusb_set_configuration: %d", r); if (kernel_driver_detached){ libusb_attach_kernel_driver(aHandle, 0); } libusb_close(aHandle); return r; } // reserve access to device log_info("claiming interface 0..."); r = libusb_claim_interface(aHandle, 0); if (r < 0) { log_error("Error claiming interface %d", r); if (kernel_driver_detached){ libusb_attach_kernel_driver(aHandle, 0); } libusb_close(aHandle); return r; } #ifdef HAVE_SCO log_info("claiming interface 1..."); r = libusb_claim_interface(aHandle, 1); if (r < 0) { log_error("Error claiming interface %d", r); if (kernel_driver_detached){ libusb_attach_kernel_driver(aHandle, 0); } libusb_close(aHandle); return r; } log_info("Switching to setting %u on interface 1..", ALT_SETTING); r = libusb_set_interface_alt_setting(aHandle, 1, ALT_SETTING); if (r < 0) { fprintf(stderr, "Error setting alternative setting %u for interface 1: %s\n", ALT_SETTING, libusb_error_name(r)); libusb_close(aHandle); return r; } #endif return 0; }
int fnusb_open_subdevices(freenect_device *dev, int index) { freenect_context *ctx = dev->parent; dev->usb_cam.parent = dev; dev->usb_cam.dev = NULL; dev->usb_motor.parent = dev; dev->usb_motor.dev = NULL; libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices ssize_t cnt = libusb_get_device_list (dev->parent->usb.ctx, &devs); //get the list of devices if (cnt < 0) return -1; int i = 0, nr_cam = 0, nr_mot = 0; int res; struct libusb_device_descriptor desc; for (i = 0; i < cnt; i++) { int r = libusb_get_device_descriptor (devs[i], &desc); if (r < 0) continue; if (desc.idVendor != VID_MICROSOFT) continue; // Search for the camera if (!dev->usb_cam.dev && desc.idProduct == PID_NUI_CAMERA) { // If the index given by the user matches our camera index if (nr_cam == index) { res = libusb_open (devs[i], &dev->usb_cam.dev); if (res < 0 || !dev->usb_cam.dev) { FN_ERROR("Could not open camera: %d\n", res); dev->usb_cam.dev = NULL; break; } #ifndef _WIN32 // Detach an existing kernel driver for the device res = libusb_kernel_driver_active(dev->usb_cam.dev, 0); if (res == 1) { res = libusb_detach_kernel_driver(dev->usb_cam.dev, 0); if (res < 0) { FN_ERROR("Could not detach kernel driver for camera: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } } #endif res = libusb_claim_interface (dev->usb_cam.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on camera: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } } else { nr_cam++; } } // Search for the motor if (!dev->usb_motor.dev && desc.idProduct == PID_NUI_MOTOR) { // If the index given by the user matches our camera index if (nr_mot == index) { res = libusb_open (devs[i], &dev->usb_motor.dev); if (res < 0 || !dev->usb_motor.dev) { FN_ERROR("Could not open motor: %d\n", res); dev->usb_motor.dev = NULL; break; } res = libusb_claim_interface (dev->usb_motor.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on motor: %d\n", res); libusb_close(dev->usb_motor.dev); dev->usb_motor.dev = NULL; break; } } else { nr_mot++; } } } libusb_free_device_list (devs, 1); // free the list, unref the devices in it if (dev->usb_cam.dev && dev->usb_motor.dev) { return 0; } else { if (dev->usb_cam.dev) { libusb_release_interface(dev->usb_cam.dev, 0); libusb_close(dev->usb_cam.dev); } if (dev->usb_motor.dev) { libusb_release_interface(dev->usb_motor.dev, 0); libusb_close(dev->usb_motor.dev); } return -1; } }
static pwr_tStatus IoCardInit( io_tCtx ctx, io_sAgent *ap, io_sRack *rp, io_sCard *cp) { ssize_t devnum; libusb_device **list; libusb_device *device = 0; int found = 0; int i; io_sLocalUSB_Agent *local_agent = (io_sLocalUSB_Agent *)ap->Local; io_sLocal_K8055 *local; pwr_sClass_Velleman_K8055_Board *op = (pwr_sClass_Velleman_K8055_Board *)cp->op; int sts; if ( !local_agent->libusb_ctx) return IO__INITFAIL; devnum = libusb_get_device_list( local_agent->libusb_ctx, &list); if ( devnum > 0) { for ( i = 0; i < devnum; i++) { struct libusb_device_descriptor desc; if ( libusb_get_device_descriptor( list[i], &desc) != 0) continue; if ( desc.idVendor == 0x10cf && desc.idProduct == 0x5500 + op->Super.Address) { device = list[i]; found = 1; break; } } } if ( !found) { errh_Error( "Init Velleman K8055, device not found '%s'", cp->Name); op->Status = IO__NODEVICE; ((pwr_sClass_Velleman_K8055 *)rp->op)->Status = op->Status; return IO__INITFAIL; } local = (io_sLocal_K8055 *) calloc( 1, sizeof(io_sLocal_K8055)); cp->Local = local; sts = libusb_open( device, &local->libusb_device); if ( sts != 0) { if ( sts == io_cLibDummy) op->Status = IO__DUMMYBUILD; else op->Status = IO__INITFAIL; ((pwr_sClass_Velleman_K8055 *)rp->op)->Status = op->Status; local->libusb_device = 0; return op->Status; } if ( libusb_kernel_driver_active( local->libusb_device, 0) != 0) libusb_detach_kernel_driver( local->libusb_device, 0); sts = libusb_claim_interface( local->libusb_device, 0); if ( sts < 0) { errh_Error( "K8055 Claim interface failed, sts %d, '%s'", sts, ap->Name); op->Status = IO__INITFAIL; ((pwr_sClass_Velleman_K8055 *)rp->op)->Status = op->Status; return IO__INITFAIL; } for ( i = 0; i < 2; i++) { if ( cp->chanlist[i].sop) io_AiRangeToCoef( &cp->chanlist[i]); } for ( i = 0; i < 2; i++) { if ( cp->chanlist[i+7].sop) io_AoRangeToCoef( &cp->chanlist[i+7]); } errh_Info( "Init of Velleman K8055 '%s'", cp->Name); op->Status = IO__SUCCESS; // Rack has no methods, set status if ( ((pwr_sClass_Velleman_K8055 *)rp->op)->Status == 0) ((pwr_sClass_Velleman_K8055 *)rp->op)->Status = op->Status; return IO__SUCCESS; }
FN_INTERNAL int fnusb_open_subdevices(freenect_device *dev, int index) { freenect_context *ctx = dev->parent; dev->device_does_motor_control_with_audio = 0; dev->motor_control_with_audio_enabled = 0; dev->usb_cam.parent = dev; dev->usb_cam.dev = NULL; dev->usb_motor.parent = dev; dev->usb_motor.dev = NULL; #ifdef BUILD_AUDIO dev->usb_audio.parent = dev; dev->usb_audio.dev = NULL; #endif libusb_device **devs; // pointer to pointer of device, used to retrieve a list of devices ssize_t cnt = libusb_get_device_list (dev->parent->usb.ctx, &devs); //get the list of devices if (cnt < 0) return -1; int i = 0, nr_cam = 0, nr_mot = 0; #ifdef BUILD_AUDIO int nr_audio = 0; #endif int res; struct libusb_device_descriptor desc; for (i = 0; i < cnt; i++) { int r = libusb_get_device_descriptor (devs[i], &desc); if (r < 0) continue; if (desc.idVendor != VID_MICROSOFT) continue; res = 0; // Search for the camera if ((ctx->enabled_subdevices & FREENECT_DEVICE_CAMERA) && !dev->usb_cam.dev && (desc.idProduct == PID_NUI_CAMERA || desc.idProduct == PID_K4W_CAMERA)) { // If the index given by the user matches our camera index if (nr_cam == index) { res = libusb_open (devs[i], &dev->usb_cam.dev); if (res < 0 || !dev->usb_cam.dev) { FN_ERROR("Could not open camera: %d\n", res); dev->usb_cam.dev = NULL; break; } if (desc.idProduct == PID_K4W_CAMERA || desc.bcdDevice != fn_le32(267)) { freenect_device_flags requested_devices = ctx->enabled_subdevices; // Not the 1414 kinect so remove the motor flag, this should preserve the audio flag if set ctx->enabled_subdevices = (freenect_device_flags)(ctx->enabled_subdevices & ~FREENECT_DEVICE_MOTOR); ctx->zero_plane_res = 334; dev->device_does_motor_control_with_audio = 1; // set the LED for non 1414 devices to keep the camera alive for some systems which get freezes // this code replaces keep_alive.c, which didn't know which hub the connected audio device was on // fnusb_find_connected_audio_device needs libusb 1.0.18 or later #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000102) libusb_device * audioDevice = fnusb_find_connected_audio_device(devs[i], devs, cnt); if (audioDevice != NULL) { libusb_device_handle * audioHandle = NULL; res = libusb_open(audioDevice, &audioHandle); if (res != 0) { FN_ERROR("Failed to set the LED of K4W or 1473 device: %d\n", res); } else { // we need to do this as it is possible that the device was not closed properly in a previous session // if we don't do this and the device wasn't closed properly - it can cause infinite hangs on LED and TILT functions libusb_reset_device(audioHandle); libusb_close(audioHandle); res = libusb_open(audioDevice, &audioHandle); if (res == 0) { res = libusb_claim_interface(audioHandle, 0); if (res != 0) { FN_ERROR("Unable to claim interface %d\n", res); } else { fnusb_set_led_alt(audioHandle, ctx, LED_GREEN); libusb_release_interface(audioHandle, 0); } libusb_close(audioHandle); } } } #else // Legacy: for older versions of libusb we use this approach which doesn't do well when multiple K4W or 1473 devices are attached to the system. // also set the LED ON to keep the camera alive for some systems which get freezes freenect_extra_keep_alive((desc.idProduct == PID_K4W_CAMERA) ? PID_K4W_AUDIO : PID_NUI_AUDIO); #endif #ifdef BUILD_AUDIO // for newer devices we need to enable the audio device for motor control // we only do this though if motor has been requested. if ((requested_devices & FREENECT_DEVICE_MOTOR) && (requested_devices & FREENECT_DEVICE_AUDIO) == 0) { ctx->enabled_subdevices = (freenect_device_flags)(ctx->enabled_subdevices | FREENECT_DEVICE_AUDIO); } #endif } else { // The good old kinect that tilts and tweets ctx->zero_plane_res = 322; } #ifndef _WIN32 // Detach an existing kernel driver for the device res = libusb_kernel_driver_active(dev->usb_cam.dev, 0); if (res == 1) { res = libusb_detach_kernel_driver(dev->usb_cam.dev, 0); if (res < 0) { FN_ERROR("Could not detach kernel driver for camera: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } } #endif res = libusb_claim_interface (dev->usb_cam.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on camera: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } if (desc.idProduct == PID_K4W_CAMERA) { res = libusb_set_interface_alt_setting(dev->usb_cam.dev, 0, 1); if (res != 0) { FN_ERROR("Failed to set alternate interface #1 for K4W: %d\n", res); libusb_close(dev->usb_cam.dev); dev->usb_cam.dev = NULL; break; } } } else { nr_cam++; } } } if (ctx->enabled_subdevices == FREENECT_DEVICE_CAMERA || res < 0) cnt = 0; // Search for the motor for (i = 0; i < cnt; i++) { int r = libusb_get_device_descriptor (devs[i], &desc); if (r < 0) continue; if (desc.idVendor != VID_MICROSOFT) continue; if ((ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR) && !dev->usb_motor.dev && desc.idProduct == PID_NUI_MOTOR) { // If the index given by the user matches our camera index if (nr_mot == index) { res = libusb_open (devs[i], &dev->usb_motor.dev); if (res < 0 || !dev->usb_motor.dev) { FN_ERROR("Could not open motor: %d\n", res); dev->usb_motor.dev = NULL; break; } res = libusb_claim_interface (dev->usb_motor.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on motor: %d\n", res); libusb_close(dev->usb_motor.dev); dev->usb_motor.dev = NULL; break; } } else { nr_mot++; } } #ifdef BUILD_AUDIO // Search for the audio if ((ctx->enabled_subdevices & FREENECT_DEVICE_AUDIO) && !dev->usb_audio.dev && (desc.idProduct == PID_NUI_AUDIO || fnusb_is_pid_k4w_audio(desc.idProduct))) { // If the index given by the user matches our audio index if (nr_audio == index) { res = libusb_open (devs[i], &dev->usb_audio.dev); if (res < 0 || !dev->usb_audio.dev) { FN_ERROR("Could not open audio: %d\n", res); dev->usb_audio.dev = NULL; break; } res = libusb_claim_interface (dev->usb_audio.dev, 0); if (res < 0) { FN_ERROR("Could not claim interface on audio: %d\n", res); libusb_close(dev->usb_audio.dev); dev->usb_audio.dev = NULL; break; } // Using the device handle that we've claimed, see if this // device has already uploaded firmware (has 2 interfaces). // If not, save the serial number (by reading the appropriate // descriptor), upload the firmware, and then enter a loop // waiting for a device with the same serial number to // reappear. int num_interfaces = fnusb_num_interfaces(&dev->usb_audio); if (num_interfaces >= 2) { if (dev->device_does_motor_control_with_audio) { dev->motor_control_with_audio_enabled = 1; } } else { // Read the serial number from the string descriptor and save it. unsigned char string_desc[256]; // String descriptors are at most 256 bytes res = libusb_get_string_descriptor_ascii(dev->usb_audio.dev, desc.iSerialNumber, string_desc, 256); if (res < 0) { FN_ERROR("Failed to retrieve serial number for audio device in bootloader state\n"); break; } char* audio_serial = strdup((char*)string_desc); FN_SPEW("Uploading firmware to audio device in bootloader state.\n"); // Check if we can load from memory - otherwise load from disk if (desc.idProduct == PID_NUI_AUDIO && ctx->fn_fw_nui_ptr && ctx->fn_fw_nui_size > 0) { FN_SPEW("loading firmware from memory\n"); res = upload_firmware_from_memory(&dev->usb_audio, ctx->fn_fw_nui_ptr, ctx->fn_fw_nui_size); } else if (desc.idProduct == PID_K4W_AUDIO && ctx->fn_fw_k4w_ptr && ctx->fn_fw_k4w_size > 0) { FN_SPEW("loading firmware from memory\n"); res = upload_firmware_from_memory(&dev->usb_audio, ctx->fn_fw_k4w_ptr, ctx->fn_fw_k4w_size); } else { res = upload_firmware(&dev->usb_audio, "audios.bin"); } if (res < 0) { FN_ERROR("upload_firmware failed: %d\n", res); break; } libusb_close(dev->usb_audio.dev); dev->usb_audio.dev = NULL; // Wait for the device to reappear. int loops = 0; for (loops = 0; loops < 10; loops++) { FN_SPEW("Try %d: Looking for new audio device matching serial %s\n", loops, audio_serial); // Scan devices. libusb_device **new_dev_list; int dev_index; ssize_t num_new_devs = libusb_get_device_list(ctx->usb.ctx, &new_dev_list); for (dev_index = 0; dev_index < num_new_devs; ++dev_index) { struct libusb_device_descriptor new_dev_desc; int r; r = libusb_get_device_descriptor (new_dev_list[dev_index], &new_dev_desc); if (r < 0) continue; // If this dev is a Kinect audio device, open device, read serial, and compare. if (new_dev_desc.idVendor == VID_MICROSOFT && (new_dev_desc.idProduct == PID_NUI_AUDIO || fnusb_is_pid_k4w_audio(desc.idProduct))) { FN_SPEW("Matched VID/PID!\n"); libusb_device_handle* new_dev_handle; // Open device r = libusb_open(new_dev_list[dev_index], &new_dev_handle); if (r < 0) continue; // Read serial r = libusb_get_string_descriptor_ascii(new_dev_handle, new_dev_desc.iSerialNumber, string_desc, 256); if (r < 0) { FN_SPEW("Lost new audio device while fetching serial number.\n"); libusb_close(new_dev_handle); continue; } // Compare to expected serial if (r == strlen(audio_serial) && strcmp((char*)string_desc, audio_serial) == 0) { // We found it! r = libusb_claim_interface(new_dev_handle, 0); if (r != 0) { // Ouch, found the device but couldn't claim the interface. FN_SPEW("Device with serial %s reappeared but couldn't claim interface 0\n", audio_serial); libusb_close(new_dev_handle); continue; } // Save the device handle. dev->usb_audio.dev = new_dev_handle; // Verify that we've actually found a device running the right firmware. num_interfaces = fnusb_num_interfaces(&dev->usb_audio); if (num_interfaces >= 2) { if (dev->device_does_motor_control_with_audio) { dev->motor_control_with_audio_enabled = 1; } } else { FN_SPEW("Opened audio with matching serial but too few interfaces.\n"); dev->usb_audio.dev = NULL; libusb_close(new_dev_handle); continue; } break; } else { FN_SPEW("Got serial %s, expected serial %s\n", (char*)string_desc, audio_serial); } } } libusb_free_device_list(new_dev_list, 1); // If we found the right device, break out of this loop. if (dev->usb_audio.dev) break; // Sleep for a second to give the device more time to reenumerate. sleep(1); } free(audio_serial); } } else { nr_audio++; } } #endif } libusb_free_device_list (devs, 1); // free the list, unref the devices in it // Check that each subdevice is either opened or not enabled. if ((dev->usb_cam.dev || !(ctx->enabled_subdevices & FREENECT_DEVICE_CAMERA)) && (dev->usb_motor.dev || !(ctx->enabled_subdevices & FREENECT_DEVICE_MOTOR)) #ifdef BUILD_AUDIO && (dev->usb_audio.dev || !(ctx->enabled_subdevices & FREENECT_DEVICE_AUDIO)) #endif ) { return 0; } else { if (dev->usb_cam.dev) { libusb_release_interface(dev->usb_cam.dev, 0); libusb_close(dev->usb_cam.dev); } else { FN_ERROR("Failed to open camera subdevice or it is not disabled."); } if (dev->usb_motor.dev) { libusb_release_interface(dev->usb_motor.dev, 0); libusb_close(dev->usb_motor.dev); } else { FN_ERROR("Failed to open motor subddevice or it is not disabled."); } #ifdef BUILD_AUDIO if (dev->usb_audio.dev) { libusb_release_interface(dev->usb_audio.dev, 0); libusb_close(dev->usb_audio.dev); } else { FN_ERROR("Failed to open audio subdevice or it is not disabled."); } #endif return -1; } }