CDC Ethernet tethering via USB

I’ve long wanted to use my Android phone as a CDC Ethernet adapter via USB connected to my Mac laptop. (Connection to Windows or Linux works via Microsoft’s RNDIS protocol.) However, CDC just doesn’t seem to work.

Now I’ve learned that Linux (upon which Android is, of course, based) does support CDC, so the question becomes, “Why doesn’t it work on Android?”

A guy dove deep into it and discovered it’s due to an incorrect regular expression in an XML configuration file for the kernel.

Since this pattern is, presumably, hard-coded into the built kernel, what possibility, if any, is there for me as an e/OS/ user to influence this?

Would this be something possible to approach at the LineageOS level?

good article, retraces the research process. Also: how a user can verify if the used device kernel meets the requirements.

Only interfaces whose names match the {@code config_ethernet_iface_regex} regular expression are tracked.

LineageOS hasn’t changed the connectivity package part to include “usb” in the regex yet.

You could ask him if there’s going to be a “part 2” where he rebuilds a device image with the changed connectivity package.

I’d guess there can be issues if you allow all usb device names to be included in the interface tracking, but likely you can ignore this when there are no other usb devices attached.

Yeah, I like reading articles like that. I tried to contact him via e-mail but got no response.

From what I can tell, the “single EthernetDataTracker? object (frameworks/base/core/java/android/net/EthernetDataTracker.java) that tracks ‘Ethernet’ device state changes […] by design […] only tracks a single device which is controlled by the config_ethernet_iface_regex string property (frameworks/base/core/res/res/values/config.xml) [and] it only monitors the last interface from /sys/class/net that matches the setting.”

It looks to me as though LineageOS can, then, actually change this if they so choose.

Huh, that property’s also defined in overlayable.xml which suggests there may be ways to, well, overlay/override this other than patching config.xml.

yes, overlayable.xml RROs seem to be there to be runtime configurable, not buildtime.

I can dump the value, but how to overwrite?

adb shell cmd overlay lookup --verbose com.android.connectivity.resources com.android.connectivity.resources:string/config_ethernet_iface_regex

I tried fabricate, but computer says “Error: For input string”

Btw, don’t grok yet why the package wasn’t listed with

adb shell cmd overlay list com.android.connectivity.resources

That RRO page describes crafting an XML file (e.g., res/xml/overlays.xml) defining the overlay. Do you have an idea where to put such a file so as to satisfy the <policy type="product|system|vendor"/> restriction? (You seem to be ahead of me in this sort of knowledge.)

For my xz2c I have the following CDC configuration. What do you have?

CONFIG_USB_NET_CDCETHER=y
# CONFIG_USB_NET_CDC_EEM is not set
CONFIG_USB_NET_CDC_NCM=y
# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
# CONFIG_USB_NET_CDC_MBIM is not set
CONFIG_USB_NET_CDC_SUBSET_ENABLE=y
CONFIG_USB_NET_CDC_SUBSET=y

When I connect via USB tethering, though, the interface is actually revealed as rndis0, not usb0, so it seems /e/ (and Lineage) is defaulting to RNDIS rather than CDC, somehow (or RNDIS is coming last, after CDC, and so is what EthernetDataTracker ends up tracking).

Curiously, the only visible RNDIS configs are not set, so if it’s necessary to disable RNDIS to get CDC working that would have to be done some other way that overlaying, presumably. (I presume the primary RNDIS config, presuming there is one is set elsewhere.)

# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set

Edit: I guess it’s USB_ETH_RNDIS.

but that is regular usb to usb tether, not ethernet-plug-to-usb?

Only here for the internals / tooling, but might test this sometime myself.

All the RRO work is already done by Lineage here. It just needs fabricate to do what it advertises. While I understood the encoded type id to be 0x3 for string, I can set an encoded string with a maximum size of an unsigned 32bit integer? that’s 4 chars in utf8?

adb shell cmd overlay fabricate --target com.android.connectivity.resources --name ServiceConnectivityResourcesConfig1 com.android.connectivity.resources:string/config_ethernet_iface_regex 0x3 0x$(echo -n 'eth\d' | xxd -p)
Error: String value 6574685c64 exceeds range of unsigned int.

ok… shorten the regex to ‘eth’ and it will go through, but the written FRRO (fabricated runtime resource overlay) seems invalid and not carry the set string when just hexdumped

idmap2 dump --idmap-path /data/resource-cache/com.android.shell-newregex1-XfMM.frro                                                                         
error: failed to parse idmap header -> failed to load idmap

I tried to follow up on the string intros by jakmcbane@google.com by git-blaming OverlayManagerShellCommand.java but I can’t figure out if there’s the intent of being able to use longer strings, currently I don’t think so. Anyway, last resort, builing framework base yourself

Edit: well, seems this isn’t merged in the lineage20 branch even (and android13 aosp? cs browser doesn’t list other branches than “main” to me). Can’t have hands-on with the latest version

Yes, simply connecting the xz2c to my Mac via USB, and selecting “USB Tethering” for the connected device.