I've exhausted the documented methods of programmatically enabling USB tethering:
The
service
method doesn't work on my phone (Samsung Note 4). It seems to be some sort of protected API, and poking it fromadb
has no effect.The
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.
Launch a
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 (
/proc/sys/net/ipv4/ip_forward
).Set up
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 (iptables -S
, 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?