Opened 3 years ago
Last modified 5 months ago
#17746 new bug
[USB tethering] Samsung S6810-L not working
Reported by: | bipolar | Owned by: | pulkomandy |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | Drivers/Network/usb_rndis | Version: | R1/Development |
Keywords: | Cc: | ||
Blocked By: | Blocking: | ||
Platform: | All |
Description
Seing the inclusion of the new usb_rndis
driver, I've attempted to use the two (rather old) Android 4.1 smartphones I have access to.
This ticket is for the one that under Linux works as an RNDIS device.
A Samsung Galaxy Fame (S6810-L, Android 4.1): Under Linux it works for USB tethering thanks to the rndis_*
(and cdc_ether
) drivers.
Under Haiku, it doesn't seems to work (no device appears under /dev/net/usb_rndis/
).
The only lines that appear on the syslog after pluging in the phone, and enabling the USB tethering are the following:
KERN: usb hub 32: port 2: new device connected KERN: usb hub 32: KERN: port 2: new device connected KERN: usb error hub 32: new device on a port that is already in use
By default it presents as a MTP device, until USB tethering is enabled. I guess that's the cause of the new device on a port that is already in use
error?
I'm attaching the output of listusb -v /dev/bus/usb/6/2
under Haiku hrev55112, and sudo lsusb -v -d 04e8:6864
under Linux, just in case (plus `lsmod | grep usbnet).
On both cases is with USB tethering already enabled (and working in case of Linux).
Attachments (10)
Change History (27)
by , 3 years ago
Attachment: | USB_04e8_6864_Haiku.txt added |
---|
by , 3 years ago
Attachment: | USB_04e8-6864_Linux.txt added |
---|
follow-up: 2 comment:1 by , 3 years ago
comment:2 by , 3 years ago
Replying to pulkomandy:
In Haiku the device is showing as CDC-ACM, and not RNDIS. Could it be that the phone decided that Haiku is not a recognized operating system, and so they switched to a different USB tethering mode?
No idea :-(
I tried it again, but this time setting the phone to default to PTP instead of MTP (no way of selecting USB tethering as default).
The following lines appear in syslog
after plugin it in, and enabling tethering:
KERN: usb hub 32: port 2: new device connected KERN: usb error hub 32: new device on a port that is already in use KERN: usb hub 32: port 2: new device connected KERN: usb error hub 32: new device on a port that is already in use KERN: usb error ehci 6: qtd (0xfb5f380) error: 0x80020d40 KERN: usb error ehci 6: qtd (0xfb5f600) error: 0x80020d40 KERN: usb error ehci 6: qtd (0xfb5f880) error: 0x80020d40 KERN: usb error ehci 6: qtd (0xfb5fb00) error: 0x80020d40 KERN: usb error ehci 6: qtd (0xfb5fd80) error: 0x80020d40
No idea what those errors are about. They also appeared in my previous tests with this phone. I didn't reported them earlier because I guess I got confused with the syslog output for my other phone (#17747) that also present similar qtd
errors.
by , 10 months ago
Attachment: | USB_04e8_6864_hrev57531.txt added |
---|
Updated "listusb -v" from current nightly (hrev57531)
comment:3 by , 10 months ago
Retested on current nightly. Output of "listusb -v" looks now more aligned to what Linux shows, but seems the usb_rndis driver still doesn't wants to work with this old phone :-)
syslog output looks cleaner (no "qtd erros"), and only shows the usual "new device connected" messages.
comment:4 by , 10 months ago
So the device reports this:
3 Class .................. 0x02 Communications () 4 Subclass ............... 0x00 Communications () 5 Protocol ............... 0x00 Communications ()
This does not match what the driver expects:
Maybe this phone is from before RNDIS got its proper subclass assigned.
But we can try to add a specific case for this phone, something like this:
static usb_support_descriptor supportDescriptor[] = { { // Standard USB-RNDIS devices 0xE0, /* CDC - Wireless device */ 0x01, 0x03, /* RNDIS subclass/protocol */ 0, 0 /* no specific vendor or device */ }, { 0x02, 0x00, 0x00, 0x04e8, 0x6864 } }; gUSBModule->register_driver(DRIVER_NAME, &supportDescriptor, 2, NULL);
RNDISDevice::_SetupDevice is also looking for the interface with the proper device class:
This will need to be adjusted to also accept descriptor->interface_class == 0x02, descriptor->interface_subclass == 0x02 and descriptor->interface_protocol == 0xff, to match this part of the USB descriptor from listusb:
Class .............. 0x02 Communications () 19 Subclass ........... 0x02 Communications (Abstract (modem), None) 20 Protocol ........... 0xff Communications (Abstract (modem), Vendor Specific (MSFT RNDIS?)) 21 Interface String ... "RNDIS Communications Control"
(Maybe check in addition in that case that the interface string is "RNDIS Communications Control", to be extra sure, but since we are already filtering on the device ID, it should be fine even without this check).
So, something like this replacing lines 630-635:
if (interface->generic_count == 0) { // Ignore this interface, it doesn't have enough endpoints, try the next one continue; } else if (descriptor->interface_class == USB_COMMUNICATION_WIRELESS_DEVICE_CLASS && descriptor->interface_subclass == 0x01 && descriptor->interface_protocol == 0x03) { // Looks good! } else if (descriptor->interface_class == 0x02 && descriptor->interface_subclass == 0x02 && descriptor->interface_protocol == 0x0F) { // TODO check interface string here, "continue" if it's not "RNDIS Communications Control" } else { // Interface does not match either of our known ways to identify an RNDIS interface, ignore it and try the next one continue; }
Let us know if that works better :)
comment:5 by , 10 months ago
Thanks PulkoMandy.
Applied your suggested changes (had to remove the "&" from gUSBModule->register_driver(DRIVER_NAME, &supportDescriptor, 2, NULL);
to make it compile, not sure if that was the right thing to do :-/).
Installed the driver under ~/config/non-packaged/add-ons/kernel/drivers
(bin/usb_rndis
and symlink to dev/net/usb_rndis
. Just in case, rebooted and black-listed the "system" usb_rndis
.
tail -f /var/log/syslog
shows:
KERN: usb_rndis: did not find a union descriptor KERN: usb_rndis: failed to setup device
When I enable USB tethering on the phone.
Still... sounds like progress! :-D
Edit: I'll double check tomorrow, hopefully with fresher eyes/head :-D
comment:6 by , 10 months ago
Typo?
- && descriptor->interface_protocol == 0x0F) { + && descriptor->interface_protocol == 0xFF) {
comment:8 by , 10 months ago
After applying the change mentioned by thebuck, now I get:
KERN: usb_rndis: control interface invalid KERN: usb_rndis: failed to setup device
Getting closer, I feel! :-D
Edit: I assume I need to change https://cgit.haiku-os.org/haiku/tree/src/add-ons/kernel/drivers/network/ether/usb_rndis/RNDISDevice.cpp#n682 in a similar way to what PulkoMandy suggested for _SetupDevice(). Task for tomorrow! :-D
comment:9 by , 10 months ago
For instance:
if ((descriptor->interface_class != USB_COMMUNICATION_WIRELESS_DEVICE_CLASS || descriptor->interface_subclass != 0x01 || descriptor->interface_protocol != 0x03) && (descriptor->interface_class != USB_COMMUNICATION_DEVICE_CLASS || descriptor->interface_subclass != 0x02 || descriptor->interface_protocol != 0xff) || interface->endpoint_count == 0) {
comment:10 by , 10 months ago
Welp, after massaging a bit that last suggestion by korli, the usb_rndis
finally recognized my phone... it started to *try* to configure it (kept getting rndis related errors on the syslog, and after I unplugged the device, got a nice KDL (I got lucky, and cont
worked :-D).
Next.. I will attach the used code diff, and a clean version of the relevant syslog messages (including KDL text).
Starting to look like it might be better to just try to find a different device I could use :-D
by , 10 months ago
Attachment: | usb_rndis-diff.txt added |
---|
by , 10 months ago
Attachment: | usb_rndis-patched-syslog.txt added |
---|
"tail -f /var/log/syslog" output while testing the modified driver
comment:11 by , 10 months ago
The change you made to Korli's suggested code seems incorrect.
You have this:
if ((interface->endpoint_count == 0) || ! ((descriptor->interface_class == USB_COMMUNICATION_WIRELESS_DEVICE_CLASS && (descriptor->interface_protocol == 0x01 || descriptor->interface_protocol == 0x03)) || (descriptor->interface_class == USB_COMMUNICATION_DEVICE_CLASS && (descriptor->interface_protocol == 0x02 || descriptor->interface_protocol == 0xFF)))) {
The second condition will always match in your case (for any descriptor). So, that will not work.
This is impossible to understand without spending 5 minutes looking at the code anyway, so let's split it up into smaller pieces so it's easier to read:
if (interface->endpoint_count == 0) { TRACE_ALWAYS("control interface has no endpoint_count\n"); return B_ERROR; } if (descriptor->interface_class == USB_COMMUNICATION_WIRELESS_DEVICE_CLASS) { if ((descriptor->interface_subclass != 0x01 || descriptor->interface_protocol != 0x03) { TRACE_ALWAYS("control interface has invalid interface subclass or protocol\n"); return B_ERROR; } } else if (descriptor->interface_class == USB_COMMUNICATION_DEVICE_CLASS) { // Microsoft USBRNDIS style control interface if ((descriptor->interface_subclass != 0x02 || descriptor->interface_protocol != 0xFF) { TRACE_ALWAYS("control interface has invalid interface subclass or protocol\n"); return B_ERROR; } } else { TRACE_ALWAYS("control interface has invalid interface class\n"); return B_ERROR; }
Then, we have this in the syslog:
usb_rndis: link speed: -2021749710 * 100bps
Getting the link speed didn't work very well. I think for now we can comment out the call to _ReadLinkSpeed, there will be no problem with that except the link speed won't be reported in network preferences.
I don't know if this failure to get the link speed is what causes the next problems or not. The next thing to do is probably to enable TRACE (add a #define TRACE_RNDIS 1
in Driver.h so we can get more information in the debug logs.
Then we will see which requests caused the other errors and hopefully see more from _EnableBroadcast, which is supposed to enable the traffic, but it seems it didn't work.
comment:12 by , 10 months ago
Thanks Adrien. Splitting that logic indeed helps readability, for sure :-)
I've applied those changes, disabled the call to _ReadLinkSpeed(), enabled TRACE_RNDIS
, and blacklisted the system-wide usb_rndis
driver.
Long story short... in 2 parts:
1.- Connecting the phone and enabling USB tethering when the custom driver is already installed:
Doesn't works. And disabling tethering on the phone (before even unplugging it) eventually ends in a KDL (vm_page_fault from RNDISDevice::_NotifyCallback()
). Sometimes cont
ends with an still usable system, sometimes... a reboot is needed.
2.- If I connect the phone, enable USB tethering... and ONLY THEN I install the custom usb_rndis
driver under non-packaged/[...]
... it seems that things work relatively fine! (besides some USB ehci, and usb_rndis errors appearing on the syslog).
Quick tested doing pkgman refresh
, and opening a couple of sites in WebPositive.
Disabling USB tethering, and waiting for the syslog output from usb_rndis to end before unplugging the phone seems to avoid surprise KDLs :-D
Will do my best to provide concise/clear logs for both situations (probably tomorrow, current logs are too long/messy).
Thanks you guys! Pretty wild seeing it actually "become alive"!
by , 10 months ago
Attachment: | usb_rndis-working-clean.txt added |
---|
log of usb_rndis driver working with Samsug S6810. File uploaded via said working connection!
comment:13 by , 10 months ago
And... got a KDL upon disabling tethering on the phone thou :-D (vm_page_fault on "usb explore" thread, from device_node DeviceRemoved(), apparently). Oh well! :-D
by , 10 months ago
Attachment: | usb_rndis-diff2.txt added |
---|
Updated .diff. Re-enabled _ReadLinkSpeed()
call, as it is not the one causing errors.
by , 10 months ago
Attachment: | usb_rndis-not-working.txt added |
---|
Relevant syslog output when usb_rndis drive fails to work, and ends on KDL (file details steps taken).
by , 10 months ago
Attachment: | usb_rndis-working.txt added |
---|
Syslog output when the driver works as intended, and steps taken to avoid getting KDL (need to disable usb_rndis on Network preflets before disabling usb-tethering, and unpluging the phone),
comment:14 by , 10 months ago
Comparing both syslogs, seems that all goes well up to the return of _RNDISInitialize()
. Then... even the mac address has a bogus value, and things just get worse from there.
Seems like EHCI gets confused with the usb device changing modes?
Will try to test on a machine with XHCI only, to see if XHCI vs EHCI makes any difference.
by , 10 months ago
Attachment: | usb_rndis-xhci-working.txt added |
---|
syslog from testing same phone, patched usb_rnids
driver on a "XHCI only" machine. (includes descriptions of the steps taken).
comment:15 by , 10 months ago
Neither unplugging the phone, or disabling USB tethering while usb_rnid driver was in use caused KDLs.
Attempting to re-connect the phone appeared to work, but could not actually access the internet. Rebooting and following the same steps detailed in the log file... resulted in working connection again (well enough as to actually slowly complete pkgman update
).
Edit: tests where performed on hrev57554, 64 bits.
comment:16 by , 10 months ago
I think we can add some more checks to _GetOID.
First of all, _ReadResponse does not return the actual length of the response, so we don't know if there was actually enough data in the reply. Probably _ReadResponse could return the actual length instead of B_OK when it received something (and all places where we call it should be adjusted).
Then, in _GetOID, the response contains a 24 byte header before the reply. We don't check anything in there either. We should check the following layout:
uint32 MessageType == 0x80000004; uint32 MessageLength == length + 24; uint32 RequestID == 0x00000001; // Currently all our requests have ID 1 (there is a TODO about it in the code) uint32 Status == 0; // RNDIS_STATUS_SUCCESS uint32 InformationBufferLength == length; uint32 InformationBufferOffset == 24;
If one of them does not match with that, we will have a better idea what is happening.
This info is from the USB-RNDIS specification: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/WinArchive/%5BMS-RNDIS%5D.pdf
comment:17 by , 5 months ago
Component: | Drivers → Drivers/Network/usb_rndis |
---|---|
Keywords: | usb tethering removed |
Owner: | changed from | to
Platform: | x86-64 → All |
Yes.
In Haiku the device is showing as CDC-ACM, and not RNDIS. Could it be that the phone decided that Haiku is not a recognized operating system, and so they switched to a different USB tethering mode?