Skip to content

Instantly share code, notes, and snippets.

@pamaury
Created June 1, 2016 23:23
Show Gist options
  • Save pamaury/6cea172644423f6bc7b5faab163ab712 to your computer and use it in GitHub Desktop.
Save pamaury/6cea172644423f6bc7b5faab163ab712 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <libusb.h>
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
#include "usb_test_def.h"
libusb_context *ctx;
#define MIN(a,b) ((a)<(b)?(a):(b));
uint64_t get_time_stamp()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}
void main_loop(libusb_device_handle *handle)
{
libusb_device *device=libusb_get_device(handle);
printf("device found at %d:%d\n",
libusb_get_bus_number(device),
libusb_get_device_address(device));
struct libusb_device_descriptor dev_desc;
int res=libusb_get_device_descriptor(device,&dev_desc);
assert(res==0);
int config_id;
res=libusb_get_configuration(handle,&config_id);
assert(res==0);
struct libusb_config_descriptor *config;
res=libusb_get_active_config_descriptor(device,&config);
assert(res==0);
printf("configuration: %d\n",config_id);
printf("interfaces: %d\n",config->bNumInterfaces);
int test_interface=-1;
for(int i=0;i<config->bNumInterfaces;i++)
{
printf("interface %d: alternative settings: %d\n",i,config->interface[i].num_altsetting);
for(int j=0;j<config->interface[i].num_altsetting;j++)
{
printf("interface %d,%d: class=%#x\n",i,j,config->interface[i].altsetting[j].bInterfaceClass);
printf("interface %d,%d: subclass=%#x\n",i,j,config->interface[i].altsetting[j].bInterfaceSubClass);
if(config->interface[i].altsetting[j].bInterfaceClass==0xff &&
config->interface[i].altsetting[j].bInterfaceSubClass==0xff &&
config->interface[i].altsetting[j].bInterfaceProtocol==0)
test_interface=i;
}
}
printf("test interface: %d\n",test_interface);
const struct libusb_interface_descriptor *interface=&config->interface[test_interface].altsetting[0];
res=libusb_claim_interface(handle,test_interface);
if(res!=0)
{
printf("claim error: %d\n",res);
assert(false);
}
printf("endpoints: %d\n",interface->bNumEndpoints);
int bulk_in_ep=-1;
int bulk_out_ep=-1;
for(int i=0;i<interface->bNumEndpoints;i++)
{
printf("endpoint %d: addr=%d dir=%d type=%d\n",i,
interface->endpoint[i].bEndpointAddress&0x7,interface->endpoint[i].bEndpointAddress>>7,
interface->endpoint[i].bmAttributes&0x3);
if((interface->endpoint[i].bEndpointAddress&LIBUSB_ENDPOINT_DIR_MASK)==LIBUSB_ENDPOINT_IN &&
(interface->endpoint[i].bmAttributes&LIBUSB_TRANSFER_TYPE_MASK)==LIBUSB_TRANSFER_TYPE_BULK)
bulk_in_ep=interface->endpoint[i].bEndpointAddress;
else if((interface->endpoint[i].bEndpointAddress&LIBUSB_ENDPOINT_DIR_MASK)==LIBUSB_ENDPOINT_OUT &&
(interface->endpoint[i].bmAttributes&LIBUSB_TRANSFER_TYPE_MASK)==LIBUSB_TRANSFER_TYPE_BULK)
bulk_out_ep=interface->endpoint[i].bEndpointAddress;
}
printf("bulk IN: %#02x\n", bulk_in_ep);
printf("bulk OUT: %#02x\n", bulk_out_ep);
printf("Starting write test...\n");
#define BUF_SIZE 512 * 1024
#define REPEAT_COUNT 100
void *buffer = malloc(BUF_SIZE);
memset(buffer, 0, BUF_SIZE);
uint64_t start_time = get_time_stamp();
bool failure = false;
for(int i = 0; i < REPEAT_COUNT; i++)
{
int xfered;
int ret = libusb_bulk_transfer(handle, bulk_out_ep, buffer, BUF_SIZE, &xfered, 1000);
if(ret != 0)
{
printf("usb error: %d\n", ret);
failure = true;
break;
}
if(xfered != BUF_SIZE)
{
printf("short transfer: %d < %d\n", xfered, BUF_SIZE);
failure = true;
break;
}
printf(".");
}
if(!failure)
{
uint64_t end_time = get_time_stamp();
unsigned count = REPEAT_COUNT * BUF_SIZE;
unsigned time_diff = (end_time - start_time) / 1000;
printf("\n");
printf("Wrote %u bytes in %u ms. Average speed is %u kB/s.\n",
count, time_diff, count / time_diff);
}
libusb_release_interface(handle,test_interface);
}
bool is_sansa(libusb_device *dev)
{
struct libusb_device_descriptor dev_desc;
int res=libusb_get_device_descriptor(dev,&dev_desc);
assert(res==0);
return dev_desc.idVendor==0x0781 && dev_desc.idProduct==0x74e1;
}
int main(int argc,char **argv)
{
(void)argc;
(void)argv;
assert(libusb_init(&ctx)==0);
libusb_set_debug(NULL,3);
libusb_device **device_list;
ssize_t list_size=libusb_get_device_list(NULL,&device_list);
assert(list_size>=0);
libusb_device *found = NULL;
for(ssize_t i=0;i<list_size;i++)
{
if(is_sansa(device_list[i]))
found=device_list[i];
}
if(found)
{
libusb_device_handle *handle;
int err=libusb_open(found,&handle);
assert(err==0);
main_loop(handle);
libusb_close(handle);
}
else
printf("No device found\n");
libusb_free_device_list(device_list,1);
libusb_exit(NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment