I'm making a Linux module (my first one) for a closed-source, enclosed (no hardware access) device. Using Wireshark I found what to send and where, so I tried the following command in user space Python and it works:
handle._controlTransfer(0x21, 0x09, 0x0300, 3, data, 8, 0) #packet sent, device reacts
Sadly I can't get it to work in the kernel module:
usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x09, 0x21, 0x0300, 3, data, 8, 0); //packet sent, device doesn't react
even by creating the urb myself:
urb = usb_alloc_urb(0, GFP_KERNEL);
cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
cr->bRequest = 0x09;
cr->wValue = cpu_to_le16(0x0300);
cr->wIndex = cpu_to_le16(3);
cr->wLength = cpu_to_le16(8);
usb_fill_control_urb(urb, dev, usb_sndctrlpipe(dev, 0), (void *)cr, data, 8, urb_callback, context);
usb_submit_urb(urb, GFP_ATOMIC);
kfree(cr);
usb_free_urb(urb);
//packet sent, device doesn't react
When I say the device "reacts" I mean it flashes with another color so there is no ambiguity in the success of the command.
I logged everything with Wireshark and the packets are identical (except for urb_id
and urb_ts_*
)
Would you have any advice for me? Something I forgot or how to debug more?
Edit
Full working Python code
context = usb1.USBContext()
handle = context.openByVendorIDAndProductID(VENDOR_ID, PRODUCT_ID)
usb1.libusb1.libusb_set_auto_detach_kernel_driver(handle._USBDeviceHandle__handle, 0)
usb1.libusb1.libusb_set_auto_detach_kernel_driver(handle._USBDeviceHandle__handle, 3)
handle.claimInterface(0)
handle.claimInterface(3)
handle._controlTransfer(0x21, 0x09, 0x0300, 3, data, 8, 0)
handle.releaseInterface(3)
handle.releaseInterface(0)