int main() { int r; // return values r = libusb_init(NULL); if (r < 0) error("ERROR: failed to initialize libusb (r = %d)\n", r); libusb_set_debug(NULL, 3); libusb_device **list; ssize_t cnt = libusb_get_device_list(NULL, &list); if (cnt < 0) error("ERROR: failed to get device list (cnt = %d)\n", cnt); for (ssize_t i = 0; i < cnt; i++) { libusb_device *dev = list[i]; struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor(dev, &desc); if (r < 0) error("ERROR: failed to get device descriptor (r = %d)\n", r); if (desc.idVendor == pololuVendorID) { for (int j = 0; j < NUM_PRODUCT_IDS && smc_count < 2; j++) { if (desc.idProduct == smcProductIDs[j]) { libusb_device_handle *handle; r = libusb_open(dev, &handle); if (r < 0) error("ERROR: failed to open device (r = %d)\n", r); smc_list[smc_count] = handle; smc_count++; char buf[100]; r = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, buf, sizeof(buf)); if (r < 0) error("ERROR: failed to get serial number string from device (r = %d)\n", r); switch(desc.idProduct) { case 0x98: printf("18v15"); break; case 0x9A: printf("24v12"); break; case 0x9C: printf("18v25"); break; case 0x9E: printf("24v23"); break; case 0xA1: printf("18v7"); break; } printf(" #%s\n", buf); break; } } } } if (smc_count == 1) printf("1 Simple Motor Controller found.\n", smc_count); else printf("%d Simple Motor Controllers found.\n", smc_count); printf("Sending ExitSafeStart...\n"); for (int i = 0; i < smc_count; i++) { r = libusb_control_transfer(smc_list[i], 0x40, ExitSafeStart, 0, 0, NULL, 0, 5000); if (r < 0) error("ERROR: failed to exit safe start (r = %d)\n", r); } set_speeds(3200, 3200); sleep(4); set_speeds(0, 0); /*char c; while (1) { scanf("%c", &c); fflush(stdin); printf("input: %c\n", c); switch (c) { case 'w': set_speeds(3200, 3200); break; case 'a': set_speeds(-3200, 3200); break; case 's': set_speeds(-3200, -3200); break; case 'd': set_speeds(3200, -3200); break; default: set_speeds(0, 0); } usleep(500000); }*/ for (int i = 0; i < smc_count; i++) libusb_close(smc_list[i]); libusb_free_device_list(list, 1); libusb_exit(NULL); return 0; }
int AndrOA::connect_to_accessory(void) { /* *Each usb device is manipulated with a libusb_device and libusb_device_handle objects in libusb. The libusb API ties an open device to a specific interface. This means that if you want to claim multiple interfaces on a device, you should open the device multiple times to receive one libusb_dev_handle for each interface you want to communicate with. Don't forget to call usb_claim_interface. */ int returned = libusb_init(&context); if(returned != 0){ printf("ERROR libusb_init failed\n"); return 1; } unsigned char ioBuffer[2]; int protocol; int res; int tries = 10; uint16_t idVendor, idProduct; /* Search for connected devices */ protocol = search_for_device(context, &idVendor, &idProduct); if ( protocol < 0 ) { printf("ERROR Android accessory device not found.\n"); return -1; } else if( protocol == 0 ) { // Check if we are already in accessory mode device_handle = libusb_open_device_with_vid_pid(context, idVendor, idProduct); libusb_claim_interface(device_handle, 0); return 0; } versionProtocol = protocol; device_handle = libusb_open_device_with_vid_pid(context, idVendor, idProduct); libusb_claim_interface(device_handle, 0); usleep(800); /* Send the accessory info */ send_string(AOA_STRING_MANUFACTURER, (char*)manufacturer); send_string(AOA_STRING_MODEL, (char*)model); send_string(AOA_STRING_DESCRIPTION, (char*)description); send_string(AOA_STRING_VERSION, (char*)version); send_string(AOA_STRING_URI, (char*)url); send_string(AOA_STRING_SERIAL, (char*)serial); /* Swich to accessory mode */ res = libusb_control_transfer(device_handle, 0x40, AOA_START, 0, 0, NULL, 0, 0); if(res < 0){ libusb_close(device_handle); device_handle = NULL; return -2; } /* Check that the devicehandle is reall NULLED */ if(device_handle != NULL){ libusb_close(device_handle); device_handle = NULL; } usleep(8000); printf("connecting to a new ProductID...\n"); //attempt to connect to new PID, //if that doesn't work try AOA_PID_ALT for(;;){ --tries; int tmpRes = search_for_device(context, &idVendor, &idProduct); if(tmpRes != 0){ continue; } device_handle = libusb_open_device_with_vid_pid(context, idVendor, idProduct); if( device_handle == NULL ){ if( tries < 0 ){ return -1; } } else{ break; } sleep(1); } res = libusb_claim_interface(device_handle, 0); if(res < 0){ return -3; } printf("Established Android accessory connection.\n"); return 0; }
int main(int argc, char **argv) { int rc; libusb_device_handle *handle = NULL; rc = libusb_init(NULL); assert(rc == 0); if (argc <= 1) { printf("Usage: %s command arguments... [command...]\n" " hex[dump] address length Dumps memory region in hex\n" " dump address length Binary memory dump\n" " exe[cute] address Call function address\n" " write address file Store file contents into memory\n" " ver[sion] Show BROM version\n" " clear address length Clear memory\n" " fill address length value Fill memory\n" , argv[0] ); } handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8); if (!handle) { fprintf(stderr, "A10 USB FEL device not found!"); exit(1); } rc = libusb_claim_interface(handle, 0); assert(rc == 0); while (argc > 1 ) { int skip = 1; if (strncmp(argv[1], "hex", 3) == 0 && argc > 3) { aw_fel_hexdump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if (strncmp(argv[1], "dump", 4) == 0 && argc > 3) { aw_fel_dump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; } else if ((strncmp(argv[1], "exe", 3) == 0 && argc > 2) ) { aw_fel_execute(handle, strtoul(argv[2], NULL, 0)); skip=3; } else if (strncmp(argv[1], "ver", 3) == 0 && argc > 1) { aw_fel_get_version(handle); skip=1; } else if (strcmp(argv[1], "write") == 0 && argc > 3) { size_t size; void *buf = load_file(argv[3], &size); aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), size); free(buf); skip=3; } else if (strcmp(argv[1], "clear") == 0 && argc > 2) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), 0); skip=3; } else if (strcmp(argv[1], "fill") == 0 && argc > 3) { aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), (unsigned char)strtoul(argv[4], NULL, 0)); skip=4; } else { fprintf(stderr,"Invalid command %s\n", argv[1]); exit(1); } argc-=skip; argv+=skip; } return 0; }
static int lusb_open(void **driver, struct bladerf_devinfo *info_in, struct bladerf_devinfo *info_out) { int status, i, n; int fx3_status; ssize_t count; struct bladerf_lusb *lusb = NULL; libusb_device **list = NULL; struct bladerf_devinfo thisinfo; libusb_context *context; /* Initialize libusb for device tree walking */ status = libusb_init(&context); if (status) { log_error("Could not initialize libusb: %s\n", libusb_error_name(status)); status = error_conv(status); goto error; } /* We can only print this out when log output is enabled, or else we'll * get snagged by -Werror=unused-but-set-variable */ # ifdef LOGGING_ENABLED { char buf[64]; get_libusb_version(buf, sizeof(buf)); log_verbose("Using libusb version: %s\n", buf); } # endif /* Iterate through all the USB devices */ count = libusb_get_device_list(context, &list); for (i = 0, n = 0; i < count; i++) { if (device_is_bladerf(list[i])) { log_verbose("Found a bladeRF (based upon VID/PID)\n"); /* Open the USB device and get some information */ status = get_devinfo(list[i], &thisinfo); if(status < 0) { log_debug("Could not open bladeRF device: %s\n", libusb_error_name(status) ); status = 0; continue; /* Continue trying the next devices */ } thisinfo.instance = n++; /* Check to see if this matches the info struct */ if (bladerf_devinfo_matches(&thisinfo, info_in)) { lusb = (struct bladerf_lusb *)malloc(sizeof(struct bladerf_lusb)); if (lusb == NULL) { log_debug("Skipping instance %d due to failed allocation\n", thisinfo.instance); lusb = NULL; continue; /* Try the next device */ } lusb->context = context; lusb->dev = list[i]; status = libusb_open(list[i], &lusb->handle); if (status < 0) { log_debug("Skipping - could not open device: %s\n", libusb_error_name(status)); /* Keep trying other devices */ status = 0; free(lusb); lusb = NULL; continue; } status = libusb_claim_interface(lusb->handle, 0); if(status < 0) { log_debug("Skipping - could not claim interface: %s\n", libusb_error_name(status)); /* Keep trying other devices */ status = 0; libusb_close(lusb->handle); free(lusb); lusb = NULL; continue; } memcpy(info_out, &thisinfo, sizeof(struct bladerf_devinfo)); *driver = lusb; break; } else { log_verbose("Devinfo doesn't match - skipping" "(instance=%d, serial=%d, bus/addr=%d\n", bladerf_instance_matches(&thisinfo, info_in), bladerf_serial_matches(&thisinfo, info_in), bladerf_bus_addr_matches(&thisinfo, info_in)); } } if (device_is_fx3_bootloader(list[i])) { fx3_status = get_devinfo(list[i], &thisinfo); if (fx3_status != 0) { log_debug("Could not open FX3 bootloader device: %s\n", libusb_error_name(fx3_status)); continue; } log_info("Found FX3 bootloader device on bus=%d addr=%d. " "This may be a bladeRF.\n", thisinfo.usb_bus, thisinfo.usb_addr); log_info("Use bladeRF-cli command \"recover %d %d " "<FX3 firmware>\" to boot the bladeRF firmware.\n", thisinfo.usb_bus, thisinfo.usb_addr); } } error: if (list) { libusb_free_device_list(list, 1); } if (lusb == NULL) { log_debug("No devices available on the libusb backend.\n"); status = BLADERF_ERR_NODEV; } if (status != 0) { if (lusb != NULL) { if (lusb->handle) { libusb_close(lusb->handle); } free(lusb); } libusb_exit(context); } return status; }
int main(int argc, char **argv) { const char *lua_init = "init.lua"; std::vector< std::pair< exec_type, std::string > > startup_cmds; // parse command line while(1) { static struct option long_options[] = { {"help", no_argument, 0, '?'}, {"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0} }; int c = getopt_long(argc, argv, "?qi:e:f:", long_options, NULL); if(c == -1) break; switch(c) { case -1: break; case 'q': g_quiet = true; break; case '?': usage(); break; case 'i': lua_init = optarg; break; case 'e': startup_cmds.push_back(std::make_pair(exec_cmd, std::string(optarg))); break; case 'f': startup_cmds.push_back(std::make_pair(exec_file, std::string(optarg))); break; default: abort(); } } // load register descriptions std::vector< soc_t > socs; for(int i = optind; i < argc; i++) { socs.push_back(soc_t()); if(!soc_desc_parse_xml(argv[i], socs[socs.size() - 1])) { printf("Cannot load description '%s'\n", argv[i]); return 2; } } // create usb context libusb_context *ctx; libusb_init(&ctx); libusb_set_debug(ctx, 3); // look for device if(!g_quiet) printf("Looking for hwstub device ...\n"); // open first device libusb_device **list; ssize_t cnt = hwstub_get_device_list(ctx, &list); if(cnt <= 0) { printf("No device found\n"); return 1; } libusb_device_handle *handle; if(libusb_open(list[0], &handle) != 0) { printf("Cannot open device\n"); return 1; } libusb_free_device_list(list, 1); // admin stuff libusb_device *mydev = libusb_get_device(handle); if(!g_quiet) { printf("device found at %d:%d\n", libusb_get_bus_number(mydev), libusb_get_device_address(mydev)); } g_hwdev = hwstub_open(handle); if(g_hwdev == NULL) { printf("Cannot open device!\n"); return 1; } // get hwstub information int ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_VERSION, &g_hwdev_ver, sizeof(g_hwdev_ver)); if(ret != sizeof(g_hwdev_ver)) { printf("Cannot get version!\n"); goto Lerr; } if(g_hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || g_hwdev_ver.bMinor < HWSTUB_VERSION_MINOR) { printf("Warning: this tool is possibly incompatible with your device:\n"); printf("Device version: %d.%d.%d\n", g_hwdev_ver.bMajor, g_hwdev_ver.bMinor, g_hwdev_ver.bRevision); printf("Host version: %d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR); } // get memory layout information ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_LAYOUT, &g_hwdev_layout, sizeof(g_hwdev_layout)); if(ret != sizeof(g_hwdev_layout)) { printf("Cannot get layout: %d\n", ret); goto Lerr; } // get target ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_TARGET, &g_hwdev_target, sizeof(g_hwdev_target)); if(ret != sizeof(g_hwdev_target)) { printf("Cannot get target: %d\n", ret); goto Lerr; } // get STMP specific information if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) { ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_STMP, &g_hwdev_stmp, sizeof(g_hwdev_stmp)); if(ret != sizeof(g_hwdev_stmp)) { printf("Cannot get stmp: %d\n", ret); goto Lerr; } } // get PP specific information if(g_hwdev_target.dID == HWSTUB_TARGET_PP) { ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_PP, &g_hwdev_pp, sizeof(g_hwdev_pp)); if(ret != sizeof(g_hwdev_pp)) { printf("Cannot get pp: %d\n", ret); goto Lerr; } } /** Init lua */ // create lua state g_lua = luaL_newstate(); if(g_lua == NULL) { printf("Cannot create lua state\n"); return 1; } // import hwstub if(!my_lua_import_hwstub()) printf("Cannot import hwstub description into Lua context\n"); // open all standard libraires luaL_openlibs(g_lua); // import socs if(!my_lua_import_soc(socs)) printf("Cannot import SoC descriptions into Lua context\n"); if(luaL_dofile(g_lua, lua_init)) printf("error in init: %s\n", lua_tostring(g_lua, -1)); lua_pop(g_lua, lua_gettop(g_lua)); /** start interactive mode */ if(!g_quiet) printf("Starting interactive lua session. Type 'help()' to get some help\n"); /** run startup commands */ for(size_t i = 0; i < startup_cmds.size(); i++) { bool ret = false; if(!g_quiet) printf("Running '%s'...\n", startup_cmds[i].second.c_str()); if(startup_cmds[i].first == exec_file) ret = luaL_dofile(g_lua, startup_cmds[i].second.c_str()); else if(startup_cmds[i].first == exec_cmd) ret = luaL_dostring(g_lua, startup_cmds[i].second.c_str()); if(ret) printf("error: %s\n", lua_tostring(g_lua, -1)); } // use readline to provide some history and completion rl_bind_key('\t', rl_complete); while(!g_exit) { char *input = readline("> "); if(!input) break; add_history(input); // evaluate string if(luaL_dostring(g_lua, input)) printf("error: %s\n", lua_tostring(g_lua, -1)); // pop everything to start from a clean stack lua_pop(g_lua, lua_gettop(g_lua)); free(input); } Lerr: // display log if handled if(!g_quiet) printf("Device log:\n"); print_log(g_hwdev); hwstub_release(g_hwdev); return 1; }
static void *libusb_hid_init(void) { unsigned i, count; int ret; struct libusb_device **devices; libusb_hid_t *hid = (libusb_hid_t*)calloc(1, sizeof(*hid)); if (!hid) goto error; ret = libusb_init(&hid->ctx); if (ret < 0) goto error; if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) goto error; hid->slots = pad_connection_init(MAX_USERS); if (!hid->slots) goto error; count = libusb_get_device_list(hid->ctx, &devices); for (i = 0; i < count; i++) { struct libusb_device_descriptor desc; libusb_get_device_descriptor(devices[i], &desc); if (desc.idVendor > 0 && desc.idProduct > 0) add_adapter(hid, devices[i]); } if (count > 0) libusb_free_device_list(devices, 1); ret = libusb_hotplug_register_callback( hid->ctx, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, libusb_hid_hotplug_callback, hid, &hid->hp); if (ret != LIBUSB_SUCCESS) { RARCH_ERR("Error creating a hotplug callback.\n"); goto error; } hid->poll_thread = sthread_create(poll_thread, hid); if (!hid->poll_thread) { RARCH_ERR("Error creating polling thread"); goto error; } return hid; error: libusb_hid_free(hid); return NULL; }
int main(int argc, char **argv) { char *gsmtap_host = "127.0.0.1"; int rc; int c, ret = 1; int skip_atr = 0; int keep_running = 0; int dump_usb = 0; int replay = 0; struct libusb_device_handle *devh; print_welcome(); while (1) { int option_index = 0; c = getopt_long(argc, argv, "i:ahkd:r:", opts, &option_index); if (c == -1) break; switch (c) { case 'h': print_help(); exit(0); break; case 'i': gsmtap_host = optarg; break; case 'a': skip_atr = 1; break; case 'k': keep_running = 1; break; case 'd': dump_usb = 1; dump_usb_file = fopen(optarg,"wb"); break; case 'r': replay = 1; dump_usb_file = fopen(optarg,"rb"); printf("replaying file %s...\n",optarg); break; } } rc = libusb_init(NULL); if (rc < 0) { fprintf(stderr, "libusb initialization failed\n"); goto close_exit; } g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0); if (!g_gti) { perror("unable to open GSMTAP"); goto close_exit; } gsmtap_source_add_sink(g_gti); as = apdu_split_init(&apdu_out_cb, NULL); if (!as) goto release_exit; if (replay) { printf("done replaying file...\n"); replay_mainloop(dump_usb_file); fclose(dump_usb_file); } else { do { devh = libusb_open_device_with_vid_pid(NULL, SIMTRACE_USB_VENDOR, SIMTRACE_USB_PRODUCT); if (!devh) { fprintf(stderr, "can't open USB device\n"); goto close_exit; } rc = libusb_claim_interface(devh, 0); if (rc < 0) { fprintf(stderr, "can't claim interface; rc=%d\n", rc); goto close_exit; } run_mainloop(devh); ret = 0; libusb_release_interface(devh, 0); close_exit: if (devh) libusb_close(devh); if (keep_running) sleep(1); } while (keep_running); } release_exit: libusb_exit(NULL); return ret; }
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 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; }
int gp_port_library_list (GPPortInfoList *list) { GPPortInfo info; int nrofdevices = 0; int d, i, i1, i2, unknownint; libusb_context *ctx; libusb_device **devs = NULL; int nrofdevs = 0; struct libusb_device_descriptor *descs; C_LIBUSB (libusb_init (&ctx), GP_ERROR_IO); /* TODO: make sure libusb_exit gets called in all error paths inside this function */ /* generic matcher. This will catch passed XXX,YYY entries for instance. */ C_GP (gp_port_info_new (&info)); gp_port_info_set_type (info, GP_PORT_USB); gp_port_info_set_name (info, ""); gp_port_info_set_path (info, "^usb:"); gp_port_info_list_append (list, info); /* do not check return value, it might be -1 */ nrofdevs = libusb_get_device_list (ctx, &devs); C_MEM (descs = calloc (nrofdevs, sizeof(descs[0]))); for (i=0;i<nrofdevs;i++) LOG_ON_LIBUSB_E (libusb_get_device_descriptor(devs[i], &descs[i])); for (d = 0; d < nrofdevs; d++) { /* Devices which are definitely not cameras. */ if ( (descs[d].bDeviceClass == LIBUSB_CLASS_HUB) || (descs[d].bDeviceClass == LIBUSB_CLASS_HID) || (descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER) || (descs[d].bDeviceClass == LIBUSB_CLASS_COMM) || (descs[d].bDeviceClass == 0xe0) /* wireless / bluetooth */ ) continue; /* excepts HUBs, usually the interfaces have the classes, not * the device */ unknownint = 0; for (i = 0; i < descs[d].bNumConfigurations; i++) { struct libusb_config_descriptor *config; if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (devs[d], i, &config))) { unknownint++; continue; } for (i1 = 0; i1 < config->bNumInterfaces; i1++) for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) { const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; if ( (intf->bInterfaceClass == LIBUSB_CLASS_HID) || (intf->bInterfaceClass == LIBUSB_CLASS_PRINTER) || (intf->bInterfaceClass == LIBUSB_CLASS_COMM) || (intf->bInterfaceClass == 0xe0) /* wireless/bluetooth*/ ) continue; unknownint++; } libusb_free_config_descriptor (config); } /* when we find only hids, printer or comm ifaces ... skip this */ if (!unknownint) continue; /* Note: We do not skip USB storage. Some devices can support both, * and the Ricoh erronously reports it. */ nrofdevices++; } #if 0 /* If we already added usb:, and have 0 or 1 devices we have nothing to do. * This should be the standard use case. */ /* We never want to return just "usb:" ... also return "usb:XXX,YYY", and * let upper layers filter out the usb: */ if (nrofdevices <= 1) return (GP_OK); #endif /* Redo the same bus/device walk, but now add the ports with usb:x,y notation, * so we can address all USB devices. */ for (d = 0; d < nrofdevs; d++) { char path[200]; /* Devices which are definitely not cameras. */ if ( (descs[d].bDeviceClass == LIBUSB_CLASS_HUB) || (descs[d].bDeviceClass == LIBUSB_CLASS_HID) || (descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER) || (descs[d].bDeviceClass == LIBUSB_CLASS_COMM) ) continue; /* excepts HUBs, usually the interfaces have the classes, not * the device */ unknownint = 0; for (i = 0; i < descs[d].bNumConfigurations; i++) { struct libusb_config_descriptor *config; if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (devs[d], i, &config))) { unknownint++; continue; } for (i1 = 0; i1 < config->bNumInterfaces; i1++) for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) { const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; if ( (intf->bInterfaceClass == LIBUSB_CLASS_HID) || (intf->bInterfaceClass == LIBUSB_CLASS_PRINTER) || (intf->bInterfaceClass == LIBUSB_CLASS_COMM)) continue; unknownint++; } libusb_free_config_descriptor (config); } /* when we find only hids, printer or comm ifaces ... skip this */ if (!unknownint) continue; /* Note: We do not skip USB storage. Some devices can support both, * and the Ricoh erronously reports it. */ C_GP (gp_port_info_new (&info)); gp_port_info_set_type (info, GP_PORT_USB); gp_port_info_set_name (info, "Universal Serial Bus"); snprintf (path,sizeof(path), "usb:%03d,%03d", libusb_get_bus_number (devs[d]), libusb_get_device_address (devs[d]) ); gp_port_info_set_path (info, path); C_GP (gp_port_info_list_append (list, info)); } libusb_free_device_list (devs, 1); libusb_exit (ctx); /* should free all stuff above */ free (descs); /* This will only be added if no other device was ever added. * Users doing "usb:" usage will enter the regular expression matcher case. */ if (nrofdevices == 0) { C_GP (gp_port_info_new (&info)); gp_port_info_set_type (info, GP_PORT_USB); gp_port_info_set_name (info, "Universal Serial Bus"); gp_port_info_set_path (info, "usb:"); C_GP (gp_port_info_list_append (list, info)); } return (GP_OK); }
int main(int argc, char **argv) { if(argc <= 1) usage(); int ret = 0; libusb_init(NULL); libusb_device_handle *dev = libusb_open_device_with_vid_pid(NULL, 0x601a, 0x4760); if(dev == NULL) { printf("Cannot open device\n"); return -1; } if(libusb_claim_interface(dev, 0) != 0) { printf("Cannot claim interface\n"); libusb_close(dev); return -2; } enum { OPT_ADDR = 0x100, OPT_LENGTH, OPT_UPLOAD, OPT_CPUINFO, OPT_DOWNLOAD, OPT_START1, OPT_WAIT, OPT_RENUMERATE, OPT_START2, OPT_FLUSH_CACHES, OPT_S1_ADDR, OPT_STAGE1 }; unsigned long last_length = 0; unsigned long s1_addr = 0x80000000; while(1) { static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"cpuinfo", no_argument, 0, OPT_CPUINFO}, {"addr", required_argument, 0, OPT_ADDR}, {"length", required_argument, 0, OPT_LENGTH}, {"upload", required_argument, 0, OPT_UPLOAD}, {"download", required_argument, 0, OPT_DOWNLOAD}, {"start1", required_argument, 0, OPT_START1}, {"wait", required_argument, 0, OPT_WAIT}, {"renumerate", no_argument, 0, OPT_RENUMERATE}, {"start2", required_argument, 0, OPT_START2}, {"flush-caches", no_argument, 0, OPT_FLUSH_CACHES}, {"s1-addr", required_argument, 0, OPT_S1_ADDR}, {"stage1", required_argument, 0, OPT_STAGE1}, {0, 0, 0, 0} }; int c = getopt_long(argc, argv, "hv", long_options, NULL); char *end = 0; unsigned long param; if(c == OPT_ADDR || c == OPT_LENGTH || c == OPT_START1 || c == OPT_WAIT || c == OPT_S1_ADDR) { param = strtoul(optarg, &end, 0); if(*end) { printf("Invalid argument '%s'\n", optarg); ret = 1; break; } } if(c == -1) break; switch(c) { default: case -1: break; case 'h': usage(); break; case 'v': g_verbose = true; break; case OPT_ADDR: ret = jz_set_addr(dev, param); break; case OPT_LENGTH: last_length = param; ret = jz_set_length(dev, param); break; case OPT_UPLOAD: ret = jz_upload(dev, optarg, last_length); break; case OPT_DOWNLOAD: ret = jz_download(dev, optarg); break; case OPT_CPUINFO: ret = jz_cpuinfo(dev); break; case OPT_START1: ret = jz_start1(dev, param); break; case OPT_WAIT: if(g_verbose) printf("Wait for %lu seconds...\n", param); sleep(param); break; case OPT_RENUMERATE: ret = renumerate(&dev); break; case OPT_START2: ret = jz_start2(dev, param); break; case OPT_FLUSH_CACHES: ret = jz_flush_caches(dev); break; case OPT_S1_ADDR: s1_addr = param; break; case OPT_STAGE1: ret = jz_stage1(dev, s1_addr, optarg); break; } if(ret != 0) break; } if(optind != argc) { printf("Error: extra arguments on command line\n"); ret = 1; } libusb_close(dev); libusb_exit(NULL); return ret; }
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); }
fx2::fx2():dev_handle(NULL) { int rv=libusb_init(&libusb_ctx); assert(!rv); libusb_set_debug(libusb_ctx,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; }
fx3_dev_err_t FX3Dev::init(const char* firmwareFileName /* = NULL */, const char* additionalFirmwareFileName /* = NULL */ ) { int ires = libusb_init( &ctx ); if ( ires != 0 ) { fprintf( stderr, "FX3Dev::Init(): __error__ libusb_init, code %d %s\n", ires, libusb_error_name( ires ) ); return FX3_ERR_USB_INIT_FAIL; } libusb_set_debug( ctx, FX3_DEBUG_LEVEL_DEFAULT ); scan(); fx3_dev_err_t eres = FX3_ERR_OK; if ( endpoint_from_dev_num == endpoint_invalid ) { fprintf( stderr, "FX3Dev::Init() asked to flash firmware. Looking for device without firmware (pid = 0x%04x)\n", DEV_PID_FOR_FW_LOAD ); device_handle = libusb_open_device_with_vid_pid( ctx, VENDOR_ID, DEV_PID_FOR_FW_LOAD ); if( device_handle != NULL ) { fprintf( stderr, "FX3Dev::Init() Found device. Will flash it with firmware from file '%s'\n", firmwareFileName ); eres = firmwareFlashFromFile( firmwareFileName ); if ( eres == FX3_ERR_OK ) { fprintf( stderr, "FX3Dev::Init() flash completed!\nPlease wait for %d seconds\n", PAUSE_AFTER_FLASH_SECONDS ); for ( int i = 0; i < PAUSE_AFTER_FLASH_SECONDS * 2; i++ ) { #ifdef WIN32 Sleep( 500 ); #else usleep( 500000 ); #endif fprintf( stderr, "*" ); } fprintf( stderr, "\n" ); libusb_close(device_handle); device_handle = NULL; scan(); } else { fprintf( stderr, "FX3Dev::Init() __error__ flash failed, error %d %s\n", eres, fx3_get_error_string( eres ) ); return eres; } } else { fprintf( stderr, "FX3Dev::Init() no device without firmware found. Maybe already flashed?\n" ); } last_overflow_count = 0; } if ( endpoint_from_dev_num == endpoint_invalid ) { fprintf( stderr, "FX3Dev::Init() Device don't have endpoint with stream data to host!\n" ); return FX3_ERR_BAD_DEVICE; } fprintf( stderr, "FX3Dev::Init() Proceed to init flashed device (0x%04x)\n", DEV_PID_NO_FW_NEEDED ); device_handle = libusb_open_device_with_vid_pid( ctx, VENDOR_ID, DEV_PID_NO_FW_NEEDED ); if ( device_handle == NULL ) { fprintf( stderr, "FX3Dev::Init() __error__ no device with vid = 0x%04x and pid = 0x%04X found!\n", VENDOR_ID, DEV_PID_NO_FW_NEEDED ); return FX3_ERR_NO_DEVICE_FOUND; } if ( additionalFirmwareFileName != NULL ) { if ( additionalFirmwareFileName[ 0 ] != 0 ) { eres = loadAdditionalFirmware( additionalFirmwareFileName, 48 ); if ( eres != FX3_ERR_OK ) { fprintf( stderr, "FX3Dev::Init() __error__ loadAdditionalFirmware %d %s\n", eres, fx3_get_error_string( eres ) ); return eres; } else { fprintf( stderr, "loadAdditionalFirmware ok\n" ); } } } readFwVersion(); ires = libusb_claim_interface(device_handle, 0); if ( ires < 0 ) { fprintf( stderr, "FX3Dev::Init() __error__ libusb_claim_interface failed %d %s\n", ires, libusb_error_name( ires ) ); return FX3_ERR_USB_INIT_FAIL; } return FX3_ERR_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; }
// // main // ---- // int main(void) { libusb_device **devs; int r; // holds return codes ssize_t cnt; libusb_device* dev; libusb_device_handle* handle; int weigh_count = WEIGH_COUNT -1; // // We first try to init libusb. // r = libusb_init(NULL); // // If `libusb_init` errored, then we quit immediately. // if (r < 0) return r; #ifdef DEBUG libusb_set_debug(NULL, 3); #endif // // Next, we try to get a list of USB devices on this computer. cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) return (int) cnt; // // Once we have the list, we use **find_scale** to loop through and match // every device against the scales.h list. **find_scale** will return the // first device that matches, or 0 if none of them matched. // dev = find_scale(devs); if(dev == 0) { fprintf(stderr, "No USB scale found on this computer.\n"); return -1; } // // Once we have a pointer to the USB scale in question, we open it. // r = libusb_open(dev, &handle); // // Note that this requires that we have permission to access this device. // If you get the "permission denied" error, check your udev rules. // if(r < 0) { if(r == LIBUSB_ERROR_ACCESS) { fprintf(stderr, "Permission denied to scale.\n"); } else if(r == LIBUSB_ERROR_NO_DEVICE) { fprintf(stderr, "Scale has been disconnected.\n"); } return -1; } // // On Linux, we typically need to detach the kernel driver so that we can // handle this USB device. We are a userspace tool, after all. // #ifdef __linux__ libusb_detach_kernel_driver(handle, 0); #endif // // Finally, we can claim the interface to this device and begin I/O. // libusb_claim_interface(handle, 0); /* * Try to transfer data about status * * http://rowsandcolumns.blogspot.com/2011/02/read-from-magtek-card-swipe-reader-in.html */ unsigned char data[WEIGH_REPORT_SIZE]; int len; int scale_result = -1; // // For some reason, we get old data the first time, so let's just get that // out of the way now. It can't hurt to grab another packet from the scale. // r = libusb_interrupt_transfer( handle, //bmRequestType => direction: in, type: class, // recipient: interface LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, data, WEIGH_REPORT_SIZE, // length of data &len, 10000 //timeout => 10 sec ); // // We read data from the scale in an infinite loop, stopping when // **print_scale_data** tells us that it's successfully gotten the weight // from the scale, or if the scale or transmissions indicates an error. // for(;;) { // // A `libusb_interrupt_transfer` of 6 bytes from the scale is the // typical scale data packet, and the usage is laid out in *HID Point // of Sale Usage Tables*, version 1.02. // r = libusb_interrupt_transfer( handle, //bmRequestType => direction: in, type: class, // recipient: interface LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, data, WEIGH_REPORT_SIZE, // length of data &len, 10000 //timeout => 10 sec ); // // If the data transfer succeeded, then we pass along the data we // received tot **print_scale_data**. // if(r == 0) { #ifdef DEBUG int i; for(i = 0; i < WEIGH_REPORT_SIZE; i++) { printf("%x\n", data[i]); } #endif if (weigh_count < 1) { scale_result = print_scale_data(data); if(scale_result != 1) break; } weigh_count--; } else { fprintf(stderr, "Error in USB transfer\n"); scale_result = -1; break; } } // // At the end, we make sure that we reattach the kernel driver that we // detached earlier, close the handle to the device, free the device list // that we retrieved, and exit libusb. // #ifdef __linux__ libusb_attach_kernel_driver(handle, 0); #endif libusb_close(handle); libusb_free_device_list(devs, 1); libusb_exit(NULL); // // The return code will be 0 for success or -1 for errors (see // `libusb_init` above if it's neither 0 nor -1). // return scale_result; }
int open_sr16(void) { libusb_device **devs; int r; int rval = -1; ssize_t cnt; libusb_device *dev; struct libusb_device_descriptor desc; struct libusb_config_descriptor *config; int transfered; char buffer[256]; r = libusb_init(NULL ); if (r < 0) { return r; } libusb_set_debug(NULL, 4); cnt = libusb_get_device_list(NULL, &devs); if ( cnt < 0 ) { return (int) cnt; } // print_devs(devs); dev = find_dev(devs, 0x0763, 0x0150 ); if ( dev ) { libusb_get_device_descriptor(dev, &desc); r = libusb_open(dev, &sr16_devh ); /* printf("bLength:\t%d\n", desc.bLength ); printf("bcdUSB:\t%d\n", desc.bcdUSB ); printf("bDeviceClass:\t%d\n", desc.bDeviceClass ); printf("bDeviceSubClass:\t%d\n", desc.bDeviceSubClass ); printf("bDeviceProtocol:\t%d\n", desc.bDeviceProtocol ); printf("bMaxPacketSize0:\t%d\n", desc.bMaxPacketSize0 ); printf("idVendor:\t%d\n", desc.idVendor ); printf("idProduct:\t%d\n", desc.idProduct ); printf("bcdDevice:\t%d\n", desc.bcdDevice ); printf("iManufacturer:\t%d\n", desc.iManufacturer ); printf("iProduct:\t%d\n", desc.iProduct ); printf("iSerialNumber:\t%d\n", desc.iSerialNumber ); printf("bNumConfigurations:\t%d\n", desc.bNumConfigurations ); */ if ( r < 0 ) { perror("loibusb_open" ); } else { rval = 0; if ( desc.iManufacturer ) { r = libusb_get_string_descriptor_ascii(sr16_devh, desc.iManufacturer, buffer, 255 ); printf("Manufacturer:\t%s\n", buffer ); } if ( desc.iProduct ) { r = libusb_get_string_descriptor_ascii(sr16_devh, desc.iProduct, buffer, 255 ); printf("Manufacturer:\t%s\n", buffer ); } if ( desc.iSerialNumber ) { r = libusb_get_string_descriptor_ascii(sr16_devh, desc.iSerialNumber, buffer, 255 ); printf("Manufacturer:\t%s\n", buffer ); } // Get the configuration /* r = libusb_get_config_descriptor(dev, 0, &config ); if ( r ) { perror("libusb_get_config_descriptor" ); } else { printf("Config:\n" ); printf("bLength:\t%d\n", config->bLength ); printf("bDescriptorType:\t%d\n", config->bDescriptorType ); printf("wTotalLength:\t%d\n", config->wTotalLength ); printf("bNumInterfaces:\t%d\n", config->bNumInterfaces ); printf("bConfigurationValue:\t%d\n", config->bConfigurationValue ); printf("iConfiguration:\t%d\n", config->iConfiguration ); printf("bmAttributes:\t%d\n", config->bmAttributes ); printf("MaxPower:\t%d\n", config->MaxPower ); printf("interface:\t%p\n", config->interface ); printf("extra:\t%p\n", config->extra ); printf("extra_length:\t%d\n", config->extra_length ); libusb_free_config_descriptor(config ); } */ } } libusb_free_device_list(devs, 1); return rval; }
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; } ////////////////// }
std::unique_ptr<libusb_context, decltype(&libusb_exit)> usb_open() { libusb_context* p; usb_error::check(libusb_init(&p)); return std::unique_ptr<libusb_context, decltype(&libusb_exit)>(p, libusb_exit); }
static int lusb_probe(struct bladerf_devinfo_list *info_list) { int status, i, n; ssize_t count; libusb_device **list; struct bladerf_devinfo info; libusb_context *context; /* Initialize libusb for device tree walking */ status = libusb_init(&context); if (status) { log_error("Could not initialize libusb: %s\n", libusb_error_name(status)); goto lusb_probe_done; } count = libusb_get_device_list(context, &list); /* Iterate through all the USB devices */ for (i = 0, n = 0; i < count && status == 0; i++) { if (device_is_bladerf(list[i])) { log_verbose("Found bladeRF (based upon VID/PID)\n"); /* Open the USB device and get some information */ status = get_devinfo(list[i], &info); if (status) { /* We may not be able to open the device if another * driver (e.g., CyUSB3) is associated with it. Therefore, * just log to the debug level and carry on. */ status = 0; log_debug("Could not open bladeRF device: %s\n", libusb_error_name(status) ); } else { info.instance = n++; status = bladerf_devinfo_list_add(info_list, &info); if( status ) { log_error("Could not add device to list: %s\n", bladerf_strerror(status) ); } else { log_verbose("Added instance %d to device list\n", info.instance); } } } if (device_is_fx3_bootloader(list[i])) { status = get_devinfo(list[i], &info); if (status) { log_error("Could not open bladeRF device: %s\n", libusb_error_name(status) ); continue; } log_info("Found FX3 bootloader device on bus=%d addr=%d. This may " "be a bladeRF.\nUse the bladeRF-cli command \"recover" " %d %d <FX3 firmware>\" to boot the bladeRF firmware.\n", info.usb_bus, info.usb_addr, info.usb_bus, info.usb_addr); } } libusb_free_device_list(list, 1); libusb_exit(context); lusb_probe_done: return status; }
int main(int argc, char **argv) { const char *mode = "CGRAY"; int resolution = 100; if(argc > 1) { switch(*argv[1]) { case 'c': mode = "CGRAY"; break; case 'g': mode = "GRAY64"; break; case 't': mode = "TEXT"; break; case '-': mode = NULL; break; default: fprintf(stderr, "ERROR: unrecognised mode, " "should be one of [cgt]\n"); return 1; } } if(argc > 2) { resolution = atoi(argv[2]); if(resolution < 100 || resolution > 600 || resolution % 100) { fprintf(stderr, "ERROR: resolution must be a positive " "multiple of 100 no greater than 600\n"); return 1; } } libusb_context *context; libusb_init(&context); device_handle = libusb_open_device_with_vid_pid(context, VID, PID); if(!device_handle) { fprintf(stderr, "ERROR: Unable to find device " "(Vendor ID = %04x, Product ID = %04x)\n", VID, PID); return 1; } libusb_claim_interface(device_handle, 0); libusb_set_interface_alt_setting(device_handle, 0, 0); control_in_vendor_device(1, 2, 0, 255); /* returns 05 10 01 02 00 */ if(mode) { char *config = build_config( mode, MIN(resolution, 300), resolution, PAGE_WIDTH * MIN(resolution, 300)/100, PAGE_HEIGHT * resolution/100); send_config(config); free(config); } int page = 1; FILE *fp = NULL; int sleep_time = 0; while(1) { unsigned char buf[0x1000]; int num_bytes = bulk_read(4, buf, 0x1000); if(num_bytes) sleep_time = 0; if(num_bytes > 2) { if(!fp) { char fname[8]; snprintf(fname, 8, "%03d.raw", page); fprintf(stderr, "Opening '%s'...\n", fname); fp = fopen(fname, "wb"); } fwrite(buf, 1, num_bytes, fp); } else if(num_bytes == 0 && sleep_time < 10) { #ifdef DEBUG fprintf(stderr, "Sleeping\n"); #endif sleep_time++; usleep(200 * 1000); } else if(num_bytes == 2 && buf[0] == 0xc2 && buf[1] == 0x00) { fprintf(stderr, "ERROR: Nothing to scan\n"); break; } else if(num_bytes == 2 && buf[0] == 0xc3 && buf[1] == 0x00) { fprintf(stderr, "ERROR: Paper jam\n"); break; } else if(num_bytes == 1 && buf[0] == 0x80) { fprintf(stderr, "No more pages\n"); break; } else if((num_bytes == 1 && buf[0] == 0x81) || sleep_time >= 10) { fprintf(stderr, "Feeding in another page"); if(sleep_time >= 10) fprintf(stderr, " (timeout)"); fprintf(stderr, "\n"); fclose(fp); fp = NULL; send_config(""); page++; sleep_time = 0; } else if(num_bytes == 1 && buf[0] == 0xc3) { fprintf(stderr, "Paper jam\n"); break; } else if(num_bytes == 1 && buf[0] == 0xc4) { fprintf(stderr, "Scan aborted\n"); break; } else { fprintf(stderr, "Received unknown data: %02x", buf[0]); if(num_bytes == 2) fprintf(stderr, " %02x", buf[1]); fprintf(stderr, "\n"); break; } } if(fp) fclose(fp); control_in_vendor_device(2, 2, 0, 255); /* returns 05 10 02 02 00 */ libusb_release_interface(device_handle, 0); libusb_close(device_handle); libusb_exit(context); return 0; }
int main (int argc, char **argv) { GOptionContext *context; GError *error = NULL; libusb_device **list; ssize_t num_devices, i; context = g_option_context_new ("- Manage Sixaxis PS3 controllers"); g_option_context_add_main_entries (context, options, NULL); if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) { g_warning ("Couldn't parse command-line options: %s", error->message); return 1; } /* Check that the passed bdaddr is correct */ if (option_master != NULL && strcmp (option_master, "auto") != 0) { //FIXME check bdaddr } libusb_init (NULL); /* Find device(s) */ num_devices = libusb_get_device_list (NULL, &list); if (num_devices < 0) { g_warning ("libusb_get_device_list failed"); return 1; } for (i = 0; i < num_devices; i++) { struct libusb_config_descriptor *cfg; libusb_device *dev = list[i]; struct libusb_device_descriptor desc; guint8 j; if (libusb_get_device_descriptor (dev, &desc) < 0) { g_warning ("libusb_get_device_descriptor failed"); continue; } /* Here we check for the supported devices */ if (desc.idVendor != VENDOR || desc.idProduct != PRODUCT) continue; /* Look for the interface number that interests us */ for (j = 0; j < desc.bNumConfigurations; j++) { struct libusb_config_descriptor *config; guint8 k; libusb_get_config_descriptor (dev, j, &config); for (k = 0; k < config->bNumInterfaces; k++) { const struct libusb_interface *itf = &config->interface[k]; int l; for (l = 0; l < itf->num_altsetting ; l++) { struct libusb_interface_descriptor alt; alt = itf->altsetting[l]; if (alt.bInterfaceClass == 3) { handle_device (dev, cfg, l, &alt); } } } } } return 0; }
void irecv_init() { #ifndef WIN32 libusb_init(&libirecovery_context); #endif }
/** * 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; }
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; }
int main(void) { struct sigaction sigact; int r = 1; r = libusb_init(NULL); if (r < 0) { fprintf(stderr, "failed to initialise libusb\n"); exit(1); } r = find_dpfp_device(); if (r < 0) { fprintf(stderr, "Could not find/open device\n"); goto out; } r = libusb_claim_interface(devh, 0); if (r < 0) { fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r)); goto out; } printf("claimed interface\n"); r = print_f0_data(); if (r < 0) goto out_release; r = do_init(); if (r < 0) goto out_deinit; /* async from here onwards */ sigact.sa_handler = sighandler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL); if (r) goto out_deinit; r = alloc_transfers(); if (r < 0) { request_exit(1); pthread_join(poll_thread, NULL); goto out_deinit; } r = init_capture(); if (r < 0) { request_exit(1); pthread_join(poll_thread, NULL); goto out_deinit; } while (!do_exit) { pthread_mutex_lock(&exit_cond_lock); pthread_cond_wait(&exit_cond, &exit_cond_lock); pthread_mutex_unlock(&exit_cond_lock); } printf("shutting down...\n"); pthread_join(poll_thread, NULL); r = libusb_cancel_transfer(irq_transfer); if (r < 0) { request_exit(1); goto out_deinit; } r = libusb_cancel_transfer(img_transfer); if (r < 0) { request_exit(1); goto out_deinit; } while (img_transfer || irq_transfer) if (libusb_handle_events(NULL) < 0) break; if (do_exit == 1) r = 0; else r = 1; out_deinit: libusb_free_transfer(img_transfer); libusb_free_transfer(irq_transfer); set_mode(0); set_hwstat(0x80); out_release: libusb_release_interface(devh, 0); out: libusb_close(devh); libusb_exit(NULL); return r >= 0 ? r : -r; }
struct launchpad* lp_register() { struct launchpad *lp; //build the struct lp = malloc(sizeof(struct launchpad)); if (lp == NULL) { fprintf(stderr,"Unable to allocate memory\n"); return NULL; } //initialize usb if(libusb_init(NULL)!=0){ fprintf(stderr,"Unable to initialize usb\n"); return NULL; } else { printf("usb initialized\n"); } //find the device lp->device = libusb_open_device_with_vid_pid(NULL, ID_VENDOR, ID_PRODUCT); if (lp->device == NULL) { fprintf(stderr,"Unable to find the launchpad\n"); return NULL; } else { printf("launchpad found\n"); } //claim the device if(libusb_claim_interface(lp->device, 0) != 0) { fprintf(stderr,"Unable to claim the launchpad\n"); return NULL; } else { printf("launchpad claimed\n"); } //allocate input buffer lp->rdata = malloc(sizeof(unsigned char)*MAX_PACKET_SIZE); if (lp->rdata == NULL) { fprintf(stderr,"could not allocate input buffer\n"); return NULL; } //allocate output buffer lp->tdata = malloc(sizeof(unsigned char)*MAX_PACKET_SIZE); if (lp->tdata == NULL) { fprintf(stderr,"could not allocate output buffer\n"); return NULL; } // initialize the protocol's state lp->event[0] = NOTE; lp->parse_at = 0; lp->received = 0; // reset launchpad lp_reset(lp); return lp; }
int iusb_init (byte ep_in_addr, byte ep_out_addr) { logd ("ep_in_addr: %d ep_out_addr: %d", ep_in_addr, ep_out_addr); iusb_ep_in = -1; iusb_ep_out = -1; iusb_best_device = NULL; iusb_best_vendor = 0; int usb_err = libusb_init (NULL); if (usb_err < 0) { loge ("Error libusb_init usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); return (-1); } logd ("OK libusb_init usb_err: %d", usb_err); libusb_set_debug (NULL, LIBUSB_LOG_LEVEL_WARNING); // DEBUG);// logd ("Done libusb_set_debug"); libusb_device ** list; usb_err = libusb_get_device_list (NULL, & list); // Get list of USB devices if (usb_err < 0) { loge ("Error libusb_get_device_list cnt: %d", usb_err, iusb_error_get (usb_err)); return (-1); } ssize_t cnt = usb_err; logd ("Done libusb_get_device_list cnt: %d", cnt); int idx = 0; int iusb_best_vendor_priority = 0; libusb_device * device; for (idx = 0; idx < cnt; idx ++) { // For all USB devices... device = list [idx]; int vendor = iusb_vendor_get (device); //int product = product_get (device); logd ("iusb_vendor_get vendor: 0x%04x device: %p", vendor, device); if (vendor) { int vendor_priority = iusb_vendor_priority_get (vendor); //if (iusb_best_vendor_priority < vendor_priority) { // For first if (iusb_best_vendor_priority <= vendor_priority) { // For last iusb_best_vendor_priority = vendor_priority; iusb_best_vendor = vendor; iusb_best_device = device; strncpy (iusb_best_man, iusb_curr_man, sizeof (iusb_best_man)); strncpy (iusb_best_pro, iusb_curr_pro, sizeof (iusb_best_pro)); } } } if (iusb_best_vendor == 0 || iusb_best_device == NULL) { // If no vendor... loge ("Error device not found iusb_best_vendor: 0x%04x iusb_best_device: %p", iusb_best_vendor, iusb_best_device); libusb_free_device_list (list, 1); // Free device list now that we are finished with it return (-1); } logd ("Device found iusb_best_vendor: 0x%04x iusb_best_device: 0x%04x iusb_best_man: \"%s\" iusb_best_pro: \"%s\"", iusb_best_vendor, iusb_best_device, iusb_best_man, iusb_best_pro); //usb_perms_set (); // Setup USB permissions, where needed if (file_get ("/sdcard/suc")) { // Set Permission w/ SU: int ret = system ("su -c chmod -R 777 /dev/bus 1>/dev/null 2>/dev/null"); // !! Binaries like ssd that write to stdout cause C system() to crash ! logd ("iusb_usb_init system() ret: %d", ret); } usb_err = libusb_open (iusb_best_device, & iusb_dev_hndl); logd ("libusb_open usb_err: %d (%s) iusb_dev_hndl: %p list: %p", usb_err, iusb_error_get (usb_err), iusb_dev_hndl, list); libusb_free_device_list (list, 1); // Free device list now that we are finished with it if (usb_err != 0) { loge ("Error libusb_open usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); return (-1); } logd ("Done libusb_open iusb_dev_hndl: %p", iusb_dev_hndl); /* usb_err = libusb_set_auto_detach_kernel_driver (iusb_dev_hndl, 1); if (usb_err) loge ("Done libusb_set_auto_detach_kernel_driver usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); else logd ("Done libusb_set_auto_detach_kernel_driver usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); //*/ usb_err = libusb_claim_interface (iusb_dev_hndl, 0); if (usb_err) loge ("Error libusb_claim_interface usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); else logd ("OK libusb_claim_interface usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); struct libusb_config_descriptor * config = NULL; usb_err = libusb_get_config_descriptor (iusb_best_device, 0, & config); if (usb_err != 0) { logd ("Expected Error libusb_get_config_descriptor usb_err: %d (%s)", usb_err, iusb_error_get (usb_err)); // !! ???? Normal error now ??? //return (-1); iusb_ep_in = ep_in_addr; //129; // Set input endpoint iusb_ep_out = ep_out_addr;// 2; // Set output endpoint return (0); } int num_int = config->bNumInterfaces; // Get number of interfaces logd ("Done get_config_descriptor config: %p num_int: %d", config, num_int); const struct libusb_interface * inter; const struct libusb_interface_descriptor * interdesc; const struct libusb_endpoint_descriptor * epdesc; for (idx = 0; idx < num_int; idx ++) { // For all interfaces... inter = & config->interface [idx]; int num_altsetting = inter->num_altsetting; logd ("num_altsetting: %d", num_altsetting); int j = 0; for (j = 0; j < inter->num_altsetting; j ++) { // For all alternate settings... interdesc = & inter->altsetting [j]; int num_int = interdesc->bInterfaceNumber; logd ("num_int: %d", num_int); int num_eps = interdesc->bNumEndpoints; logd ("num_eps: %d", num_eps); int k = 0; for (k = 0; k < num_eps; k ++) { // For all endpoints... epdesc = & interdesc->endpoint [k]; if (epdesc->bDescriptorType == LIBUSB_DT_ENDPOINT) { // 5 if ((epdesc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) { int ep_add = epdesc->bEndpointAddress; if (ep_add & LIBUSB_ENDPOINT_DIR_MASK) { if (iusb_ep_in < 0) { iusb_ep_in = ep_add; // Set input endpoint logd ("iusb_ep_in: 0x%02x", iusb_ep_in); } } else { if (iusb_ep_out < 0) { iusb_ep_out = ep_add; // Set output endpoint logd ("iusb_ep_out: 0x%02x", iusb_ep_out); } } if (iusb_ep_in > 0 && iusb_ep_out > 0) { // If we have both endpoints now... libusb_free_config_descriptor (config); if ((ep_in_addr != -1 || ep_out_addr != -1) && (iusb_ep_in != ep_in_addr || iusb_ep_out != ep_out_addr)) { loge ("MISMATCH Done endpoint search iusb_ep_in: 0x%02x iusb_ep_out: 0x%02x", iusb_ep_in, iusb_ep_out); // Favor libusb over passed in } else logd ("Match Done endpoint search iusb_ep_in: 0x%02x iusb_ep_out: 0x%02x", iusb_ep_in, iusb_ep_out); return (0); } } } } } } // Else if DON'T have both endpoints... loge ("Error in and/or out endpoints unknown iusb_ep_in: 0x%02x iusb_ep_out: 0x%02x", iusb_ep_in, iusb_ep_out); libusb_free_config_descriptor (config); if (iusb_ep_in == -1) iusb_ep_in = ep_in_addr; //129; // Set input endpoint if (iusb_ep_out == -1) iusb_ep_out = ep_out_addr;// 2; // Set output endpoint if (iusb_ep_in == -1 || iusb_ep_out == -1) return (-1); loge ("!!!!! FIXED EP's !!!!!"); return (0); }
/** @brief detect devices based on usb pid / vid. * @return list with usb VID / PID values. */ QMap<uint32_t, QString> System::listUsbDevices(void) { QMap<uint32_t, QString> usbids; // usb pid detection LOG_INFO() << "Searching for USB devices"; #if defined(Q_OS_LINUX) #if defined(LIBUSB1) libusb_device **devs; if(libusb_init(NULL) != 0) { LOG_ERROR() << "Initializing libusb-1 failed."; return usbids; } if(libusb_get_device_list(NULL, &devs) < 1) { LOG_ERROR() << "Error getting device list."; return usbids; } libusb_device *dev; int i = 0; while((dev = devs[i++]) != NULL) { QString name; unsigned char buf[256]; uint32_t id; struct libusb_device_descriptor descriptor; if(libusb_get_device_descriptor(dev, &descriptor) == 0) { id = descriptor.idVendor << 16 | descriptor.idProduct; libusb_device_handle *dh; if(libusb_open(dev, &dh) == 0) { libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256); name += QString::fromLatin1((char*)buf) + " "; libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256); name += QString::fromLatin1((char*)buf); libusb_close(dh); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insertMulti(id, name); LOG_INFO("USB: 0x%08x, %s", id, name.toLocal8Bit().data()); } } } libusb_free_device_list(devs, 1); libusb_exit(NULL); #else usb_init(); usb_find_busses(); usb_find_devices(); struct usb_bus *b; b = usb_busses; while(b) { if(b->devices) { struct usb_device *u; u = b->devices; while(u) { uint32_t id; id = u->descriptor.idVendor << 16 | u->descriptor.idProduct; // get identification strings usb_dev_handle *dev; QString name; char string[256]; int res; dev = usb_open(u); if(dev) { if(u->descriptor.iManufacturer) { res = usb_get_string_simple(dev, u->descriptor.iManufacturer, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string) + " "; } if(u->descriptor.iProduct) { res = usb_get_string_simple(dev, u->descriptor.iProduct, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string); } usb_close(dev); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insertMulti(id, name); LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name; } u = u->next; } } b = b->next; } #endif #endif #if defined(Q_OS_MACX) kern_return_t result = KERN_FAILURE; CFMutableDictionaryRef usb_matching_dictionary; io_iterator_t usb_iterator = IO_OBJECT_NULL; usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName); result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary, &usb_iterator); if(result) { LOG_ERROR() << "USB: IOKit: Could not get matching services."; return usbids; } io_object_t usbCurrentObj; while((usbCurrentObj = IOIteratorNext(usb_iterator))) { uint32_t id; QString name; /* get vendor ID */ CFTypeRef vidref = NULL; int vid = 0; vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid); CFRelease(vidref); /* get product ID */ CFTypeRef pidref = NULL; int pid = 0; pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid); CFRelease(pidref); id = vid << 16 | pid; /* get product vendor */ char vendor_buf[256]; CFIndex vendor_buflen = 256; CFTypeRef vendor_name_ref = NULL; vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Vendor Name"), kCFAllocatorDefault, 0); if(vendor_name_ref != NULL) { CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(vendor_buf) + " "; CFRelease(vendor_name_ref); } else { name += QObject::tr("(unknown vendor name) "); } /* get product name */ char product_buf[256]; CFIndex product_buflen = 256; CFTypeRef product_name_ref = NULL; product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Product Name"), kCFAllocatorDefault, 0); if(product_name_ref != NULL) { CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(product_buf); CFRelease(product_name_ref); } else { name += QObject::tr("(unknown product name)"); } if(id) { usbids.insertMulti(id, name); LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name; } } IOObjectRelease(usb_iterator); #endif #if defined(Q_OS_WIN32) HDEVINFO deviceInfo; SP_DEVINFO_DATA infoData; DWORD i; // Iterate over all devices // by doing it this way it's unneccessary to use GUIDs which might be not // present in current MinGW. It also seemed to be more reliably than using // a GUID. // See KB259695 for an example. deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); infoData.cbSize = sizeof(SP_DEVINFO_DATA); for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) { DWORD data; LPTSTR buffer = NULL; DWORD buffersize = 0; QString description; // get device desriptor first // for some reason not doing so results in bad things (tm) while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } description = QString::fromWCharArray(buffer); // now get the hardware id, which contains PID and VID. while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } unsigned int vid, pid; // convert buffer text to upper case to avoid depending on the case of // the keys (W7 uses different casing than XP at least). int len = _tcslen(buffer); while(len--) buffer[len] = _totupper(buffer[len]); if(_stscanf(buffer, _TEXT("USB\\VID_%x&PID_%x"), &vid, &pid) == 2) { uint32_t id; id = vid << 16 | pid; usbids.insert(id, description); LOG_INFO("USB VID: %04x, PID: %04x", vid, pid); } if(buffer) free(buffer); } SetupDiDestroyDeviceInfoList(deviceInfo); #endif return usbids; }