-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- -- Hallo to all,
I am sniffing the USB bus under windows i had been able to collect some 
informations, i want to share some ideas and get your suggestions.

The windows driver start its comunications with the mp3 player sending this 
two commands, the first is:
03 00 00
device response is:
02 00 00 00 00 00 01 01 00 01 00 00 01 01 00 5b 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
(64bytes)

The second command is:
06 01 00 00 00 00
device response is:
00 00 00 ec 76 ff 01 01 00 01 00 00 01 01 00 5b
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

So i decided to issue the same commands under linux using a skeleton driver i 
have written (a char device which send and receive data from the device) and 
i have got a different answer! which is:
02 00 00 00 00 00 01 01 00 01 00 00 01 01 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
and
00 00 00 ec 76 ff 01 01 00 01 00 00 01 01 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Is there any reason for this different behaviour in Linux? 
I run every test after unplugging/turning off/turning on/puggling again the 
device...
Please note before receiving the data from the device i always memset to 0 the 
entire receive buffer, so maybe the difference between all those "ff" and the 
"00" is a shorted data transferred form the device.

If this is the case, i have a question to ask you: how can i konw how much 
data will the device send me? Or how can i know how much data the device 
actually sent me? (i already consider urbp->actual_length which says 0x40 
bytes after the usb_submit_urb)

I attach the source of the kernel driver, please note it is only test code not 
meant for speed... also it will never work in case of concurrent access.

the reader1.c attachment is an example of how i send commands to the device 
from user land.

If you can help me, thanks.


! 
 Willy Gardiol - [EMAIL PROTECTED]
 gardiol.eu.org
 Use linux for your freedom.

   "La GPL e il modello open source inpediscono
    l'accaparramento delle tecnologie e assicurano
    che chiunque sia interessato a un progetto o
    a una tecnologia non possa essere escluso
    dai suoi sviluppi"

      Linus Torvalds

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE/chrmQ9qolN/zUk4RAiX0AJ9MnBj7khv8626siqUyWOcCczd1/gCdEuNi
nwCqzEQRIpyex7hkuwQjIYk=
=OkAG
-----END PGP SIGNATURE-----
#include "napa-pa1x.h"

struct usb_device* napa;

static struct usb_device_id napa_ids [] = {
	{ USB_DEVICE(0x066f, 0x004b) },
	{ USB_DEVICE(0x066f, 0x3400) },
	{ USB_DEVICE(0x066f, 0x9999) },
	{ }						/* Terminating entry */
};

void napa_bulk_complete( struct urb *urbp )
{
	wait_queue_head_t *s = urbp->context;
	wake_up(s);
}

int napa_bulk_send( struct usb_device* dev, char* buf, int len  )
{
	struct urb* urbp = usb_alloc_urb(0);
	char *buffer = (char*)kmalloc( len+1, GFP_KERNEL);
	int i;
	wait_queue_head_t coda;
	init_waitqueue_head( &coda );

	for ( i = 0 ; i < len; i++ )
		buffer[i] = buf[i];

	FILL_BULK_URB( urbp, dev, usb_sndbulkpipe(dev,1), 
			buffer, len, napa_bulk_complete, &coda);
	printk("     submit retval is: %d\n", usb_submit_urb(urbp));
	sleep_on(&coda);
	printk("               Status: %d\n", urbp->status );
	usb_free_urb( urbp);
	kfree(buffer);
	return 0;
}

int napa_bulk_recv( struct usb_device* dev, char* buf, int len  )
{
	struct urb* urbp = usb_alloc_urb(0);
	char *buffer = (char*)kmalloc( len+1, GFP_KERNEL);
	int i;
	wait_queue_head_t coda;
	init_waitqueue_head( &coda );

	FILL_BULK_URB( urbp, dev, usb_rcvbulkpipe(dev,2), 
			buffer, len, napa_bulk_complete, &coda);
	printk("     submit retval is: %d\n", usb_submit_urb(urbp));
	sleep_on(&coda);
	printk("               Status: %d\n", urbp->status );

	for ( i = 0 ; i < urbp->actual_length; i++ )
		buf[i] = ((char*)urbp->transfer_buffer)[i];

	i = urbp->actual_length;
	usb_free_urb( urbp);
	kfree(buffer);
	
	return i;
}


