ubports / ubuntu-touch

Ubuntu Touch's issue inbox is now migrated to GitLab.
https://gitlab.com/ubports/ubuntu-touch
1.28k stars 110 forks source link

USB tethering not working #1393

Open ruedigerkupper opened 4 years ago

ruedigerkupper commented 4 years ago

Steps to reproduce

Try enabling USB tethering either using UT Tweak Tool or from the command line.

Expected behavior

Phone provides network connection over USB to connected devices.

Actual behavior

Phone does not provide network access over USB. Instead you get the usual data connection (MTP).

slowcyclist commented 4 years ago

By looking at the existing fixes for broken tethering (here or here), one finds out that the main cause of the issue is that the phone has neither a "usb0" nor an "rndis0" device.

I have found a way to bring up rndis0 (all lines with sudo):

bash  /android/system/halium/usr/share/usbinit/setupusb reset
bash  /android/system/halium/usr/share/usbinit/setupusb rndis

After that, the phone has an rndis0 interface! Then you can try to do the usual ubports setup of tethering

sed -i -e 's/rndis0/usb0/g' /usr/bin/tethering
tethering enable

which instructs NetworkManager to use rndis0 for an ethernet connection and to bring it up (see NM configuration /etc/NetworkManager/system-connections/tethering)

At that point the rndis0 has an IP address 10.42.0.1 and the desktop pc on other side of the usb cable indeed sees an ethernet link on its usb that it can connect to (provided you manually assign it an ip address). However that connection is non-functionnal, probably because on the phone side ip link show rndis0 reports state DOWN. Accordingly, on both sides ifconfig reports no transmitted packets, and TX errors on the desktop side.

I'm not at all an expert and don't know what to try next to work around this.

ruedigerkupper commented 4 years ago

Looks promising! @fredldotme Do you know what to make of that?

slowcyclist commented 4 years ago

I made tethering work by running this usb setup script in place of /android/system/halium/usr/share/usbinit/setupusb. This other script creates both usb0 and rndis0 (don't know why one would need both). Turns out you can connect with usb gadget function rndis.usb0 (yielding device usb0), but not usb gadget function rndis_bam.rndis (yielding device rndis0) which is used in setupusb. I will now try to fix setupusb accordingly.

fredldotme commented 4 years ago

@slowcyclist great, if you can do that I'd be happy to merge it :)

slowcyclist commented 4 years ago

Well yes it's easy actually. A simple patching of setupusb fixes the issue with the usb0 device:

--- setupusb
+++ setupusb-fixed
@@ -1,3 +1,5 @@
+#! /bin/bash
+
 CONFIG_DIR=/dev/config
 GADGET_DIR=$CONFIG_DIR/usb_gadget
 SERIALNUMBER=`getprop ro.serialno`
@@ -49,7 +51,7 @@

 setup_rndis() {
     write $GADGET_DIR/gadget1/configs/config.1/strings/0x409/configuration "rndis"
-    symlink $GADGET_DIR/gadget1/functions/rndis_bam.rndis $GADGET_DIR/gadget1/configs/config.1
+    symlink $GADGET_DIR/gadget1/functions/rndis.usb0 $GADGET_DIR/gadget1/configs/config.1
     write $GADGET_DIR/gadget1/UDC ${CONTROLLER}
     setprop sys.usb.state rndis
 }
@@ -57,7 +59,7 @@
 reset_usb() {
     rm $GADGET_DIR/gadget1/configs/config.1/mtp.gs0
     rm $GADGET_DIR/gadget1/configs/config.1/ffs.adb
-    rm $GADGET_DIR/gadget1/configs/config.1/rndis_bam.rndis
+    rm $GADGET_DIR/gadget1/configs/config.1/rndis.usb0
 }

 setup_boot() {
@@ -90,10 +92,7 @@
     mkdir -p $GADGET_DIR/gadget1/functions/ffs.adb
     mkdir -p $GADGET_DIR/gadget1/functions/cser.dun.0
     mkdir -p $GADGET_DIR/gadget1/functions/cser.nmea.1
-    mkdir -p $GADGET_DIR/gadget1/functions/gsi.rmnet
-    mkdir -p $GADGET_DIR/gadget1/functions/gsi.rndis
-    mkdir -p $GADGET_DIR/gadget1/functions/gsi.dpl
-    mkdir -p $GADGET_DIR/gadget1/functions/rndis_bam.rndis
+    mkdir -p $GADGET_DIR/gadget1/functions/rndis.usb0
     mkdir -p $GADGET_DIR/gadget1/functions/rmnet_bam.rmnet
     mkdir -p $GADGET_DIR/gadget1/functions/rmnet_bam.dpl
     mkdir -p $GADGET_DIR/gadget1/functions/ncm.0

(I made some changes that are not strictly necessary: adding the shebang and removing the gsi.* functions that are not found) And in order to have the tethering properly activated/deactivated from the UTTweak tool, one also needs to patch the /usr/bin/tethering script:

--- tethering
+++ tethering-fixed
@@ -2,8 +2,14 @@

 NMCONF=/etc/NetworkManager/system-connections/tethering

+init_interface(){
+bash  /android/system/halium/usr/share/usbinit/setupusb reset
+bash  /android/system/halium/usr/share/usbinit/setupusb rndis
+ifconfig usb0 up
+}
+
 enable(){
-    MAC="$(ip -o link show rndis0 |sed -e 's/^.*ether //'|cut -d' ' -f1)"
+    MAC="$(ip -o link show usb0 |sed -e 's/^.*ether //'|cut -d' ' -f1)"
     UUID=ca16a21d-7d8b-4b49-926e-"$(echo $MAC|sed -e 's/://g')"
     STAMP=$(date +%s)

@@ -41,10 +47,15 @@
 disable(){
     nmcli c down id tethering || true
     rm $NMCONF || true
+
+    #restore persistent usb state (adb, mtp ... )
+    #see /system/halium/etc/init/mtp-state.conf
+    initctl start mtp-state
 }

 case $1 in
     enable)
+        init_interface
         enable
         ;;
     disable)

With both patches it's working rather nicely. Yet, some more polishing is probably needed for the persistence of the usb settings to work as expected. For now if you reboot while in tethering, the phone has no adb, no mtp and no tethering and the settings shown in UTtweak tool is inconsistent with the actual state of the interface; you need to toggle the settings once to get mtp back (without reboot).

For my own use, I further expanded the tethering script so that it can also setup a reverse tether (but the added option is not accessible from the GUI. If anyone is interested, just ask).

@fredldotme I installed your port a few weeks ago (coming from SailfishOS) and have not yet have the opportunity to thank you. Kudos for your great work!