[sane-devel] Libusb - reads and writes?

René Kjellerup webmaster at keenan.dk
Fri Dec 8 23:46:02 CET 2006


> -----Original Message-----
> From: m. allan noah
> Sent: 8. december 2006 22:07
> To: René Kjellerup
> Cc: sane-devel at lists.alioth.debian.org
> Subject: Re: [sane-devel] Libusb - reads and writes?
> 
> On Fri, 8 Dec 2006, René Kjellerup wrote:
> 
> >
> >
> > On Fri, 8 Dec 2006, m. allan noah
> >
> >> On Thu, 7 Dec 2006, René Kjellerup wrote:
> >>
> >>> So the primary question is, which endpoint does one write to, and 
> >>> which does one read from?
> >>
> >> the in/out identifiers are written from the perspective of
> the host, not
> > the device. so you read in and write out. just as a check,
> the IN endpoint
> > will > have its high bit set (0x80).
> >>
> > Thanks
> >
> >> it is not unusual to get timeout errors and other
> weirdness on your first
> > command to the device, some fujitsu scanners require you to
> call TEST UNIT
> > READY several times with a really short timeout and ignore
> the errors before
> > they will play.
> >
> > :) well being used to TCP connections, I'd never expected
> USB communication
> > to be so inconsistent.
> >
> > Should I fill the scanner's endpoint buffer before reading? 
> Or will a few
> > one byte writes do?
> > Anyone know how Canon's scanners like it? [:)]
> 
> haha- oh, you're serious? you have to write a properly formatted 
> command before you read. sending single bytes is a great way to 
> confuse the scanner.

Indeed I was serious. I was writing a single byte (in range 0x00-0x0f
approx.) to the scanner and I've even tried with 4 random bytes. Then tried
to Read up to the max of that endpoint (either 512 or 1 byte) (for those
inclined see the appended source code)

> 
> get a trace on windows using benoit's usbsniffer, and work from that.
> 
> post links to the traces on this list if you need some help.

Well I need the help in generating the traces, as the only windows machine I
own is a Windows x64 Pro, and there's no drivers for it.
Vmware doesn't help :( And no I wont setup a multi boot with 2 windowses.

> 
> allan
> 
> >
> > Best regards
> > René Kjellerup
> > -- as life grows older, I gain experience.
> >
> >>
> >> allan
> >>
> >> --
> >> "so don't tell us it can't be done, putting down what you
> don't know.
> >> money isn't our god, integrity will free our souls" - Max Cavalera
> >
> >
> 
> --
> "so don't tell us it can't be done, putting down what you don't know.
> money isn't our god, integrity will free our souls" - Max Cavalera
> 
-------------- next part --------------
#include <usb.h>

// gets a pointer to the usb device
struct usb_device* get_device(u_int16_t v, u_int16_t p, struct usb_bus *b);
// the function to handle the communication with the scanner
void device_function(struct usb_dev_handle* dhnd, struct usb_device*,int);

int 
main(int argc, char *argv[])
{
    struct usb_bus *busses;
    struct usb_device *dev;
    u_int16_t vend = 0x04a9; // Canon
    u_int16_t prod = 0x221b; // CanoScan 4200F
    int index = 0;
    if(argc > 1) index = atoi(argv[1]); 
    usb_init();
    usb_find_busses();
    usb_find_devices();
    busses = usb_get_busses();
    dev = get_device(vend,prod,busses);
    if(dev == 0) {
		printf("CanoScan 4200F not found\n");
		return;
    }
    device_function(usb_open(dev),dev,index);
    return 0;
}

struct usb_device*
get_device(u_int16_t v, u_int16_t p, struct usb_bus *b)
{
    struct usb_bus *bus;
    struct usb_device *dev;
    for(bus = b; bus; bus = bus->next)
    {
	for(dev = bus->devices; dev; dev = dev->next)
	{
	    if(dev->descriptor.idVendor == v)
		if(dev->descriptor.idProduct == p)
		    return dev;
	}
    }
    return (0);
}

/* this is a mess and I won't bother explaining why it looks as it does.
 * Sufficiently to say that trial/error has something to do with it.
 */
void
device_function(struct usb_dev_handle *dhnd, struct usb_device* dev, int idx)
{
    struct usb_endpoint_descriptor *endpoints, *endp;
    char buf[520], irq;
    char *ii;
    int i;
    bzero(buf,520);
    if(dhnd) {
	i = usb_set_configuration(dhnd,dev->config->bConfigurationValue);
	if(i<0) printf("set config failed\n");
	endpoints = dev->config->interface->altsetting->endpoint;
	i = usb_claim_interface(dhnd,0);
	if(i < 0) { printf("error no: %d\n",i); goto endf; }
	i = usb_set_altinterface(dhnd,dev->config->interface->altsetting->bAlternateSetting);
	printf("Interface Claimed\n");
	irq = idx;
	ii = (char*)&idx;
	buf[0] = ii[0];
	buf[1] = ii[1];
	buf[2] = ii[2];
	buf[3] = ii[3];
	
	printf("0x%02x 0x%02x 0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
	i = usb_bulk_write(dhnd,1,buf,4,15);
	if(i<0){ 
	 printf("bulk write failed %d\n",i); 
	 usb_release_interface(dhnd,0); goto endf; 
	}
	bzero(buf,520);
	i = usb_interrupt_read(dhnd,3,buf,1,0);
	if(i<0) printf("read failed %d\n",i);
	usb_release_interface(dhnd,0);
	printf("Interface Released\n");
	printf("out: '%s'\n",buf);
endf:
        usb_close(dhnd);
	return;
    }
    printf("No device found\n");
}


More information about the sane-devel mailing list