int napa_open( struct inode* i, struct file* f)
{
	if ( napa == NULL )
		return EINVAL;

	printk("napa opened\n");
	return 0;
}

int napa_release( struct inode* i, struct file* f)
{
	printk("napa closed\n");
	return 0;
}

ssize_t napa_read( struct file* f, char* c, size_t s, loff_t* o)
{
	char *buffer;
	int  len;
	struct usb_device* dev = napa;

	if ( napa == NULL )
		return EINVAL;

	buffer = (char*)kmalloc(10000, GFP_KERNEL);
	len = napa_bulk_recv( dev, buffer, s );

	copy_to_user( (void*)c, (const void*)buffer, len);

	kfree(buffer);
	return len;
}

ssize_t napa_write( struct file* f, const char* c, size_t s, loff_t* o)
{
	char *buffer;
	struct usb_device* dev = napa;
	if ( napa == NULL )
		return EINVAL;	

	buffer = (char*)kmalloc( s, GFP_KERNEL );

	copy_from_user( buffer, c, s );
	napa_bulk_send( dev, buffer, s );

	return s;
}

static struct file_operations napa_fops =
{
	open: 		napa_open,
	release:	napa_release,
	read: 		napa_read,
	write:		napa_write,
	owner:		THIS_MODULE,
};

MODULE_DEVICE_TABLE (usb, napa_ids);

/* NAPA PROBE */
void* napa_probe( struct usb_device *dev, unsigned int interface,
			const struct usb_device_id *id_table)
{
	int d,i,s,e;
	if ( dev->descriptor.idVendor == 0x66f )
	{
		MOD_INC_USE_COUNT;
		printk("setup configuration n.1\n");
		printk("Result: %d\n", usb_set_configuration( dev, 1) );
		printk("napa-pa1x: yes it is a napa-pa11, device registered.\n");
		printk("To send commands and receive responses open /dev/usb/napa-pa1x\n");
		napa = dev;
		printk("ok, so far! \n");
	}
	return NULL;

}

static void napa_disconnect( struct usb_device* dev, void *data)
{
	printk("Device unregistered. \n");
	MOD_DEC_USE_COUNT;
}

static struct usb_driver napa_driver =
{
	name:		"napa-pa1x",
	probe:		napa_probe,
	disconnect:	napa_disconnect,
	fops:		&napa_fops,
	minor:		NAPA_MINOR,
	id_table:	napa_ids,
};

int __init napa_pa1x_init(void)
{
	int err = 0;
	napa = NULL;
	
	if (usb_register(&napa_driver))
		return -1;

	printk("Module napa-pa1x is loading...\n");

	goto exit_from_init;

exit_from_init:
	return err;
}

void __exit napa_pa1x_exit(void)
{
	printk("Module napa-pa1x is unloading...\n");
	usb_deregister (&napa_driver);

	return;
}

module_init(napa_pa1x_init);
module_exit(napa_pa1x_exit);

MODULE_AUTHOR("Willy Gardiol");
MODULE_DESCRIPTION("Driver for napa-pa1x MP3 players serie");


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char comands[2][1024] = 
{ { 0x03, 0x00, 0x00 },

  { 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 }
};

int main()
{
	char *buffer;
	int file;
	int len;
	int i;

	buffer = (char*)malloc( 1024*1024 );
	memset( buffer, 0, 1024*1024);

	file = open("/dev/usb/napa-pa1x", O_RDWR);
	if ( file == -1 )
	{
		printf("Error opening!\n");
		exit(1);
	}
	write( file, comands[0], 3 );
	len = read( file, buffer, 64);
	HexKPrint( buffer, len );
	memset( buffer, 0, 1024*1024);

	write( file, comandi[1], 6 );
	len = read( file, buffer, 64);
	HexKPrint( buffer, len, stdout,0 );
	memset( buffer, 0, 1024*1024);

	free(buffer);
	close( file );
}

Reply via email to