libusb driver question: can't write to endpoint

Phil Dibowitz <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
So I sat down to start seeing if I could write the aforementioned driver for
the Logitech Harmony remote using libusb. After reading the docs, I whipped
out the following test code (ok, its mostly a copy and paste of the docs,
but that's OK) which binds to the interface and attempts to do an interrupt
transfer to the endpoint.

But I get: "error submitting URB: Bad address". I've attached the (very
ugly) code below, but I don't think it's a coding error as much as a not
understanding error.

Looking at lsusb, the device has one Configuration with bConfigurationValue
1, and one Interface with bInterfaceNumber 0.

Under this interface, it has two endpoints, 0x81, "EP 1 IN", and 0x02, "EP 1
OUT", which I believe, from looking at USB Snoopy dumps, are IN ==>
device-to-host, and OUT ==> host-to-device. But I've tried my code using
both endpoints, and get the same error each time.

The USBSnoopy log shows from windows shows a very simple setup:
SELECT_CONFIGURATION, CLASS_INTERFACE, GET_DESCRIPTOR_FROM_INTERFACE, and
then a ton of BULK_OR_INTERRUPT_TRANSFERs. lsusb shows that the devices or
of transfer type Interrupt.

Since all the software does is write a blob to the remote (which, after
looking, turns out to just be XML), this all seems straight forward. It
doesn't seem like I have to do any special setup...

The USBSnoopy logs show it writing 64 bytes at a time, so that's what I
write in my code.

-- 
Phil Dibowitz                             [email protected]
Open Source software and tech docs        Insanity Palace of Metallica
http://www.phildev.net/                   http://www.ipom.com/

"Never write it in C if you can do it in 'awk';
 Never do it in 'awk' if 'sed' can handle it;
 Never use 'sed' when 'tr' can do the job;
 Never invoke 'tr' when 'cat' is sufficient;
 Avoid using 'cat' whenever possible" -- Taylor's Laws of Programming

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
harmony.c (text/x-csrc, 1.9 KB)
#include <stdio.h>
#include <errno.h>
#include <stdio.h>
#include <usb.h>

#define LH_VENDOR_ID 0x046d
#define LH_PRODUCT_ID 0xc110
#define DATAFILE "/tmp/Connectivity.EZHex"
#define SIZE 64
#define IN_EP 0x81
#define OUT_EP 0x02

void write_data(usb_dev_handle *udev);

int main(int argc, char *argv[])
{
	struct usb_bus *busses, *bus;
	int retval = 0;
    
	usb_init();
	usb_find_busses();
	usb_find_devices();
    
	busses = usb_get_busses();

	/* loop through busses... */
	for (bus = busses; bus; bus = bus->next) {
		struct usb_device *dev;

		/* loop through devices on bus ...*/
		for (dev = bus->devices; dev; dev = dev->next) {
			usb_dev_handle *udev;
			if (dev->descriptor.idVendor == LH_VENDOR_ID
			    && dev->descriptor.idProduct == LH_PRODUCT_ID) {
				printf("Found remote\n");
				udev = usb_open(dev);
				if (!udev) {
					printf("Failed to open device\n");
					exit(1);
				}
				printf("Opened device\n");
				/*
 				 * Choose the first configuration (1)
 				 */
				if (usb_set_configuration(udev,1) < 0) {
					printf("Failed to set conf: %s\n",
						usb_strerror());
					exit(1);
				}
				printf("Set conf\n");
				/*
 				 * Choose the first interface (0)
 				 */
				retval = usb_claim_interface(udev,1);
				if (retval == -EBUSY) {
					printf("Interface busy\n");
					exit(1);
				}
				printf("Claimed device\n");
				write_data(udev);
				usb_release_interface(udev,0);
				printf("released device\n");
				usb_close(udev);
				printf("closed device\n");
				exit(0);
			} else {
				printf("Found another device\n");
				continue;
			}
		}
	}
	exit(1);
}

void write_data(usb_dev_handle* udev)
{
	printf("writing data...\n");
	char buf[SIZE];
	int bytes = 0;
	FILE *fh;
	fh = fopen(DATAFILE, "r");
	int i = 0;
	while (bytes = read((int)fh, buf, SIZE)) {
		printf("writing %d bytes (%d)\n",SIZE,++i);
		if (usb_interrupt_write(udev, OUT_EP, buf, bytes, 2) < 0) {
			printf("Write failed: %s\n", usb_strerror());
			return;
		}
	}
	fclose(fh);
}
signature.asc (application/pgp-signature, 252 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF80G9N5XoxaHnMrsRArgNAKCdqlvMFFYrorBjK9UeVe4YtQPi3ACeMX5t
FzP9IdV8mNu9NOlSmndeUB8=
=xJB6
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.