I've exhausted the documented methods of programmatically enabling USB tethering:
service method doesn't work on my phone (Samsung Note 4). It seems to be some sort of protected API, and poking it from
adb has no effect.
shell input method is not applicable, as it requires that the device is unlocked, and there doesn't seem to be a way to programmatically and non-destructively unlock a device locked with a fingerprint.
So, I'm looking into achieving this goal "the hard way", i.e. do everything that the Android userspace does when you tap the USB tether checkbox.
As far as I can tell, this involves the following steps (most of which would be similar to how you'd do it on a Linux machine):
Establish an IP connection to the host computer through USB. This involves putting USB in
rndis mode, setting up routes, assigning an IP, etc.
I've already figured out how to achieve this and posted the answer here.
dnsmasq instance, to assign an IP to the connected PC via DHCP, and forward DNS requests.
This step shouldn't be necessary if you don't need DNS server detection and assign static IPs on the USB interfaces yourself.
Enable IP forwarding (
iptables to enable forwarding/masquerading.
Update routing tables for traffic accounting.
I managed to write a bunch of scripts which replicate exactly the visible effects (described above) as performed by the Android OS when enabling USB tethering through its UI. To create the scripts, I recorded the system state (
ip route show table all) with and without tethering, then converted the differences into shell commands to apply the changes to the system. However, my replicas are still not enough; some part of the system remains unconfigured which prevents traffic from going through.
Does anyone have a clue as to what I might be missing, or how I can narrow down / debug the problem?