'USB Ethernet on Android devices

I have an embedded Linux system that uses the USB Gadget framework to appear as an Ethernet class device (ACM Ethernet, using the g_ether kernel driver.) All is well using this with an Ubuntu system to connect to the device. I can either get the device to issue DHCP leases to the Ubuntu system or set up a static IP configuration in Ubuntu and on the embedded system, and network traffic passes just fine. On the Ubuntu system this appears as a usb0 network interface (regular Ethernet ports appearing as eth0, etc.)

Now, I want this to work with an Android device. Specifically, a Samsung Galaxy S20 and a Galaxy Tab A, but wide support for other devices would be good too.

We already have an application working with this phone and tablet which uses a USB Serial Gadget to communicate with the embedded system.

I note that when I connect a USB Ethernet dongle to the Android tablet, I can actually access the internet through this device, once the setting is enabled in the "More connection settings" page.

However, if we connect our gadget USB device to the Android tablet, the option to enable Ethernet remains disabled.

My suspicion is that this is because Android is either filtering by VID/PID (a whitelist of devices?), or it only enables this option if it detects an eth0 device.

So my question is two fold:

  • Is it possible, without rooting or modifying stock Android, to make a usb0 device accessible from the user-accessible network settings page?

  • Failing that, what are the conditions for Android/Linux in distinguishing between usb0 and eth0 as names for devices? (Assuming Android is not using a whitelist to further filter acceptable devices: I can find no confirmation or denial of this.) I have quite a lot of control over how the Gadget advertises itself, for instance I can add descriptors, change IDs, version numbers and so on. What does not work is simply changing the VID/PID to emulate an existing chipset e.g. RTL8153. Linux does in fact recognise the device as an x8153 if I do this, however it still remains as usb0. It breaks usb0 too; whilst it enumerates correctly and will accept a netmask and address, no network traffic passes. I would guess that the RTL8153 and similar drivers want to write register maps that definitely do not exist on the Gadget and so end up endlessly waiting for something to happen. Even if it did not break things, it would be a horrid, non-USB-compliant way to do things, so it is not the way I want to go.

I have a bit of data: Another product we are aware of does, in fact, require an application which uses a rooted device and su to configure the Linux routing table manually to achieve USB Ethernet. We are trying to avoid the need to do this, but it does seem that may not be possible. Alarmingly, this product has a secure usage profile, so it seems a bit at odds with needing to root the phone.

I have tried, incidentally, this with an RNDIS gadget driver (Linux supports both) and the behaviour is identical.



Solution 1:[1]

The problem is solved. It is all down to the MAC address that the USB Gadget advertises. You need to advertise a universal address (U/L bit is clear) for the udev rules in Linux (on the Android side) to associate an eth0 device instead of usb0. Once this is done, Android will connect to the device as normal from the settings page, even if it is a composite USB device.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thomas O